;+
; Project     : SOLAR-B - EIS
;
; Name        : EIS_CPT_og_class__define
;
; Purpose     : Generates object EIS_CPT_og_class.
;
; Explanation : EIS_CPT_og_class.
;
;               Tags are :-
;                   og_number : INT OG number for each store item.
;                   og_fixed  : INT indicating number of fixed OGs in store (0 or 1)
;                   INHERITS eis_cpt_commands_class.
;
;               Methods are :-
;                   add          : Adds item to the store.
;                        Use         : <res = self->add(time, seq_name, commands, FIXED=fixed)>
;                        Inputs      : time      : DOUBLE TAI time
;                                      seq_name  : STRING sequence name.
;                                      commands  : STRARR[] OG sequence commands.
;                        Outputs     : res       : INT 1 or 0 indicating success or failure.
;                        Keywords    : fixed     : INT flag indicating fixed OG.
;                   process      : Outputs items as text array.
;                        Use         : <res = self->process(text, REORDER=reorder)>
;                        Outputs     : res       : INT 1 or 0 indicating success or failure.
;                                      text      : STRARR[] text from sequences.
;                        Keywords    : reorder   : INT flag indicating should time order sequences (else orders in OG number order).
;
; Use         : <dummy = {EIS_CPT_og_class}>
;
; Inputs      : None.
;
; Opt. Inputs : None.
;
; Outputs     : Sets up class structure.
;
; Opt. Outputs: None.
;
; Keywords    : None,
;
; Calls       : None.
;
; Common      : None.
;
; Restrictions: None.
;
; Side effects: None.
;
; Category    : EIS_CPT.
;
; Prev. Hist. : None.
;
; Written     : Martin Carter RAL 27/04/07, MKC
;
; Modified    : Version 0.0, 27/04/07, MKC
;               Version 0.1, 18/05/07, MKC
;                 Removed global indentation of commands.
;               Version 0.2, 31/01/08, MKC
;                 Changed error text if OG number overflow.
;                 Added check that OG number array size not exceeded.
;                 Used EIS CPT constants for EIS OG number range.
;               Version 0.3, 22/04/14, MKC
;                 Changed mechanism for specifying range of available OG numbers.
;                 Replaced with keyword FIXED in method add.
;                 Changed check on fixed OG.
;                 Added OG fixed tag to EIS CPT og class.
;                 Changed OG number overflow message.
;                 Removed OG number invalid message.
;
; Version     : 0.3, 22/04/14
;-
;**********************************************************

FUNCTION eis_cpt_og_class::add, time, seq_name, description, commands, FIXED=fixed

  ; get OG number 

  ; check if OG sequence present already in OG store 

  IF self.number GT 0 THEN BEGIN

    ; get list of sequences with the same name

    list = WHERE(self.store[0:self.number-1].seq_name EQ seq_name, count)

    IF count GT 0 THEN BEGIN

      ; should only be one previous command sequence with same name

      IF count NE 1 THEN MESSAGE, 'IMPLEMENTATION ERROR'

      ; get index of sequence with the same name

      index = list[0]

      ; do check if fixed og 
 
      IF KEYWORD_SET(fixed) THEN BEGIN

        ; check OG number correct for fixed OG

        IF self.og_number[index] NE !EIS_CPT_CONSTANTS.OG_indices[0] THEN BEGIN

          eis_cpt_message, 'ERROR, DUPLICATE OG SEQUENCE NAMES WITH DIFFERENT OG NUMBERS : '+seq_name, /INFORMATIONAL

          GOTO, error

        ENDIF

      ENDIF 

      ; get OG number

      og_number = self.og_number[index]

    ENDIF 

  ENDIF 
 
  ; if OG not in store then OG number not yet defined

  IF N_ELEMENTS(og_number) EQ 0 THEN BEGIN

    ; check og number store size not exceeded

    IF self.number GE N_ELEMENTS(self.og_number) THEN BEGIN

      eis_cpt_message, 'ERROR, OG NUMBER STORE SIZE EXCEEDED : '+self.number, /INFORMATIONAL

      GOTO, error

    ENDIF

    ; check OG numbers not all used

    IF self.number-self.og_fixed+1 GE N_ELEMENTS(!EIS_CPT_CONSTANTS.OG_indices) THEN BEGIN

      eis_cpt_message, 'ERROR, OG NUMBER OVERFLOW FOR '+seq_name 

      GOTO, error

    ENDIF

    ; check if fixed OG

    IF KEYWORD_SET(fixed) THEN BEGIN
 
      ; use first index for fixed OG 

      og_number = !EIS_CPT_CONSTANTS.OG_indices[0] 

    ENDIF ELSE BEGIN
    
      ; check if OGs in store already
 
      IF self.number EQ 0 THEN BEGIN

        ; if no OGs in store use second index
 
        og_number = !EIS_CPT_CONSTANTS.OG_indices[1]

      ENDIF ELSE BEGIN

        ; keep account of whether fixed OGs in store

        og_number = !EIS_CPT_CONSTANTS.OG_indices[self.number-self.og_fixed+1]

      ENDELSE

    ENDELSE

    ; store og_number if new OG sequence
    ; NB have not yet incremented self.number

    self.og_number[self.number] = og_number

  ENDIF

  ; prepend OG number to sequence

  eis_cpt_add, commands, 'NUMBER:'+STRING(og_number,FORMAT='(I3)')+';', /PRE

  ; add OG sequence
  ; checks OG sequence same as stored version if already present
  ; call superclass method

  IF NOT self->eis_cpt_commands_class::add ( time, seq_name, description, commands, 'OG') THEN GOTO, error

  ; set fixed flag

  IF KEYWORD_SET(fixed) THEN self.og_fixed = 1

  ; return finished OK flag

  RETURN, 1

error :

  ; issue routine name

  MESSAGE, 'ERROR', /INFORMATIONAL

  ; return error flag

  RETURN, 0

END

FUNCTION eis_cpt_og_class::process, text, REORDER=reorder

  ; check reorder flag
  ; if not time ordered then number ordered

  IF NOT KEYWORD_SET(reorder) THEN BEGIN

    ; order store according to OG number

    IF self.number GT 0 THEN BEGIN

      list = SORT(self.og_number[0:self.number-1])

      self.og_number[0:self.number-1] = self.og_number[list]

      self.store[0:self.number-1] = self.store[list]

      self.commands[0:self.number-1] = self.commands[list]

    ENDIF

  ENDIF

  ; call superclass method

  IF NOT self->eis_cpt_commands_class::process ( text, REORDER=reorder) THEN GOTO, error

  ; return finished OK flag

  RETURN, 1

error :

  ; issue routine name

  MESSAGE, 'ERROR', /INFORMATIONAL

  ; return error flag

  RETURN, 0

END

PRO eis_cpt_og_class__define

  ; NB size of store set to some suitable number in eis cpt store class define
  ;    same size should be used here for OG number array

  dummy = {EIS_CPT_og_class, og_number:INTARR(100), og_fixed:0, INHERITS eis_cpt_commands_class }

END



