;+
; Project     :	SOHO - CDS
;
; Name        :	CP_GET_STATE
;
; Purpose     :	Gets VDS state database information.
;
; Explanation :	This returns a structure containing information about various 
;               quasi-static VDS parameters. 
;
; Use         : < cp_get_state, date, desc, ERRMSG=errmsg>
;
; Inputs      : DATE	= The date/time value that the user wishes the state
;			  for.  This can be in any of the standard CDS time
;			  formats.
;
; Opt. Inputs : None.
;
; Outputs     : DESC	= Structure containing the state description.  It
;			  contains the following tags:
;
;			DATE	   = Start date and time for the period for
;				     which the parameters in this record are
;				     valid.  The period ends at the start
;				     date/time of the next record.  This is a
;				     double precision TAI value.  If no entries
;				     are found, then a simplified structure is
;				     returned with this set to zero.
;			VDS_READ   = Code value (1-7) giving the VDS readout
;				     mode.
;			VDS_PMCP   = Programmable voltage (0--255) controlling
;				     the voltage across the VDS microchannel
;				     plate.
;			VDS_OFFSET = Two integers giving the offset of the VDS
;				     wavelength bands on the CCD.
;                       VDS_CENTRE = Integer giving the dividing line of the VDS CCD.
;
; Opt. Outputs:	None.
;
; Keywords    : 
;       ERRMSG    = If defined and passed, then any error messages will be
;                   returned to the user in this parameter rather than
;                   depending on the MESSAGE routine in IDL.  If no errors are
;                   encountered, then a null string is returned.  In order to
;                   use this feature, ERRMSG must be defined first, e.g.
;
;                       ERRMSG = ''
;                       GET_STATE, ERRMSG=ERRMSG, ... 
;                       IF ERRMSG NE '' THEN ...
;
; Calls       :	datatype, cp_get_history, anytim2utc, utc2tai.
;                
; Common      :	None.
;
; Restrictions:	None.
;
; Side effects:	None.
;
; Category    :	Command preparation.
;
; Prev. Hist. :	None.
;
; Written     :	Version 0.0, Martin Carter, RAL, 25/8/95
;                 Adapted from get_state function.
;
; Modified    :	Version 0.1, 8/9/95, MKC.
;                 Renamed VDS_PCMP to VDS_PMCP
;		Version 0.2, William Thompson, GSFC, 26 September 1995
;			Added keyword ERRMSG
;               Version 0.3, MKC, 18/10/95
;                       Added VDS_CENTRE tag to structure.
;		Version 1, William Thompson, GSFC, 15 February 1996
;			Changed to correct mnemonics for the readout mode and
;			MCP programmable voltage.
;
; Version     :	Version 1, 15 February 1996
;-
;**********************************************************

PRO cp_get_state, date, desc, ERRMSG=ERRMSG

  ;
  ;  Define a null result.  If the routine is successful, this will be updated
  ;  later.
  ;
	desc = {date: 0}
  ;
  ;  Check the number of parameters.
  ;
        IF N_PARAMS() NE 2 THEN BEGIN
		MESSAGE = 'Syntax:  CP_GET_STATE, DATE, DESC'
		GOTO, HANDLE_ERROR
	ENDIF
  ;
  ;  Check the input parameter.
  ;
	IF N_ELEMENTS(date) NE 1 THEN BEGIN
		MESSAGE = 'DATE must be a scalar'
		GOTO, HANDLE_ERROR
	ENDIF
  ;
  ;  Convert the date to TAI format.
  ;
	IF DATATYPE(date,1) EQ 'Double' THEN tai = date ELSE	$
		tai = UTC2TAI(date)
  ;
  ; get VDS parameters from state database

  ; get VDS_READ

  s = cp_get_history ( {mnemonic:'CBVCAM', pnumber:4}, /QUIET )

  IF s(0).mnemonic EQ 'Unknown' THEN BEGIN
    MESSAGE = 'INVALID VDS PARAMETER IN CDHS STATE DATABASE'
    GOTO, HANDLE_ERROR
  ENDIF

  ; look for dates before given date for item

  list = WHERE ( UTC2TAI ( ANYTIM2UTC ( s.date ) ) LE tai, count )

  IF count EQ 0 THEN BEGIN
	MESSAGE = 'NO VDS PARAMETER BEFORE GIVEN DATE IN CDHS STATE DATABASE'
	GOTO, HANDLE_ERROR
  ENDIF

  ; get latest item

  s = s ( list(count-1) )

  vds_read_dat = s.active
  vds_read_tim = UTC2TAI ( ANYTIM2UTC ( s.date ) )

  ; get VDS_PMCP

  s = cp_get_history ( {mnemonic:'CBVVOLT', pnumber:15}, /QUIET )

  IF s(0).mnemonic EQ 'Unknown' THEN BEGIN
    MESSAGE = 'INVALID VDS PARAMETER IN CDHS STATE DATABASE'
    GOTO, HANDLE_ERROR
  ENDIF

  ; look for dates before given date for item

  list = WHERE ( UTC2TAI ( ANYTIM2UTC ( s.date ) ) LE tai, count )

  IF count EQ 0 THEN BEGIN
	MESSAGE = 'NO VDS PARAMETER BEFORE GIVEN DATE IN CDHS STATE DATABASE'
	GOTO, HANDLE_ERROR
  ENDIF

  ; get latest item

  s = s ( list(count-1) )

  vds_pmcp_dat = s.active
  vds_pmcp_tim = UTC2TAI ( ANYTIM2UTC ( s.date ) )

  ; get VDS OFFSET 0 

  s = cp_get_history ( {mnemonic:'VDSOFF', pnumber:0}, /QUIET )

  IF s(0).mnemonic EQ 'Unknown' THEN BEGIN
    MESSAGE = 'INVALID VDS PARAMETER IN CDHS STATE DATABASE'
    GOTO, HANDLE_ERROR
  ENDIF

  ; look for dates before given date for item

  list = WHERE ( UTC2TAI ( ANYTIM2UTC ( s.date ) ) LE tai, count )

  IF count EQ 0 THEN BEGIN
	MESSAGE = 'NO VDS PARAMETER BEFORE GIVEN DATE IN CDHS STATE DATABASE'
	GOTO, HANDLE_ERROR
  ENDIF

  ; get latest item

  s = s ( list(count-1) )

  vds_off0_dat = s.active
  vds_off0_tim = UTC2TAI ( ANYTIM2UTC ( s.date ) )

  ; get VDS OFFSET 1 

  s = cp_get_history ( {mnemonic:'VDSOFF', pnumber:1}, /QUIET )

  IF s(0).mnemonic EQ 'Unknown' THEN BEGIN
    MESSAGE = 'INVALID VDS PARAMETER IN CDHS STATE DATABASE'
    GOTO, HANDLE_ERROR
  ENDIF

  ; look for dates before given date for item

  list = WHERE ( UTC2TAI ( ANYTIM2UTC ( s.date ) ) LE tai, count )

  IF count EQ 0 THEN BEGIN
	MESSAGE = 'NO VDS PARAMETER BEFORE GIVEN DATE IN CDHS STATE DATABASE'
	GOTO, HANDLE_ERROR
  ENDIF

  ; get latest item

  s = s ( list(count-1) )

  vds_off1_dat = s.active
  vds_off1_tim = UTC2TAI ( ANYTIM2UTC ( s.date ) )

  ; get VDS_CENTRE

  s = cp_get_history ( {mnemonic:'VDSCENT', pnumber:0}, /QUIET )

  IF s(0).mnemonic EQ 'Unknown' THEN BEGIN
    MESSAGE = 'INVALID VDS PARAMETER IN CDHS STATE DATABASE'
    GOTO, HANDLE_ERROR
  ENDIF

  ; look for dates before given date for item

  list = WHERE ( UTC2TAI ( ANYTIM2UTC ( s.date ) ) LE tai, count )

  IF count EQ 0 THEN BEGIN
	MESSAGE = 'NO VDS PARAMETER BEFORE GIVEN DATE IN CDHS STATE DATABASE'
	GOTO, HANDLE_ERROR
  ENDIF

  ; get latest item

  s = s ( list(count-1) )

  vds_cent_dat = s.active
  vds_cent_tim = UTC2TAI ( ANYTIM2UTC ( s.date ) )

  ; set up output structure

  desc = {date: MAX ( [vds_read_tim, vds_pmcp_tim, vds_off0_tim, vds_off1_tim, vds_cent_tim] ), $
          vds_read: vds_read_dat, vds_pmcp: vds_pmcp_dat, $
          vds_offset:[vds_off0_dat,vds_off1_dat], vds_centre: vds_cent_dat}
  
  RETURN
;
;  Error handling point.
;
HANDLE_ERROR:
	IF N_ELEMENTS(ERRMSG) NE 0 THEN ERRMSG = 'CP_GET_STATE: ' + MESSAGE $
		ELSE MESSAGE, MESSAGE
END
