;+
; NAME:
;     WPOINT
; PURPOSE:
;     Supervises analysis and solution of interferometric POINT data.
; CATEGORY:
;     OVRO APC CALIBRATION ANALYSIS
; CALLING SEQUENCE:
;     wpoint,filename
; INPUTS:
;     filename   The name of the .ARC file containing the POINT
;                  measurements.
; OPTIONAL (KEYWORD) INPUT PARAMETERS:
; ROUTINES CALLED:
;     pntchek, mountcal
; OUTPUTS:
; COMMENTS:
; SIDE EFFECTS:
; RESTRICTIONS:
; MODIFICATION HISTORY:
;     Written 29-Dec-1999 by Dale E. Gary
;-

pro wpoint_event, event

   ; Read the state structure from the child base
   base = event.handler
   stash = widget_info(base,/child)
   widget_control,stash,get_uvalue=state,/no_copy

   WIDGET_CONTROL,Event.Id,GET_UVALUE=Ev

   CASE Ev OF

   'TAB_SEL': BEGIN
         if (Event.Type eq 4) then begin
            state.select = [Event.sel_left,Event.sel_top,$
                            Event.sel_right,Event.sel_bottom<(state.npnt-1)]
            IF (state.select(0) EQ 0 AND state.select(2) EQ 0) THEN BEGIN
               ; Select column was selected.

               ; Read the table from the widget
               widget_control,state.TableID,get_value=scan
               for i = state.select[1], state.select[3] do begin
                  ; Toggle the setting of each line
                  if (scan[i].sel eq '*') then scan[i].sel = ' ' $
                                          else scan[i].sel = '*'
               endfor
               ; Check how many are selected, and if none desensitize the
               ; Analyze button.
               sel = where(scan.sel eq '*',nsel)
               if (nsel eq 0) then begin
                  state.selflag = 0
                  WIDGET_CONTROL,state.AnalID,SENSITIVE=0
               endif else begin
                  state.selflag = 1
                  WIDGET_CONTROL,state.AnalID,SENSITIVE=1
               endelse

               ; Write the table back to the widget
               widget_control,state.TableID,set_value=scan
            ENDIF
            IF (state.select(0) EQ 6 AND state.select(2) EQ 6) THEN BEGIN
               ; Analyze column was selected.

               ; Read the table from the widget
               widget_control,state.TableID,get_value=scan
               for i = state.select[1], state.select[3] do begin
                  ; Analyze flag can only be unset, not set.  Unset them all
                  scan[i].anal = ' '
               endfor
               ; See how many remain set, and if none, desensitize the SOLVE button
               anal = where(scan.anal eq '*',nanal)
               if (nanal eq 0) then WIDGET_CONTROL,state.SolveID,SENSITIVE=0

               ; Write the table back to the widget
               widget_control,state.TableID,set_value=scan
            ENDIF
         endif
      END
   'ANALYZE': BEGIN
         widget_control,/hourglass

         ; Freeze editing
         WIDGET_CONTROL,state.TableID,ALL_TABLE_EVENTS=0,EDITABLE=0
         WIDGET_CONTROL,state.AllID,SENSITIVE=0

         WIDGET_CONTROL,state.TableID,GET_VALUE=scan
         ; Loop through and analyze all selected scans
         for i = 0, state.npnt-1 do begin
            ; Check if this scan was selected, and not already analyzed
            if (scan[i].sel eq '*' and scan[i].anal ne '*') then begin
               widget_control,state.TableID,set_table_view=[0,(i-14)>0]
               pntchek,state.filename,scan[i].srec,output
               scan[i].anal = '*'
               state.output[*,i] = output
               ; Write the table back to the widget
               widget_control,state.TableID,set_value=scan
            endif
         endfor

         ; Unfreeze editing
         WIDGET_CONTROL,state.TableID,ALL_TABLE_EVENTS=1,EDITABLE=1
         WIDGET_CONTROL,state.AllID,SENSITIVE=1
         WIDGET_CONTROL,state.SolveID,SENSITIVE=1
      END
   'SELALL': BEGIN
         ; Toggle state of flag
         state.selflag = 1 - state.selflag

         ; Read the table from the widget
         widget_control,state.TableID,get_value=scan

         if (state.selflag) then begin
            ; Change button text to Clear All, and select all scans
            WIDGET_CONTROL,state.AllID,SET_VALUE='Clear All'
            scan.sel = '*'
            WIDGET_CONTROL,state.AnalID,SENSITIVE=1
         endif else begin
            ; Change button text to Select All, and clear all scans
            WIDGET_CONTROL,state.AllID,SET_VALUE='Select All'
            scan.sel = ' '
            WIDGET_CONTROL,state.AnalID,SENSITIVE=0
         endelse
         ; Write the table back to the widget
         widget_control,state.TableID,set_value=scan
      END
   'SOLVE': BEGIN
         mountcal
      END
   ELSE:
   ENDCASE

WRITE_STATE:
   WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY

return
end


pro wpoint, filename, group = Group

   IF N_ELEMENTS(Group) EQ 0 THEN GROUP=0

   ; If no filename was specified, ask the user for a file.  If the user cancels,
   ; exit.
   if (n_elements(filename) eq 0) then begin
ask:
      filename = dialog_pickfile(path=!defaults.datadir,filter='*.arc',$
                    title='Select file containing POINT measurements')
      if (filename eq '') then return
   endif

   lun = openarc(filename,a,nrec)
   if (lun eq 0) then goto,ask

   ; Check for existence of an INDEX record
   indexrec = (find_index(a,nrec))[0]

   ; INDEXREC is now -1 if there is no INDEX segment, or contains the record
   ; number of the first record of the INDEX segment if one exists.
   if (indexrec eq -1) then idx = get_index_struct() else begin
      ; Decode the INDEX segment, returning an INDEX structure
      data = getdata(indexrec-1,a)
      for i = 0, 9 do begin
         data = [data,(getdata(indexrec+i,a))]
      endfor
      idx = decode(data,!SEGM.INDEX)
   endelse

   ; Create a flag to indicate presence of valid index structure
   if (idx.nscans eq 0) then noidx = 1 else noidx = 0

   if (noidx) then begin

      ; There is not INDEX, so we have to find the information the hard way...

      ; Read the POINT headers from the file
      seglist = get_segments(a,nrec)
      nadded = findsegentries(seglist,ihed,iseg)
;      seglist = seglist[ihed]
      ipnt = where(strpos(seglist,'Header: POINT') ne -1,npnt)
      if (npnt ne 0) then seglist = seglist[ipnt]
      if (npnt eq 0) then begin
         ans = dialog_message('WPOINT: File contains no POINT scans.',/error)
         free_lun,lun
         goto,ask
      endif
   endif else begin
      ipnt = where((*idx.pscan).scancode eq !scan.point,npnt)
   endelse

   ; Fill in scanlist structure
   scan = replicate({sel:' ',srcname:'',date:'', time:'',srec:0,erec:0,anal:' '},npnt)
   if (noidx) then begin
      ; No INDEX, so go through the file one scan at a time

      ; Loop over all scans
      for i = 0, npnt-1 do begin
         scan[i].srec = fix(strmid(seglist[i],14,5))
         scan[i].erec = fix(strmid(seglist[i],20,5))

         ; Read the header
         hrec = scan[i].srec
         data = getdata(hrec-1,a)   ; Read the header
         header = decode(data,!SEGM.HEADER)
         scan[i].date = header.tls.date
         scan[i].time = strmid(header.tls.timstr,1,8)

         ; Find the trajectory segment record that corresponds to this scan
         rec = findseg(a,hrec,nrec,!SEGM.TRAJ,idx=idx)
         ; Decode the trajectory segment, if any
         data = getdata(rec-1,a)
         traj = decode(data,!SEGM.TRAJ)
         scan[i].srcname = traj.srcname
      endfor
   endif else begin
      ; There is an INDEX, so get the info from the INDEX structure
      scan.srec = (*idx.pscan)[ipnt].srec
      scan.erec = (*idx.pscan)[ipnt].erec
      scan.srcname = (*idx.pscan)[ipnt].srcname
      for i = 0, npnt-1 do begin
         datarr = cvdoy((*idx.pscan)[ipnt[i]].syear,(*idx.pscan)[ipnt[i]].sday)
         scan[i].date = string(datarr,format='(I4,"/",I2.2,"/",I2.2)')
         scan[i].time = strmid(msec2str((*idx.pscan)[ipnt[i]].smsec),1,8)
      endfor
   endelse

   free_lun,lun

   ; Create a simple base widget and child base widget.  The
   ; child base carries the timer messages
   base = widget_base(TITLE='WPoint',GROUP_LEADER=Group)
   base2 = widget_base(base,/ROW)
   lbase = widget_base(base2,/column)
   rbase = widget_base(base2,/column)
   tbase = widget_base(lbase,/row)

   font = 'Lucida Console*14'

   fmt = strarr(7,npnt)
   for i = 0, npnt-1 do begin
      fmt(*,i) = ['(a)','(a)','(a)','(a)','(I5)','(I5)','(a)']
   endfor

   TableId = WIDGET_TABLE(LBASE,VALUE=scan,COLUMN_WIDTHS=[10,70,70,50,35,35,30],X_SCROLL_SIZE=7,$
       COLUMN_LABELS=['*','SRCNAME','Date','Time','SRec','ERec','Anlz'],Y_SCROLL_SIZE=15<npnt,$
       ALIGNMENT=[1,0,1,1,2,2,1]#replicate(1,npnt),FORMAT=fmt,UVALUE='TAB_SEL',/ALL_EVENTS)

   advbase = WIDGET_BASE(LBASE,/ROW,/MAP)
   AllId   = WIDGET_BUTTON(ADVBASE,VALUE='Select All',UVALUE='SELALL')
   AnalId  = WIDGET_BUTTON(ADVBASE,VALUE='Analyze',UVALUE='ANALYZE',SENSITIVE=0)
   SolveId = WIDGET_BUTTON(ADVBASE,VALUE='Solve',UVALUE='SOLVE',SENSITIVE=0)

   ; Realize the heirarchy, even though there is nothing to see
   widget_control,base,/realize

   ; Save some information in a state structure to read in the
   ; event handler
   maxlines = 100
   status = intarr(maxlines)
   AR = {AR,Name:'',HAO:0,DECO:0,Open:0}
   Cal = {Calstr,Name:'',Open:0}
   state = {base:base,base2:base2,AllId:AllId,AnalId:AnalId,SolveId:SolveId,$
             TableID:TableID,curline:0,npnt:npnt,RBase:RBase,selflag:0,$
             filename:filename,select:[-1,-1,-1,-1],output:strarr(4,npnt)}

   widget_control,widget_info(base,/child),set_uvalue=state, /no_copy

   ; Call XMANAGER to handle the event messages
   xmanager,'wpoint',base, /NO_BLOCK

   return
end
