;+
; PROJECT
;           HINODE/EIS
;
; NAME
;           eis_rp_cpt__DEFINE
;
; PURPOSE
;           eis_rp_cpt class definition
;
; NOTES
;           The
;
; CATEGORY
;           EIS timeline planning
;           Remote Planning
;
; WRITTEN
;           John A Rainne RAL, 8-Sep-2008
;
; VERSION
;          v0.1 JAR 10-Oct-2008
;               Modified call to eis_cpt_environment_wrapper routine
;          v0.2 JAR 28-Oct-2008
;               Corrected CMDCMDPLN to CMDPLN_EISCO
;               Corrected CO and CP mismatch
;          v0.3 JAR 13-Feb-2008
;               Delete contents of /remote_planning/eisco/cmdpln/latest
;               directory
;          v0.4 JAR 12-Apr-2009
;               Planner and observer tags were reversed. Corrected.
;          v0.5 DHB 7-May-2009
;               Upload_time_time at line 158 should be upload_time
;               Otherwise the tag can't be changed.
;          v0.6 JAR 14-Jun-2010
;               Ensure only 1 event study is appended to eis_study_detail
;               structure, regardless of how many times the trigger is
;               enabled. Previously, if 2 Eis Event BP hunters existed,
;               then 2 event tables were added.
;          v0.7 JAR 9-Dec-2010. Changed EIS pixel size to 1 arcsecond
;                Was 115. On advice from Martin and Khalid after testing
;                EIS Flare trigger at MSSL on 8-Dec-2010
;          v0.8 JAR 18-Apr-2011
;               Added "revised_plan" handling.
;          v0.9 JAR 08-Sep-2011
;               IF invalid trigger tables, then issue warning + bail out
;          v1.0 JAR 17-Nov-2011
;               Commented out an unnecessary line that was causing a crash!
;          v1.1 JAR 09-Jan-2012
;               Updated to include XRT Flare trigger handling - in line with
;               gui version: eis_cpt_gui__define.pro
;          v1.2 JAR 2-Feb-2012
;               Need to set default values of verify_fov, x0 and y0
;               whether XRT flare trigger used or not!
;          v1.3 JAR 31-Jul-2012
;               Changed the value of the tag from 1 to 3
;               "eis_eng_props.xrt_flare_parameters.eis_fov_flag".
;               Also, if x0 or y0 are zero, then subtract off an offset
;          v1.4 JAR 03-Dec-2014
;               Updated EIS Flare trigger handling. Nice.
;
;
;______________________________________________________________________________
FUNCTION eis_rp_cpt::Init , interactive = interactive , test = test

IF (KEYWORD_SET(test) EQ 1) THEN Self.test = 1B

!QUIET  = 1
!PROMPT = "RPCPT_IDL>"
get_utc , utc
date_bit   = anytim2cal(utc , /DATE , form = 8)
time_bit   = anytim2cal(utc , /TIME , form = 8)
datestring = STRJOIN([date_bit , time_bit],'_',/SINGLE)
baseName   = STRJOIN(["eis_rpcpt_" , datestring , ".log"],/SINGLE)
fileName   = CONCAT_DIR("$HOME" , baseName)

; OPENW    , lun , fileName , /GET_LUN
; PRINTF   , lun , "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
; PRINTF   , lun , "Starting the RPCPT object..."
; PRINTF   , lun , ""
; FREE_LUN , lun


;!QUIET = 0
print,"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
print,"Starting the RPCPT object..."
print,""

Self->cpt_props_from_file

RETURN , 1

END
;______________________________________________________________________________
; Cleanup
;______________________________________________________________________________
PRO eis_rp_cpt::CleanUp

OBJ_DESTROY , Self.tlc
PTR_FREE    , Self.dr_output
print,'Destroying the RPCPT object...goodbye!'
print,"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

END
;______________________________________________________________________________
;
;______________________________________________________________________________
PRO eis_rp_cpt::setProperty , opog_pass       = opog_pass            ,     $
                              obstbl_pass     = obstbl_pass          ,     $
                              co              = co                   ,     $
                              cp              = cp                   ,     $
                              tohban          = tohban               ,     $
                              start_time      = start_time           ,     $
                              stop_time       = stop_time            ,     $
                              upload_time     = upload_time

IF (N_ELEMENTS(opog_pass) GT 0) THEN BEGIN

   IF (is_number(opog_pass) NE 1) THEN                                 $
       opog_pass = FIX(opog_pass)
   IF (opog_pass LT 0) OR (opog_pass GT 9999) THEN BEGIN
       print,"This value is outside its range (0 to 9999). Ignoring!"
   ENDIF ELSE BEGIN
       Self.opog_pass_id_string = STRING(format='(I04)',opog_pass)
       print,"Successfully changed OP/OG Upload Pass Number to: "    +     $
             Self.opog_pass_id_string
   ENDELSE

ENDIF

IF (N_ELEMENTS(obstbl_pass) GT 0) THEN BEGIN

   IF (is_number(obstbl_pass) NE 1) THEN                                 $
       obstbl_pass = FIX(obstbl_pass)
   IF (obstbl_pass LT 0) OR (obstbl_pass GT 9999) THEN BEGIN
       print,"This value is outside its range (0 to 9999). Ignoring!"
   ENDIF ELSE BEGIN
       Self.obstbl_pass_id_string = STRING(format='(I04)',obstbl_pass)
       print,"Successfully changed OP/OG Upload Pass Number to: "    +     $
             Self.obstbl_pass_id_string
   ENDELSE

ENDIF

IF (N_ELEMENTS(co) GT 0) THEN BEGIN
   Self.observer = co
   print,"Successfully changed EIS CO to: " + co
ENDIF
IF (N_ELEMENTS(cp) GT 0) THEN BEGIN
   Self.planner = cp
   print,"Successfully changed Hinode CP to: " + cp
ENDIF
IF (N_ELEMENTS(tohban) GT 0) THEN BEGIN
   Self.tohban = tohban
   print,"Successfully changed Tohban to: " + tohban
ENDIF


IF (N_ELEMENTS(start_time) GT 0) THEN BEGIN

   IF (valid_time(start_time) EQ 1) THEN BEGIN
       Self.start_time = anytim2tai(start_time)
       print,"Successfully changed RPCPT Start Time"
   ENDIF ELSE BEGIN
       print,"Invalid Start Time: Ignoring!"
   ENDELSE

ENDIF

IF (N_ELEMENTS(stop_time) GT 0) THEN BEGIN

   IF (valid_time(stop_time) EQ 1) THEN BEGIN
       Self.stop_time = anytim2tai(stop_time)
       print,"Successfully changed RPCPT Stop Time"
   ENDIF ELSE BEGIN
       print,"Invalid Stop Time: Ignoring!"
   ENDELSE

ENDIF

IF (N_ELEMENTS(upload_time) GT 0) THEN BEGIN

   IF (valid_time(upload_time) EQ 1) THEN BEGIN
       Self.upload_time = anytim2tai(upload_time)
       print,"Successfully changed RPCPT Upload Time"
   ENDIF ELSE BEGIN
       print,"Invalid Upload Time: Ignoring!"
   ENDELSE

ENDIF


Self->props


END
;______________________________________________________________________________
;
;______________________________________________________________________________
PRO eis_rp_cpt::getProperty, tl_graphics = tl_graphics

tl_graphics = Self.tl_graphics

END
;______________________________________________________________________________
; cpt_props_from_file
;______________________________________________________________________________
PRO eis_rp_cpt::cpt_props_from_file

baseName = "eis_cpt_properties.txt"
fileName = CONCAT_DIR( EXPAND_PATH(GETENV('HOME')) , baseName)
IF (FILE_TEST(fileName) EQ 1) THEN BEGIN
   Self->read_cpt_props_file , fileName
   Self->props
   status = Self->test_props()
ENDIF ELSE BEGIN
   print,"eis_cpt_properties.txt file NOT found!"
ENDELSE

END
;______________________________________________________________________________
; Test CPT Properties
;______________________________________________________________________________
FUNCTION eis_rp_cpt::test_props

;
; Check start, stop and upload times
;
wot_time = ['start' , 'stop' , 'upload']
datetime = [Self.start_time , Self.stop_time , Self.upload_time]
FOR i = 0, 2 DO BEGIN
   status = Self->check_datetime(datetime[i] , wot_time[i])
   IF (status NE 1) THEN RETURN , 0B
ENDFOR
; Check time period is OK
status = Self->check_time_period()
IF (status NE 1) THEN RETURN , 0B

;
; OP/OG and OBSTBL Upload Pass IDs
;
wot_pass = ['opog' , 'obstbl']
pass_num = [Self.opog_pass_id_string , Self.obstbl_pass_id_string]
FOR i = 0, 1 DO BEGIN
   status = Self->check_pass_num(pass_num[i] , wot_pass[i])
   IF (status NE 1) THEN RETURN , 0B
ENDFOR

; print,"Check revised_plan is 0 or 1"
IF (Self.revised_plan LT 0) THEN RETURN , 0B
IF (Self.revised_plan GT 1) THEN RETURN , 0B
; print,"Revised plan value is valid"

print,"RPCPT Properties are OK!"
RETURN , 1B

END
;______________________________________________________________________________
; Read eis_cpt_properties.txt file
;______________________________________________________________________________
PRO eis_rp_cpt::read_cpt_props_file , fileName

lines = rd_ascii(fileName)

; start_time
line_split = STRSPLIT(lines[1] , /EXTRACT)
IF (N_ELEMENTS(line_split) EQ 3) THEN BEGIN
   start_time = STRJOIN(line_split[1:*],' ',/SINGLE)
   IF (valid_time(start_time) EQ 1) THEN Self.start_time = anytim2tai(start_time)
ENDIF
; stop_time
line_split = STRSPLIT(lines[2] , /EXTRACT)
IF (N_ELEMENTS(line_split) EQ 3) THEN BEGIN
   stop_time = STRJOIN(line_split[1:*],' ',/SINGLE)
   IF (valid_time(stop_time) EQ 1) THEN Self.stop_time = anytim2tai(stop_time)
ENDIF
; upload_time
line_split = STRSPLIT(lines[3] , /EXTRACT)
IF (N_ELEMENTS(line_split) EQ 3) THEN BEGIN
   upload_time = STRJOIN(line_split[1:*],' ',/SINGLE)
   IF (valid_time(upload_time) EQ 1) THEN Self.upload_time = anytim2tai(upload_time)
ENDIF

; OP/OG Pass ID
line_split = STRSPLIT(lines[4] , /EXTRACT)
IF (N_ELEMENTS(line_split) EQ 2) THEN BEGIN
   opog_pass_id_string = STRJOIN(line_split[1],' ',/SINGLE)
   Self.opog_pass_id_string = opog_pass_id_string
ENDIF
; OBSTBL Pass ID
line_split = STRSPLIT(lines[5] , /EXTRACT)
IF (N_ELEMENTS(line_split) EQ 2) THEN BEGIN
   obstbl_pass_id_string = STRJOIN(line_split[1],' ',/SINGLE)
   Self.obstbl_pass_id_string = obstbl_pass_id_string
ENDIF

; EIS CO
line_split = STRSPLIT(lines[6] , /EXTRACT)
IF (N_ELEMENTS(line_split) GT 1) THEN BEGIN
   Self.observer = STRJOIN(line_split[1:*],' ',/SINGLE)
ENDIF
; Hinode CP
line_split = STRSPLIT(lines[7] , /EXTRACT)
IF (N_ELEMENTS(line_split) GT 1) THEN BEGIN
   Self.planner = STRJOIN(line_split[1:*],' ',/SINGLE)
ENDIF
; Hinode Tohban
line_split = STRSPLIT(lines[8] , /EXTRACT)
IF (N_ELEMENTS(line_split) GT 1) THEN BEGIN
   Self.tohban = STRJOIN(line_split[1:*],' ',/SINGLE)
ENDIF
; Revised Plan
line_split = STRSPLIT(lines[9] , /EXTRACT)
IF (N_ELEMENTS(line_split) GT 1) THEN BEGIN
   Self.revised_plan = FIX(line_split[1])
ENDIF


END
;______________________________________________________________________________
; Print Properties
;______________________________________________________________________________
PRO eis_rp_cpt::props

start_time_string   = STRTRIM(anytim2utc(Self.start_time,/STIME),2)
stop_time_string    = STRTRIM(anytim2utc(Self.stop_time ,/STIME),2)
upload_time_string  = STRTRIM(anytim2utc(Self.upload_time ,/STIME),2)
revised_plan_string = STRCOMPRESS(Self.revised_plan,/REMOVE_ALL)

;          v0.4 JAR 12-Apr-2009
;               Planner and observer tags were reversed. Corrected.

print,""
print,"RPCPT Properties :  +++++++++++++++++++++++"
print,STRJOIN(["    + Start  Time  :  " ,start_time_string          ],/SINGLE)
print,STRJOIN(["    + Stop   Time  :  " ,stop_time_string           ],/SINGLE)
print,STRJOIN(["    + Upload Time  :  " ,upload_time_string         ],/SINGLE)
print,STRJOIN(["    + OP/OG  Pass  :  " ,Self.opog_pass_id_string   ],/SINGLE)
print,STRJOIN(["    + OBSTBL Pass  :  " ,Self.obstbl_pass_id_string ],/SINGLE)
print,STRJOIN(["    + EIS    CO    :  " ,Self.observer              ],/SINGLE)
print,STRJOIN(["    + Hinode CP    :  " ,Self.planner               ],/SINGLE)
print,STRJOIN(["    + EIS Tohban   :  " ,Self.tohban                ],/SINGLE)
print,STRJOIN(["    + Revised Plan :  " ,revised_plan_string        ],/SINGLE)
print,"RPCPT Properties :  +++++++++++++++++++++++"
print,""

END
;______________________________________________________________________________
; Read Plan from Database
;______________________________________________________________________________
PRO eis_rp_cpt::update_tl_graphics_str

;
; Update tl_graphics.axes structure - needed for eis_tlc object method
; "read_database"
;
rpcpt_period = Self.stop_time - Self.start_time
Self.tl_graphics.axes.x_axis_day_tai = Self.start_time
Self.tl_graphics.axes.x_axis_length  = rpcpt_period

END
;______________________________________________________________________________
; Read Plan from Database
;______________________________________________________________________________
PRO eis_rp_cpt::readPlanFromDatabase

print,"Reading Timeline Database..."
; Read database
timeline = eis_get_timeline_entries(Self.start_time, Self.stop_time, /ALL)
;
; Remove entries that don't have an entry_type = 'S' or 'E'
;
IF (N_TAGS(timeline[0]) NE 0) THEN BEGIN

    entry_type = timeline[*].entry_type
    valid_tl   = WHERE(entry_type EQ 'S' OR entry_type EQ 'E' , valid_count)
    IF (valid_count NE 0) THEN timeline   = timeline[valid_tl]

ENDIF

;
; IF no entries are found then tlc->clear_all, zero widgets and bail out
;
IF (N_TAGS(timeline[0]) EQ 0) THEN BEGIN

    print,"No timeline entries found. Aborting RPCPT"
    Self->quit

ENDIF ELSE BEGIN

    ; Create the tlc object
    Self.tlc = OBJ_NEW("eis_timeline_container" , Self)
    Self.tlc->read_database, timeline

ENDELSE

END
;______________________________________________________________________________
; Destroy object
;______________________________________________________________________________
PRO eis_rp_cpt::quit

OBJ_DESTROY , Self

END
;______________________________________________________________________________
; Test CPT
;______________________________________________________________________________
PRO eis_rp_cpt::test

Self->runCPT , jside = 2

END
;______________________________________________________________________________
; RUN CPT
;______________________________________________________________________________
PRO eis_rp_cpt::run

Self->runCPT , jside = 1

END
;______________________________________________________________________________
; Check datetime string is valid
;______________________________________________________________________________
FUNCTION eis_rp_cpt::check_time_period

time_delta = Self.stop_time - Self.start_time
line = STRJOIN(["RPCPT time period ("                                ,     $
                sec2dhms(time_delta)                                 ,     $
                ") " ] ,/SINGLE)
IF (time_delta LT 0.) THEN BEGIN
   print , line + "is INVALID! Aborting RPCPT!"
   print,"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
   RETURN , 0B
ENDIF

time_delta = Self.start_time - Self.upload_time
IF (time_delta LT 0.) THEN BEGIN
   print,"INVALID! Upload Time must be before Start Time. Aborting RPCPT!"
   print,"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
   RETURN , 0B
ENDIF

print,line + "is VALID. Continuing..."
RETURN , 1B

END
;______________________________________________________________________________
; Check Upload Pass Number string is valid
;______________________________________________________________________________
FUNCTION eis_rp_cpt::check_pass_num , pass_num , wot_pass

CASE wot_pass OF
   "opog"   : label = 'OP/OG'
   "obstbl" : label = 'OBSTBL'
ENDCASE

IF (is_number(pass_num) EQ 1) THEN BEGIN
   pass_num = FIX(pass_num)
   IF (pass_num LT 0) OR (pass_num GT 9999) THEN BEGIN
       print,""
       print,"RPCPT time is NOT a valid time format. Aborting RPCPT!"
       print,""
       print,"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
       RETURN , 0
   ENDIF ELSE BEGIN
       pass_num = STRING(format='(I04)',pass_num)
       CASE wot_pass OF
           "opog"   : Self.opog_pass_id_string = pass_num
           "obstbl" : Self.obstbl_pass_id_string = pass_num
       ENDCASE
   ENDELSE
ENDIF ELSE BEGIN
   line0 = label + " Upload Pass Number ("
   line1 = pass_num
   line2 = ") is NOT valid. Aborting RPCPT!"
   line3 = STRJOIN([line0 , line1 , line2],/SINGLE)
   print,""
   print,line3
   print,""
   print,"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
   RETURN , 0

ENDELSE

RETURN , 1B

END
;______________________________________________________________________________
; Check datetime string is valid
;______________________________________________________________________________
FUNCTION eis_rp_cpt::check_datetime , datetime , wot_time

IF (valid_time(datetime) EQ 1) THEN BEGIN
   CASE wot_time OF
       "start"  : Self.start_time  = anytim2tai(datetime)
       "stop"   : Self.stop_time   = anytim2tai(datetime)
       "upload" : Self.upload_time = anytim2tai(datetime)
       ELSE     : stop
   ENDCASE
ENDIF ELSE BEGIN
   print,""
   print,"RPCPT time is NOT a valid time format. Aborting RPCPT!"
   print,"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
   RETURN , 0B
ENDELSE

RETURN , 1B

END
;______________________________________________________________________________
; Test CPT
;______________________________________________________________________________
PRO eis_rp_cpt::testCPT

Self->runCPT , jside = 2

END
;______________________________________________________________________________
; RUN CPT
;______________________________________________________________________________
PRO eis_rp_cpt::apply

Self->runCPT , jside = 1

END
;______________________________________________________________________________
; Check for EIS_EVENT
;______________________________________________________________________________
FUNCTION eis_rp_cpt::check_for_eis_event , cpt_tlc

; 1. Check if there are any tl entries flagged to respond to EIS Events
;    The result is an array of {eis_event_component} structures, one for
;    each studyRaster flagged with an EIS EVENT trigger. The result will
;    be zero if NO such entries are found (hence use N_TAGS on result to
;    decide).
cpt_tlc_eis_event = cpt_tlc->eis_event_structure()

; 2. If there are such entries, then let's get to work
IF (N_TAGS(cpt_tlc_eis_event[0]) GT 0) THEN BEGIN
   ; 3. OK, how many we got? If > 1, then we need to ensure the props
   ;    are the same for all. If so, just take the first one and
   ;    carry on.
   IF (N_ELEMENTS(cpt_tlc_eis_event) GT 1) THEN BEGIN

       stop
       valid = eis_event_props_same(cpt_tlc_eis_event)
       IF (valid.valid NE 1) THEN BEGIN
           BEEP
           complain = DIALOG_MESSAGE( valid.mText                ,         $
                         DIALOG_PARENT = Self.tlbID          ,             $
                         /ERROR )
           RETURN , 0

       ENDIF
   ENDIF
   ; 4. OK, this is where we actually check the properties have been
   ;    set.
   valid           = eis_event_props_valid(cpt_tlc_eis_event[0])
   stop
   ; 5. If there's a problem, report it here! Then bail out!
   IF (valid.valid NE 1) THEN BEGIN
       BEEP
       complain = DIALOG_MESSAGE( valid.mText                ,             $
                         DIALOG_PARENT = Self.tlbID          ,             $
                         /ERROR )
       RETURN , 0

   ENDIF

ENDIF

RETURN , cpt_tlc_eis_event

END
;______________________________________________________________________________
; Check for XRT_FLARE
;______________________________________________________________________________
FUNCTION eis_rp_cpt::check_for_xrt_flare , cpt_tlc

; 1. Check if there are any tl entries flagged to respond to EIS Events
;    The result is an array of {eis_event_component} structures, one for
;    each studyRaster flagged with an EIS EVENT trigger. The result will
;    be zero if NO such entries are found (hence use N_TAGS on result to
;    decide).
cpt_tlc_xrt_flare = cpt_tlc->xrt_flare_structure()

RETURN , cpt_tlc_xrt_flare

END
;______________________________________________________________________________
; Run CPT
;______________________________________________________________________________
PRO eis_rp_cpt::runCPT , JSIDE = JSIDE

status = Self->test_props()
IF (status NE 1) THEN BEGIN
   print,"RPCPT Properties are INVALID! Correct and try again!"
   RETURN
ENDIF

; JAR 13-Feb-2009. Friday the 13th.
; Valentine's Day tomorrow. Aaaahhhh!! Which is scarier?
; Delete existing files in /remote_planning/eisco/cmdpln/latest
pathName = STRJOIN([GETENV('CMDPLN_EISCO'),'latest'],/SINGLE,PATH_SEP())
IF (FILE_TEST(pathName , /DIRECTORY) EQ 1) THEN BEGIN
   files = FILE_SEARCH(pathName , '*' , count = count)
   IF (count GT 0) THEN FILE_DELETE , files , /QUIET
ENDIF


; Read timeline database
Self->readPlanFromDatabase
IF (OBJ_VALID(Self.tlc) NE 1) THEN BEGIN
    BEEP
    print,'There are NO entries in this time range. Aborting!'
    Self->quit
ENDIF
;
; OK, 'cos we're reading an extended range of the database, we've probably
; got some entries that lie outside the CPT time range!
;
; What about entries that cross the CPT time range?????
;
all_tlc_entries = Self.tlc->get(/ALL)
;
; Loop over entries, weeding out those that are NOT within the
; CPT time range
;
; Make a temporary IDL_CONTAINER - and populate it with just
; those entries that are within the CPT time range
;
cpt_tlc = OBJ_NEW('EIS_TIMELINE_CONTAINER' , Self)
FOR i = 0 , Self.tlc->count() -1 DO BEGIN

    s = all_tlc_entries[i]->get()

    IF (s.time_component.start_time LE Self.stop_time  ) AND                    $
       (s.time_component.start_time GE Self.start_time ) THEN BEGIN

        IF (s.time_component.entry_type EQ 'S') OR                          $
           (s.time_component.entry_type EQ 'E') THEN BEGIN

            ; Set planning party values
            s.science_component.observer   = Self.observer
            s.science_component.planner    = Self.planner
            s.science_component.tohbans[0] = Self.tohban
            all_tlc_entries[i]->set , s
            ; If within CPT time range, then save to cpt_tlc
            cpt_tlc->add , all_tlc_entries[i]

        ENDIF

    ENDIF

ENDFOR


count = cpt_tlc->count()
IF (count LT 1) THEN BEGIN
    BEEP
    print,'There are NO entries in this time range. Aborting!'
    Self->quit
ENDIF

; OK, make sure we have read all of the science components
FOR i = 0 , count -1 DO BEGIN

    temp = cpt_tlc->get(POSITION = i)
    temp->getProperty , seq_id = seq_id
    print,'CPTing seq_id = ' + STRCOMPRESS(seq_id,/REMOVE_ALL)
    tl   = temp->get()
    tc   = tl.time_component
    IF (tc.read_all NE 1) THEN temp->get_all_info

ENDFOR

;______________________________________________________________________________
;
; Get an array of the entry details
;
;______________________________________________________________________________
;
; Create a list (array of structures) of each timeline entry
;
eis_study_detail  = eis_list_timeline_entries(cpt_tlc)

;______________________________________________________________________________
;
; Event Trigger Studies
;
;______________________________________________________________________________
; OK, are there any event triggers? If so, then check all event control
; tables are valid, and that there is only 1 unique table

; Get verify_fov, x0 and y0 values. These need to go into
; eis_eng_props.xrt_flare_parameters structure.
; Need to set default values whether XRT flare trigger used or not!
; If an xrtf trigger is used, these variables will be updated.
verify_fov = 1
x0y0       = eis_get_default_x0y0()
x0         = x0y0[0]
y0         = x0y0[1]

triggers = cpt_tlc->detect_trigger_studies(/QUIET)
; If so, check them
IF (N_TAGS(triggers[0]) NE 0) THEN BEGIN

   ; Instantiate eis_response_obj object and check event tables
   eis_response_obj = OBJ_NEW("eis_response_obj" , cpt_tlc , triggers)
   valid = eis_response_obj->check_is_valid()

   IF (valid EQ 1) THEN BEGIN
       print,''
       print,'Trigger/Response Events are Valid....continuing with CPT'
       print,'********************************************************'
   ENDIF ELSE BEGIN
       line_0 = ''
       line_1 = 'Trigger/Response Events are NOT Valid!'
       line_2 = 'CPT cannot be continued until the they are valid!'
       line_3 = 'Bye'

       ; JAR 08-Sep-2011
       ; IF invalid trigger tables, then print warning + bail out
       BEEP
       print,line_0
       print,line_1
       print,line_2
       print,line_3
       print,'********************************************************'
       ; 2. Cleanup cpt_tlc
       cpt_tlc->REMOVE , /ALL
       OBJ_DESTROY , cpt_tlc
       ; 3. Cleanup eis_response_obj
       OBJ_DESTROY , eis_response_obj
       ; 4. Cleanup triggers - don't need cleanup
       ; 5. And finally.....bail out!!
       RETURN

   ;ENDELSE - 17-Nov-2011 commented out this unnessecary line!
   ENDELSE

   ; Call eis_response_obj method to create the eis_control structure
   eis_control = eis_response_obj->get_eis_control()

   ; Finally, destroy Object
   OBJ_DESTROY , eis_response_obj

   eise_all        = 0
   eisf_all        = 0
   xrtf_all        = 0
   xrtf_filler_all = 0

   ; Get study details for response and filler studies
   FOR i = 0 , N_ELEMENTS(triggers) - 1 DO BEGIN

       trigger = triggers[i]

       ; OK, what type of response study are we dealing with here?
       eebp_event = STRMATCH(trigger.type,'eebp',/FOLD_CASE)
       IF (eebp_event EQ 1) THEN BEGIN
           eise = eis_get_eis_event_study_details(trigger.st_id_response)
           CASE N_TAGS(eise_all[0]) OF
               0    : eise_all =  eise
               ELSE : eise_all = [eise_all , eise]
           ENDCASE
       ENDIF

       eisf_event = STRMATCH(trigger.type,'eisf',/FOLD_CASE)
       IF (eisf_event EQ 1) THEN BEGIN
           ; 01-Dec-2014 JAR
           ; Get response study ID from the response DB
           ;stop
           ;status         = eis_open_db(/RESPONSE)
           response_st_id = trigger.st_id_response
           ;print,response_st_id
           ;dbclose
           eisf = eis_get_eis_flare_study_details(response_st_id)
           CASE N_TAGS(eisf_all[0]) OF
               0    : eisf_all =  eisf
               ELSE : eisf_all = [eisf_all , eisf]
           ENDCASE

       ENDIF

       xrtf_event = STRMATCH(trigger.type,'xrtf',/FOLD_CASE)
       IF (xrtf_event EQ 1) THEN BEGIN
           ; 26-Jun-2013 JAR
           ; Get response and filler study IDs from the response DB
           status         = eis_open_db(/RESPONSE)
           response_st_id = dbval(trigger.resp_id, 'RESPONSE_ST_ID')
           filler_st_id   = dbval(trigger.resp_id, 'FILLER_ST_ID')
           x0             = dbval(trigger.resp_id, 'LOCATE_X')
           y0             = dbval(trigger.resp_id, 'LOCATE_Y')
           verify_fov     = dbval(trigger.resp_id, 'LINE_INDEX')
           dbclose
           ; Now get response study details and concatenate to list
           xrtf = eis_get_xrt_flare_study_details(response_st_id)
           CASE N_TAGS(xrtf_all[0]) OF
               0    : xrtf_all =  xrtf
               ELSE : xrtf_all = [xrtf_all , xrtf]
           ENDCASE

           ; If defined, then get Filler study details
           IF (filler_st_id GT 0) THEN BEGIN
               xrtf = eis_get_xrt_flare_study_details(filler_st_id,$
                                                        /FILLER_STUDY)
               CASE N_TAGS(xrtf_filler_all[0]) OF
                   0    : xrtf_filler_all =  xrtf
                   ELSE : xrtf_filler_all = [xrtf_filler_all , xrtf]
               ENDCASE

           ENDIF
       ENDIF


   ENDFOR

   ; 14-Jun-2010
   IF (N_TAGS(eise_all[0]) GT 0) THEN                                      $
       eis_study_detail = [eis_study_detail,eise_all[0]]
   IF (N_TAGS(eisf_all[0]) GT 0) THEN                                      $
       eis_study_detail = [eis_study_detail,eisf_all[0]]
   IF (N_TAGS(xrtf_all[0]) GT 0) THEN                                      $
       eis_study_detail = [eis_study_detail,xrtf_all[0]]
   IF (N_TAGS(xrtf_filler_all[0]) GT 0) THEN                               $
       eis_study_detail = [eis_study_detail,xrtf_filler_all[0]]

ENDIF





; ;
; ; EIS EVENT Trigger Studies
; ;
; ; Get study_detail of EIS EVENT response study (if there is one) and append
; ; it to "eis_study_detail"
; cpt_tlc_eis_event = Self->check_for_eis_event(cpt_tlc)
; IF (N_TAGS(cpt_tlc_eis_event[0]) GT 0) THEN BEGIN
;
;    st_id            = cpt_tlc_eis_event[0].response_study_id
;    eise             = eis_get_eis_event_study_details(st_id)
;    eis_study_detail = [eis_study_detail,eise]
;
; ENDIF
;
; ;
; ; XRT Flare
; ;
; ; Get study_detail of XRT response study (if there is one) and append it
; ; to "eis_study_detail"
; eis_xrt_flare_control = Self->check_for_xrt_flare(cpt_tlc)
; st_id = eis_xrt_flare_control.response_identifier
; IF (st_id NE 0) THEN BEGIN
;
;     xrtf = eis_get_xrt_flare_study_details(st_id)
;     eis_study_detail = [eis_study_detail,xrtf]
;
; ENDIF
; ; Get study_detail of XRT filler study (if there is one) and append it
; ; to "eis_study_detail"
; st_id = eis_xrt_flare_control.filler_identifier
; IF (st_id NE 0) THEN BEGIN
;
;     xrtf = eis_get_xrt_flare_study_details(st_id , /filler_study)
;     eis_study_detail = [eis_study_detail,xrtf]
;
; ENDIF
;
; ;
; ; Concatenate trigger studies to study list
; ;
; eis_control = eis_get_control( eis_xrt_flare_control     ,                $
;                                cpt_tlc_eis_event[0]                   )


;
; Engineering Properties
;
eis_eng_props     = eis_get_engineering()
; JAR 9-Dec-2010. Changed EIS pixel size to 1 arcsecond
; Was 115. On advice from Martin and Khalid after testing
; EIS Flare trigger at MSSL on 8-Dec-2010
eis_eng_props.eis_flare_parameters.eis_p_size = 100


; JAR 31-Jul-2012
; If x0 or y0 are NOT zero, then subtract CMIR offset
; Commented out on 12-Dec-2012
;IF (x0 NE 0.) THEN x0 = x0 - 77
;IF (y0 NE 0.) THEN y0 = y0 - 16

;
; JAR 14-Dec-2011
; Hard wire the XRT Flare parameters
;
; These tags needs updating - they are editable by the planner!
eis_eng_props.xrt_flare_parameters.verify_fov     = verify_fov
eis_eng_props.xrt_flare_parameters.x0             = x0
eis_eng_props.xrt_flare_parameters.y0             = y0
;print,eis_eng_props.xrt_flare_parameters.verify_fov
;print,eis_eng_props.xrt_flare_parameters.x0
;print,eis_eng_props.xrt_flare_parameters.y0



; The following are hard-coded.
eis_eng_props.xrt_flare_parameters.x_conversion   = 1
eis_eng_props.xrt_flare_parameters.y_conversion   = 0
eis_eng_props.xrt_flare_parameters.angle          = 0
eis_eng_props.xrt_flare_parameters.ocb            = 8
eis_eng_props.xrt_flare_parameters.xrt_pixel_size = 100
; JAR 31-Jul-2012. Changed the following from 1 to 3
eis_eng_props.xrt_flare_parameters.eis_fov_flag   = 3
; End of XRT Flare parameters!

;
; BakeOut Properties
;
;eis_bakeout_props = eis_list_bakeout_periods(cpt_tlc)
;
; Upload Parameters
;
eis_upload            = {EIS_upload}
eis_upload.time       = Self.upload_time
upload_time_string1   = anytim2utc(Self.upload_time    , /STIME   , /DATE)
upload_time_string2   = anytim2cal(upload_time_string1 , FORM = 8 , /DATE)
; Fill in eis_upload structure values
eis_upload.obstbl_upload_id = STRJOIN([upload_time_string2,Self.obstbl_pass_id_string],/SINGLE)
eis_upload.orl_upload_id    = STRJOIN([upload_time_string2,Self.opog_pass_id_string],/SINGLE)
eis_upload.version          = ''
eis_upload.ram_sub_id       = ''

; Is reset button selected - ON
reset = 0
IF (Self.reset_on EQ 1) THEN BEGIN

    CASE Self.soft_reset OF
        0: reset = 2
        1: reset = 1
    ENDCASE

ENDIF

Self->eis_cpt_environment_wrapper

print,'+++++++++++++++++++++++++++++++++++++++++++++++++++++++'
print,STRJOIN(['CPT started at          : ',systime()],/SINGLE)

cpt = eis_cpt( engineering           = eis_eng_props             ,          $
               revised_plan          = Self.revised_plan         ,          $
               JSIDE                 = JSIDE                     ,          $
               UPLOAD                = eis_upload                ,          $
               MSSL                  = Self.mssl                 ,          $
               INTEL                 = Self.intel                ,          $
               QUIET                 = Self.quiet                ,          $
               RESET                 = reset                     ,          $
               CONTROL               = eis_control               ,          $
               TIME_PERIOD           = [Self.start_time,Self.stop_time]  ,  $
               STUDIES               = eis_study_detail                    $
               ;widget                = Self.outputTextID                    $
;               contact_info          = eis_read_file_station_events(fileName)    $
            )


IF (cpt EQ 0) THEN BEGIN
    BEEP
    print,'CPT error. Aborting.'
ENDIF ELSE BEGIN
    ;
    ; Write dR output file
    ;
    olines = cpt_tlc->create_dr_output(                                    $
                        start_time = anytim2tai(Self.start_time)     ,     $
                        stop_time  = anytim2tai(Self.stop_time ) )
    PTR_FREE , Self.dr_output
    Self.dr_output = PTR_NEW(olines)
    ; And finally, write to the file
    Self->write_dr_output_file , Self.opog_pass_id_string

    fileName = Self->get_dr_output_filename(Self.opog_pass_id_string)
    BEEP
    print,'Data Rate output file   : ' + fileName

    ;
    ; 3-Apr-2007
    ; JAR - adding plan_summary
    fileName = Self->get_plan_summary_filename()
    mText = 'Plan Summary file       : ' + fileName
    print,mText
    eis_ps = OBJ_NEW('eis_plan_summary' , cpt_tlc , fileName)
    OBJ_DESTROY , eis_ps

    print,'CPT ran successfully    : Time for coffee!'
    print,'+++++++++++++++++++++++++++++++++++++++++++++++++++++++'

ENDELSE

;
;
; OK , remove objects from the cpt_tlc container. They're still in use
; in the tlc container. The destroy the cpt_tlc container!!
;
cpt_tlc->REMOVE , /ALL
OBJ_DESTROY , cpt_tlc

END
;______________________________________________________________________________
; Write DR file
;______________________________________________________________________________
PRO eis_rp_cpt::eis_cpt_environment_wrapper

; JAR 18-Sep-2008
eis_cpt_output_path = EXPAND_PATH(EXPAND_PATH(GETENV('cpt_output_dir')))
eis_cpt_input_path  = EXPAND_PATH(EXPAND_PATH(GETENV('cpt_input_dir' )))
cmdpln_eisco        = EXPAND_PATH(GETENV('CMDPLN_EISCO' ))

; Define eis_cpt environment constants
eis_cpt_environment_wrapper                                          ,     $
            concat_dir(eis_cpt_output_path , 'obstbl')               ,     $
            concat_dir(eis_cpt_output_path , 'obstbl_map')           ,     $
            concat_dir(eis_cpt_input_path  , 'engineering_tables')   ,     $
            concat_dir(eis_cpt_input_path  , 'sibcmd-table-20070731'),     $
   LATEST = concat_dir(cmdpln_eisco        , 'latest')               ,     $
   MSSL   = concat_dir(eis_cpt_output_path , 'mssl_tables')          ,     $
   INTEL  = concat_dir(eis_cpt_output_path , 'intel_tables')         ,     $
   ORL    = concat_dir(eis_cpt_output_path , 'orl')                  ,     $
   OBSTBL = concat_dir(eis_cpt_output_path , 'obstbl')               ,     $
   MAP    = concat_dir(eis_cpt_output_path , 'obstbl_map')

END
;______________________________________________________________________________
; Write DR file
;______________________________________________________________________________
PRO eis_rp_cpt::write_dr_output_file , opog_pass_id_string

fileName = Self->get_dr_output_filename(Self.opog_pass_id_string)

OPENW  , lun , fileName , /GET_LUN
FOR i = 0, N_ELEMENTS(*Self.dr_output) - 1 DO BEGIN
   PRINTF , lun , (*Self.dr_output)[i]
ENDFOR
FREE_LUN , lun

; Copy this file to $HOME/cmdpln/latest directory
baseName = FILE_BASENAME(fileName)
pathName = STRJOIN([EXPAND_PATH(GETENV('CMDPLN_EISCO')),'latest']    ,     $
                                              PATH_SEP(),/SINGLE)
IF (FILE_TEST(pathName,/DIRECTORY) EQ 1) THEN BEGIN
   fileName_copy = CONCAT_DIR(pathName , baseName)
   FILE_COPY , fileName , fileName_copy , /OVERWRITE , /FORCE
   ;IF ~FILE_TEST(fileName_copy) THEN FILE_COPY , fileName , fileName_copy
   value = STRJOIN(['Data Rate output file   : ',fileName_copy],/SINGLE)
   print,value
ENDIF

END
;______________________________________________________________________________
; Create DR output filename
;______________________________________________________________________________
FUNCTION eis_rp_cpt::get_dr_output_filename , opog_pass_id_string

; Get Upload Time
upload_time_string = anytim2utc(Self.upload_time,/STIME)
; Create date string - 20070615
date_string = anytim2cal(upload_time_string , form = 8 , /DATE)

; Create fileName
pathName = EXPAND_PATH(GETENV('cpt_output_dir'))
pathName = STRJOIN([pathName,'dr'],PATH_SEP(),/SINGLE)
baseName = STRJOIN(['dr_EIS_' , date_string ,Self.opog_pass_id_string, '.txt'] , /SINGLE)

RETURN , CONCAT_DIR(pathName , baseName)

END
;______________________________________________________________________________
; Create eis_plan summary filename
;______________________________________________________________________________
FUNCTION eis_rp_cpt::get_plan_summary_filename

; Get Upload Time
upload_time_string = anytim2utc(Self.upload_time,/STIME)
; Create date string - 20070615
date_string = anytim2cal(upload_time_string , form = 8 , /DATE)

; Create fileName
pathName = EXPAND_PATH(GETENV('cpt_output_dir'))
pathName = STRJOIN([pathName,'eis_plan'],PATH_SEP(),/SINGLE)
baseName = STRJOIN(['eis_plan_' , date_string , '.txt'] , /SINGLE)

RETURN , CONCAT_DIR(pathName , baseName)

END
;______________________________________________________________________________
; Define Data members
;______________________________________________________________________________
PRO eis_rp_cpt__define

struct  =  { eis_rp_cpt                                              ,   $
                   dr_output             : PTR_NEW()                 ,   $
                   tlc                   : OBJ_NEW()                 ,   $
                   tl_graphics           : {eis_timeline_graphics}   ,   $
                   opog_pass_id_string   : ""                        ,   $
                   obstbl_pass_id_string : ""                        ,   $
                   test                  : 0B                        ,   $
                   planner               : ""                        ,   $
                   observer              : ""                        ,   $
                   tohban                : ""                        ,   $
                   start_time            : 0.D                       ,   $
                   stop_time             : 0.D                       ,   $
                   upload_time           : 0.D                       ,   $
                   revised_plan          : 0                         ,   $
                   mssl                  : 0B                        ,   $
                   intel                 : 0B                        ,   $
                   quiet                 : 0B                        ,   $
                   reset_on              : 0B                        ,   $
                   soft_reset            : 0B                            $
           }

END
