;+
; Project     : SOHO - CDS
;
; Name        : XCPT
;
; Purpose     : widget interface to CPT
;
; Category    : planning
;
; Syntax      : IDL> XCPT
;
; Inputs      : None
;
; Opt. Inputs : TSTART,TEND = start/end times to process
;
; Keywords    : GROUP = widget id of calling widget
;               ERR = error string
;               STATUS = 0/1 if user aborted/proceeded with CPT
;
; Restrictions: Normally run after IAP file is created with XIAP
;
; History     : 26-Jan-1996,  D.M. Zarro.  Written
;               09-Oct-1997.  Change use of adjust_allowed keyword.  CDP
;               11-Feb-1999.  Fixed a typo introduced at some time in the recent past?! CDP
;               28-Dec-1999.  Added pointing to preview option (DMZ)
;               15-Sep-2002.  Used SAVEGEN/RESTGEN for log files (DMZ)
;                7-Jul-2003.  Added SOHO_ORIENT label - Zarro (EER/GSFC)
;                3-Dec-2003.  Added second check for SOHO_ORIENT -
;                Zarro (L-3Com/GSFC)
;                6-Jan-2009. Fixed a bug with modal
;
; Contact     : DZARRO@SOLAR.STANFORD.EDU
;-

 pro xcpt_event,event

 common xcpt_com,info

 widget_control, event.id, get_uvalue = uservalue
 wtype=widget_info(event.id,/type)
 if (n_elements(uservalue) eq 0) then uservalue=''
 bname=strtrim(uservalue,2)

 case bname of

 'OPS1' : begin 
           good=xvalidate(info,event,/bytag)
           if good then xcpt_set_roll
          end

 'OPS2' : begin 
           good=xvalidate(info,event,/bytag)
           if good then xcpt_set_roll
          end

 'QUIT' : begin
   xtext_reset,info
   xkill,event.top
  end

 'RESET': begin
   for i=0,n_elements(info.sbuttons)-1 do widget_control,info.sbuttons(i),set_button=0 
   info.now=0 & info.new=0 & info.new=0 & info.emergency=1 & info.adjust=0
   info.ops1=info.def_ops1 & info.ops2=info.def_ops2
   widget_control,info.wops1,set_value=tai2utc(info.ops1,/ecs,/vms)
   widget_control,info.wops2,set_value=tai2utc(info.ops2,/ecs,/vms)
   widget_control,info.wmess,set_value=''
  end
 
 'PREVIEW': begin
   good=xvalidate(info,event,/bytag)
   cds_plan_brief,info.ops1,info.ops2,group=event.top,nobs=nobs,/acr,/det,/point
   if exist(nobs) then begin
    if nobs eq 0 then $
     xack,'No detailed plans during specified period',group=event.top else $
      info.previewed=1
   endif
  end 

 'VIEW': begin
   log_exist=loc_file(info.logfile,count=nf)
   if nf gt 0 then begin
    cpt_log=0
    restgen,cpt_log,file=info.logfile
    xlist,cpt_log,group=event.top,pad=3,title='Log of last CPT runs',/clear,/modal
    if datatype(cpt_log) ne 'STC' then rm_file,info.logfile
    return
   endif else xtext,'No CPT log file exists',/just_reg,/wait
  end
 else:do_nothing=1
 endcase

;-- check other button inputs

 slook=where(bname eq info.svalues,cnt)
 if cnt eq 1 then begin
  item=info.svalues(slook(0))
  s='info.'+item+'='+string(event.select)
  s=execute(s)
  if info.now then begin
   get_utc,temp 
   info.ops1=utc2tai(temp)
   temp.time=0 
   temp.mjd=temp.mjd+1
   info.ops2=utc2tai(temp)
   widget_control,info.wops1,set_value=tai2utc(info.ops1,/ecs,/vms)
   widget_control,info.wops2,set_value=tai2utc(info.ops2,/ecs,/vms)
  endif
 endif

;-- check times before running

 if bname eq 'RUN' then begin
  
  good=xvalidate(info,event,/bytag)
  if good then begin
   old_roll=getenv('SOHO_ORIENT')
   roll=get_soho_roll(info.ops1)
   if roll ne old_roll then begin
       rmess = ['Caution: SOHO roll changed to '+trim(string(roll,'(f7.1)'))+ $
                ' (DEGS)']
       val=xanswer(rmess,group=event.top,instruct='Continue with CPT?',def=1)
       if not val then return
   endif
   xcpt_set_roll
   if (not info.previewed) then begin
    rmess=['It is strongly recommended that you preview detailed studies ',$
         'before running CPT.']

    val=xanswer(rmess,group=event.top,instruct='Preview studies?',/suppress,def=0)
   endif else val=0

   if val then begin
    cds_plan_brief,info.ops1,info.ops2,group=event.top,nobs=nobs,/acr,/det,/point
    if nobs eq 0 then begin
     xack,'No detailed plans during specified period',group=event.top
     return
    endif else info.previewed=1
    val=xanswer('Continue with CPT?',group=event.top)
    if not val then return
   endif
 
;-- check that first plan is time-tagged

   widget_control,/hour
   err=''
   list_detail,info.ops1,info.ops2,obs,nf,err=err

   if nf gt 0 then begin
    if (err eq '') then begin
     if not obs(0).time_tagged then begin
      err='First Plan in CPT sequence must be TIME-TAGGED'
     endif
    endif
   endif else err='No plans during specified time'
   if err ne '' then begin
    xack,err,group=event.top,/icon
    return
   endif
   
   if info.new then begin
    ok=xanswer('Initializing ALL onboard tables',instruct='Are you sure?',$
       group=event.top)
   endif else ok=1

   if ok then begin

    t1=min(obs.date_obs)
    t2=max(obs.date_end)
 
;-- check and update log file

    new_cpt={Start_Time:tai2utc(t1,/ecs),Stop_Time:tai2utc(t2,/ecs)}
    clook=loc_file(info.logfile,count=count)
    if count gt 0 then begin
     cpt_log=0
     restgen,cpt_log,file=info.logfile
     new_start=str_format(info.ops1)
     new_stop=str_format(info.ops2)
     do_this=0
     if (info.new eq 0) and do_this then begin

;-- make sure new start occurs after end of last run

      last_plan_time=str_format(max(anytim2tai(cpt_log.stop_time)))
      if (new_start le last_plan_time) and (new_stop gt last_plan_time) then begin
       tgap=1.d0
       new_start=info.ops1+tgap
       dprint,'changing TSTART to '+anytim2utc(new_start,/ecs)
       widget_control,info.wops1,set_value=anytim2utc(new_start,/vms,/ecs)
       new_cpt.start_time=tai2utc(new_start,/ecs)
       new_start=str_format(new_start)
      endif

      check=where( (new_start ge str_format(anytim2tai(cpt_log.start_time))) and $
                   (new_start le str_format(anytim2tai(cpt_log.stop_time))),cnt)

      if cnt eq 0 then begin
       check=where( (new_stop ge str_format(anytim2tai(cpt_log.start_time))) and $
                    (new_stop le str_format(anytim2tai(cpt_log.stop_time))),cnt)
      endif

      if cnt eq 0 then begin
       check=where( (new_stop ge str_format(anytim2tai(cpt_log.stop_time))) and $
                    (new_start le str_format(anytim2tai(cpt_log.start_time))),cnt)
      endif

      if (cnt gt 0) then begin
       warn=['The start/end times of this CPT run overlap an earlier run that, perhaps, failed.',$
             'or was never loaded.','',$
             'It may be necessary to Initialize onboard tables.',$
             'Please check with your local CDS operator before proceeding.']
       value=xanswer(warn,group=event.top,instruct='Proceed?')
       if not value then return
      endif
     endif
    endif
    cpt_log=concat_struct(new_cpt,cpt_log)
    savegen,cpt_log,/xdr,file=info.logfile,/notype
    !priv=3
    widget_control,info.wmess,set_value='Clearing DCS...'
    widget_control,/hour
    dcs_sel_clear,anytim2utc(info.ops1),anytim2utc(info.ops2)

;-- get instrument state

    widget_control,info.wmess,set_value='Getting initial state...',/app
    widget_control,/hour
    initial_state=get_cds_state(info.ops1)

;-- if /NEW, initialize all except GSET ID

    if info.new gt 0 then begin
     base_state = {state_structure, mode:'X',solarx:0, solary:0, slitn:0, gsetid:0}
     base_state.gsetid=initial_state.gsetid
     initial_state=base_state
    endif
    widget_control,info.wmess,set_value='Running CPT...',/app
    widget_control,/hour
    cpt,startof=info.ops1,endof=info.ops2,now=info.now,$
                emergency=info.emergency,adjust=info.adjust,$
                new=info.new,state=initial_state
    !priv=3
    prepare_ft
    xshow,event.top
    info.status=1

;-- print log files

    if info.tlb then begin
     tstart=utc2str(tai2utc(info.ops1))
     ttc = loc_file(concat_dir('$CDS_CP_TTCFILES_W',tstart+ '.TTC' ),count=nf)
     status1=(nf gt 0)
     if status1 then begin
      xprint,ttc,printer=printer,status=status2,group=event.top,$
       instruct='Select printer for Table Load files'
      if status2 then begin
       ltb=loc_file(concat_dir('$CDS_CP_LTBFILES_W',tstart+ '.LTB'),count=nf)
       status3=(nf gt 0)
       if status3 then xprint,ltb,printer=printer,/nosel,group=event.top else $
        widget_control,info.wmess,set_value='Cannot locate LTB file',/app
      endif
     endif else widget_control,info.wmess,set_value='Cannot locate TTC file',/app
    endif

;-- write and submit IAP files

    if info.iap then begin
     dstart=tai2utc(info.ops1)
     dend=tai2utc(info.ops2)
     widget_control,/hour
     widget_control,info.wmess,set_value='Writing IAP files...',/app
     tstart=dstart.mjd
     tend=(dend.mjd-1) > tstart
     for i=tstart,tend do begin
      tiap=dstart & tiap.time=0 & tiap.mjd=i
      err=''
      status1=write_iap(tiap,file=file,observer=getenv('USER'),err=err,/noconcat)
      if not status1 then smess=err else smess= 'Written IAP file:   '+file
      widget_control,info.wmess,set_value=smess,/app
      if status1 then begin
       err=''
       status2=submit_iap(file,err=err)
       if not status2 then smess=err else smess='Submitted IAP file: '+file
      endif
      widget_control,info.wmess,set_value=smess,/app
     endfor
    endif
    widget_control,info.wmess,set_value='CPT completed',/app
    xtext,'CPT completed',wait=2,/just_reg
   endif
  endif
 endif

 if bname eq 'HELP' then $
  widg_help,'xcpt.hlp',group=event.top,/modal,$
              font='9x15bold',tfont='9x15bold',xtextsize=80

 return & end

;-----------------------------------------------------------------------------
;-- check SOHO roll state

 pro xcpt_set_roll

 common xcpt_com
 roll=get_soho_roll(info.ops1)
 mklog,'SOHO_ORIENT',roll
 widget_control,info.worient,set_value='CURRENT SOHO ORIENTATION: '+trim(string(roll,'(f7.1)'))+' (DEGS)'
 return & end

;--------------------------------------------------------------------------------

pro xcpt,tstart,tend,status=status,group=group,err=err,modal=modal,last=last

common xcpt_com

;-- defaults                  

select_windows
if not have_widgets() then begin
 message,'widgets unavailable',/cont
 return
endif

;caller=get_caller(stat) 
;if stat and (not xalive(group)) then xkill,/all
;modal=keyword_set(modal)
;if (not modal) and (xregistered('xcpt') ne 0) then return

if (xregistered('xcpt') ne 0) then return

status=0

;-- check for output directory access

ttc=getenv('CDS_CP_TTCFILES_W')
ltb=getenv('CDS_CP_LTBFILES_W')
if (ttc eq '') or (ltb eq '') then begin
 err='Warning - undefined ENV: CDS_CP_TTCFILES_W & CDS_CP_LTBFILES_W'
 xack,err
; return
endif

if (not test_open(ttc,/write)) or (not test_open(ltb,/write)) then begin
 err='Warning - no write access to: CDS_CP_TTCFILES_W & CDS_CP_LTBFILES_W'
 xack,err
; return
endif

;-- check input times

cds_plan_brief,/init
tgap=1.d
secs_per_day=24l*3600l
last=keyword_set(last)
get_utc,ops1 & ops1.time=0
ops2=ops1
ops2.mjd=ops1.mjd+1
ops1=utc2tai(ops1)
ops2=utc2tai(ops2)-tgap
dtime=[ops1,ops2]
ctime=[0.d,0.d]
if datatype(info) eq 'STC' then begin
 if tag_exist(info,'ops1') then ctime(0)=info.ops1
 if tag_exist(info,'ops2') then ctime(1)=info.ops2
endif

;-- create widgets

mk_dfont,lfont=lfont,bfont=bfont

wbase=widget_base(title='XCPT',/column,group=group)

row1=widget_base(wbase,/row,/frame)

quit=widget_button(row1,value='DONE',uvalue='QUIT',font=bfont,/no_rel)
reset=widget_button(row1,value='RESET',uvalue='RESET',font=bfont,/no_rel)
view=widget_button(row1,value='VIEW CPT RUN LOG',uvalue='VIEW',font=bfont,/no_rel)
preview=widget_button(row1,value='PREVIEW PLANNED STUDIES',uvalue='PREVIEW',font=bfont,/no_rel)
ok=widget_button(row1,value='GO RUN CPT',uvalue='RUN',font=bfont,/no_rel)
help=widget_button(row1,value='HELP',uvalue='HELP',font=bfont,/no_rel)


row2=widget_base(wbase,/column,/frame)

wops1=cw_field(row2, Title= 'START TIME:   ',fieldfont=bfont,$
                     /ret, xsize = 24, font = bfont,uvalue='OPS1')

wops2=cw_field(row2,  Title='STOP TIME:    ',fieldfont=bfont,$
                     /ret, xsize = 24, font = bfont,uvalue='OPS2')

row3=widget_base(wbase,/column,/frame)


temp=widget_base(row3,/row)
worient=widget_label(temp,value='',font=bfont)


values=['Set time of CDS science plan period from now to end of today']
values=['Delete ALL existing onboard tables before loading new ones',$
        'Append emergency study',$
        'Use mirror and slit (GIS only) to avoid use of OPS (see rules)',$
        'Automatically write and submit new IAP files',$
        'Automatically print table load files when done']

svalues=['NOW','NEW','EMERGENCY','ADJUST']
svalues=['NEW','EMERGENCY','ADJUST','IAP','TLB']
nvals=n_elements(values)
sbuttons=lonarr(nvals)
for i=0,nvals-1 do begin
 temp=widget_base(row3,/nonexclusive,/column)
 sbuttons(i)=widget_button(temp,value=values(i),uvalue=svalues(i),font=bfont)
 if i eq 0 then lab=widget_label(row3,value='--> Please check with CDS operator before initializing tables <--')
endfor

wlab=widget_label(wbase,value='MESSAGES',font=lfont)
wmess=widget_text(wbase,ysize=5,font=lfont)

;-- get CPT log file

home=getenv('HOME')
cpt_log_file=concat_dir(home,'.xcpt_log.genx')

;-- create info structure

wids={sbuttons:sbuttons,wops1:wops1,wops2:wops2,wmess:wmess,worient:worient}

def_info={sbuttons:sbuttons,wops1:wops1,wops2:wops2,wmess:wmess,svalues:svalues,$
          def_ops1:dtime(0),def_ops2:dtime(1),ops1:ops1,ops2:ops2,status:0,$
          now:0,new:0,emergency:1,adjust:0,logfile:cpt_log_file,$
          iap:1,tlb:1,previewed:0,worient:worient}

;-- try to recover last setup

if datatype(info) eq 'STC' then begin
 if not match_struct(info,def_info,/tags) then info=def_info
endif else info=def_info

copy_struct,wids,info
times=pick_times(tstart,tend,ctime=ctime,dtime=dtime,last=last)
info.ops1=times(0) & info.ops2=times(1)
info.new=0 & info.status=0 & info.previewed=0
 
;-- check if NOW is being used

if info.now then begin
 get_utc,temp 
 info.ops1=utc2tai(temp)
 temp.time=0 
 temp.mjd=temp.mjd+1
 info.ops2=utc2tai(temp)
endif

;-- update SOHO_ORIENT based on date

xcpt_set_roll
widget_control,wops1,set_value=tai2utc(info.ops1,/ecs,/vms)
widget_control,wops2,set_value=tai2utc(info.ops2,/ecs,/vms)

for i=0,nvals-1 do begin
 s=execute('set = info.'+svalues(i)+' ne 0')
 widget_control,sbuttons(i),set_button=set
endfor

;-- realize and center main base

xrealize,wbase,group=group,/center 

xmanager,'xcpt',wbase,modal=modal

if not xalive(wbase) then status=info.status

return & end



