
;+
; Project     :	SOHO - CDS
;
; Name        :	CP_GET_LOAD()
;
; Purpose     :	Produces a CDS update file from list of commands from the CDHS state database.
;
; Explanation : Receives a structure containing current commands in the CDHS state database.
;               Extracts from this all commands which require loading.
;               Outputs a file containing these commands and their parameters. Any commands which
;               fail validity tests result in a popup message and are not output. Returns a structure
;               containing the relevant entries in the CDHS state database.
;               The commands are output to the update file with the following format :
;                   COMMAND arguments or command.update.dt
;                   SCRIPT  arguments or script.update.dt
;               The files are written to the directory defined by the environment variable
;               $CDS_CP_UPDATE_W.
;               If no commands in the input list are loadable then returns a structure with command 
;               mnemonic : "Unknown".          
;
; Use         : < st = cp_get_load ( struct ) >
;
; Inputs      : struct = structure array of type st_cdhsstate containing command mnemonics and parameters.                        
;                 struct.mnemonic = parameter mnemonic
;                 struct.date     = date values last changed
;                 struct.numberp  = no. of parameters associated with mnemonic
;                 struct.pnumber  = parameter number for this entry
;                 struct.load     = flag indicating whether value requires loading
;                 struct.delay    = delay in secs associated with command
;                 struct.active   = value for parameter
;                 struct.default  = default value for parameter
;                 struct.comment  = comment on parameter
;
; Opt. Inputs : None.
;
; Outputs     : Outputs loadable commands to the update.dt file.
;               Returns structure array of type st_cdhsstate containing loadable command mnemonics.
;                 struct.mnemonic = parameter mnemonic
;                 struct.date     = date values last changed
;                 struct.numberp  = no. of parameters associated with mnemonic
;                 struct.pnumber  = parameter number for this entry
;                 struct.load     = flag indicating whether value requires loading
;                 struct.delay    = delay in secs associated with command
;                 struct.active   = value for parameter
;                 struct.default  = default value for parameter
;                 struct.comment  = comment on parameter
;
; Opt. Outputs:	None.
;
; Keywords    : GROUP : group for popup message box.
;
; Calls       :	get_utc, popup_msg, shorthex, concat_dir.
;                
; Common      :	None.
;
; Restrictions:	None.
;
; Side effects:	None.
;
; Category    :	Command preparation.
;
; Prev. Hist. :	None.
;
; Written     :	Version 0.0, Martin Carter, RAL, 25/5/94
;
; Modified    :	Version 0.1, MKC, 14/8/95
;                 Added comment field to structure.
;               Version 0.2, MKC, 23/10/95
;                 Renamed environment variables and used concat_dir.
;               Version 0.3, MKC, 23/11/95
;                 Changed format of update file.
;               Version 0.4, MKC, 19/12/95
;                 Added delay tag.
;                 Added special case if numberp=1
;               Version 0.5, MKC, 2/1/96
;                 Added special case to numberp=0
;               Version 0.6, MKC, 16/1/96
;                 Changed macro delay logic,
;               Version 0.7, MKC, 2/2/96
;                 Prevented attempt to write update file if environment variable
;                 not set.
;
; Version     :	Version 0.7, 2/2/96
;-
;**********************************************************

FUNCTION cp_get_load, struct, GROUP=group

  ; extract loadable parameters from structure array

  list = WHERE ( struct.load NE 0, count )

  IF count EQ 0 THEN BEGIN

    s = struct(0)
    s.mnemonic = 'Unknown'
    RETURN, s
  
  ENDIF

  ; get loadable items

  s = struct(list)

  ; check if have access to update directory

  IF GETENV('CDS_CP_UPDATE_W') EQ '' THEN BEGIN
    popup_msg, ['WARNING', $
                'No access to update directory'], $
                title = 'ERROR MESSAGE',/modal, GROUP=group
    RETURN, s
  ENDIF

  ; produce update file

  ; delete any existing update files

  files = concat_dir ( '$CDS_CP_UPDATE_W' , 'update.dt' )

  PRINT, ''
  PRINT, 'Removing files ', files

  SPAWN, 'rm ' + files

  ; get file name

  filename = concat_dir ( '$CDS_CP_UPDATE_W' , 'update.dt' )

  PRINT, 'Writing file = ', filename

  ; open wide file

  OPENW, unit, filename, /GET_LUN, WIDTH=200

  ; file header info

  get_utc, utc, /ECS

  PRINTF, unit, '# CDHS UPDATE FILE'
  PRINTF, unit, '# ' + utc
  PRINTF, unit

  ; find last occurrences of unique mnemonics 
  ; values are already sorted by mnemonic and pnumber

  IF N_ELEMENTS(s) GT 1 THEN list = UNIQ ( s.mnemonic ) ELSE list = [0]

  ; loop through array extracting data for each mnemonic

  pos = 0 ; current position in structure array

  FOR k = 0, N_ELEMENTS(list)-1 DO BEGIN

    ; ss is temporary copy of entries for each mnemonic

    ss = s(pos:list(k)) ; extract data for mnemonic

    pos = list(k)+1     ; update current position

    ; check all values with the same mnemonics have the same no. of parameters
    ; use valid flag to indicate whether any problems with command

    valid = 1

    IF MIN ( ss.numberp ) NE MAX ( ss.numberp ) THEN BEGIN

      ; display message and invalidate command

      popup_msg, ['WARNING', $
                  'Contradictory values for number of parameters.', $
                  'Command not output.'], $
                  title = 'ERROR MESSAGE',/modal, GROUP=group
      valid = 0

    ENDIF

    ; check correct no. of parameters
    ; Added special case if numberp=1.

    IF ss(0).numberp NE 0 AND ss(0).numberp NE 1 AND N_ELEMENTS ( ss.numberp ) NE ss(0).numberp THEN BEGIN

      ; display message and invalidate command

      popup_msg, ['WARNING', $
                  'Invalid number of parameters for ' + ss(0).mnemonic, $
                  'Command not output.'], $
                  title = 'ERROR MESSAGE', /modal, GROUP=group
      valid = 0

    ENDIF

    ; write out command if valid

    IF valid THEN BEGIN

      IF ss(0).numberp EQ 0 THEN BEGIN

        ; output command string for each pnumber
        ; may have multiple values associated with mnemonic
        ; the pnumber value is output also

        FOR pn = 0, N_ELEMENTS(ss)-1 DO $
          PRINTF, unit, ss(pn).mnemonic + ' ' + shorthex ( ss(pn).pnumber ) + ' ' + $
                        shorthex ( ss(pn).active ) + ' # ' + STRTRIM(ss(pn).comment)

      ENDIF ELSE IF ss(0).numberp EQ 1 THEN BEGIN

        ; output command string for each pnumber
        ; may have multiple values associated with mnemonic

        FOR pn = 0, N_ELEMENTS(ss)-1 DO $
          PRINTF, unit, ss(pn).mnemonic + ' ' + shorthex ( ss(pn).active ) + ' # ' + STRTRIM(ss(pn).comment)

      ENDIF ELSE IF ss(0).numberp LE 5 THEN BEGIN

        ; form string

        command = ss(0).mnemonic 

        FOR p = 0, ss(0).numberp-1 DO command = command + ' ' + shorthex ( ss(p).active )

        command = command + ' # ' + STRTRIM(ss(0).comment)

        ; output command string

        PRINTF, unit, command

      ENDIF ELSE BEGIN

        ; create parameter file name

        mnemonic = STRLOWCASE ( STRCOMPRESS ( ss(0).mnemonic, /REMOVE_ALL ) )

        filename =  mnemonic + '.update.dt'

        ; output command string

        PRINTF, unit, ss(0).mnemonic + ' ' + filename + ' # ' + STRTRIM(ss(0).comment)

        ; output parameter file, overwriting any existing file 

        ; get file name

        filename = concat_dir ( '$CDS_CP_UPDATE_W', filename )

        PRINT, 'Writing file = ', filename

        ; open file

        OPENW, tunit, filename, /GET_LUN

        ; file header info

        get_utc, utc, /ECS

        PRINTF, tunit, '# CDHS PARAMETER FILE FOR ' + ss(0).mnemonic
        PRINTF, tunit, '# ' + utc
        PRINTF, tunit

        ; output parameters

        FOR p = 0, ss(0).numberp-1 DO PRINTF, tunit, shorthex ( ss(p).active ) + $
                                                     ' # ' + STRTRIM(ss(p).comment)

        ; close file

        FREE_LUN, tunit

      ENDELSE

      ; check if delay required
      ; NB delay cannot be bigger than 16 bit no.

      delay = LONG(ss(0).delay * 100)

      WHILE delay GT 0 DO BEGIN

        IF delay GT 30000 THEN BEGIN
          PRINTF, unit, 'CB5WAIT 30000 # tell macro to wait'
          delay = delay - 30000
        ENDIF ELSE BEGIN
          PRINTF, unit, 'CB5WAIT ' + shorthex(delay) + ' # tell macro to wait'
          delay = 0
        ENDELSE

      ENDWHILE

    ENDIF    

  ENDFOR

  PRINTF, unit

  ; close file

  FREE_LUN, unit

  RETURN, s
  
END


