;+
; Project     : SOLAR-B - EIS
;
; Name        : EIS_CPT_SEQUENCE_MATCH
;
; Purpose     : Finds if sequence tables already loaded into OBSTBL.
;
; Explanation : This routine locates the sequence tables forming each study if they are already in OBSTBL.
;               NB There is a limitation of the approach taken which occurs if the same study
;               is used at the start of different daisy-chains. A repeat of one of the daisy-chains may not
;               find the existing studies loaded since the first occurrance is taken.
;
; Use         : < result = eis_cpt_sequence_match( sequences ) >
;
; Inputs      : sequences   : STRUCTURE ARRAY of type EIS_CPT_sequence.
;
; Opt. Inputs : None.
;
; Outputs     : result      : INT flag :
;                               1 : processed science plan OK.
;                               0 : processing failed.
;               sequences   : STRUCTURE ARRAY updates .exact tag.
;
; Opt. Outputs: None.
;
; Keywords    : None.
;
; Calls       : None.
;
; Common      : None.
;
; Restrictions: None.
;
; Side effects: May output ASCII files.
;
; Category    : EIS_CPT.
;
; Prev. Hist. : None.
;
; Written     : Martin Carter RAL 17/09/05
;
; Modified    : Version 0.0, 17/09/05, MKC
;               Version 0.1, 05/10/05, MKC
;                 Allowed for obscure case where exact match found lower down in a daisy-chain
;                 but for a different table_index.
;                 Changed so that table_index = -1 if no placement found.
;               Version 0.2, 16/06/06, MKC
;                 Changed so that table index is undefined if no place found for table.
;
; Version     : 0.2, 16/06/06
;-
;**********************************************************

FUNCTION eis_cpt_sequence_match, sequences

  ; loop through sequence tables finding any tables that already have exact matches loaded

  FOR s = 0, N_ELEMENTS(sequences)-1 DO BEGIN

    ; set running index to sequence
    ; this will point to the next sequence in the sequence list
    ; this will be set to -1 if daisy-chain sequence terminates

    ss = s

    ; unset table_index so that all OBSTBL sequence tables are searched
    ; this will point to the next table in OBSTBL
    ; this will be undefined if daisy-chain sequence terminates

    eis_cpt_undefine, table_index

    ; undefine sequence indexes in exact match daisy-chain

    eis_cpt_undefine, sequence_indexes

    ; initialize exact flag
    ; this will be switched off if mismatch occurs

    exact = 1

    ; loop through daisy-chain, checking next linked sequence
    ; if sequence already tagged as exact match then ignore to avoid unnecessary work and loops

    WHILE exact AND ss GE 0 AND sequences[ss>0].exact EQ 0 DO BEGIN

      ; check if this sequence has an exact match in OBSTBL
      ; NB ignores the last two bytes (i.e linked sequence table index and checksum) in looking for an exact match

      IF NOT eis_cpt_obstbl(sequences[ss].bytes, table_index, dummy, dummy, $
                            /PLACE, /SEQUENCE, /USED, /EXACT) THEN GOTO, error

      ; check if match found

      IF N_ELEMENTS(table_index) EQ 0 THEN BEGIN

        ; no match found, terminate processing this daisy-chain

        exact = 0

      ENDIF ELSE BEGIN

        ; match found

        ; mark sequence as exact match

        sequences[ss].exact = 1

        ; store location of OBSTBL table

        sequences[ss].index = table_index

        ; store indexes of sequence found in this daisy-chain

        eis_cpt_add, sequence_indexes, ss

        ; since there is an exact match there will already be agreement as to whether the
        ; sequence terminates or continues (the sequence control command is checked but not its argument or the checksum)

        ; check if daisy-chain terminates

        IF sequences[ss].link GE 0 THEN BEGIN

          ; get next sequence in daisy-chain
          ; get OBSTBL table that OBSTBL sequence points to

          IF NOT eis_cpt_obstbl(table, table_index, dummy, dummy, /EXTRACT, /SEQUENCE) THEN GOTO, error

          ; set daisy-chained OBSTBL table index

          table_index = table[table[0]-2]

        ENDIF

        ; point to next sequence in sequence list

        ss = sequences[ss].link

      ENDELSE

    ENDWHILE

    ; if sequences marked as exact but match turned out false then unmark them

    ; check if any sequences matched

    IF N_ELEMENTS(sequence_indexes) GT 0 THEN BEGIN

      ; check if no match broke down

      IF NOT exact THEN BEGIN

        ; unmark all sequences in daisy-chain as exact matches

        sequences[sequence_indexes].exact = 0

      ENDIF ELSE IF ss GE 0 AND sequences[ss>0].exact THEN BEGIN

        ; daisy-chain references an existing daisy chain with exact match
        ; NB this is not applied if the exact match is to the first sequence in the daisy-chain
        ; check if table indexes match
        ; ( have a study which links to another study in the plan
        ;   the other study has already been matched to a loaded study
        ;   but table index of other study differs from linked table index in current study
        ;   i.e other study is not the one linked to in the current sequence table )

        IF sequences[ss].index NE table_index THEN BEGIN

          ; false match

          eis_cpt_message, 'WARNING, FALSE DAISY-CHAIN MATCH ENCOUNTERED, CANNOT RE-USE STUDY'

          ; unmark all sequences in daisy-chain as exact matches

          sequences[sequence_indexes].exact = 0

        ENDIF

      ENDIF

    ENDIF

  ENDFOR

  ; return finished OK flag

  RETURN, 1

error :

  ; issue routine name

  MESSAGE, 'ERROR', /INFORMATIONAL

  ; return error flag

  RETURN, 0

END





