;+
;NAME:
;  thm_ui_pwrspc_options
;
;PURPOSE:
;  A widget used to set keyword options for creating power spectra.  This
;  widget returns an anonymous structure of keyword settings that is passed
;  through the OPTIONS positional parameter of THM_UI_NEW_PWRSPC.  Intended to
;  be called from THM_UI_NEW_DPROC.
;
;CALLING SEQUENCE:
;  opt_struct = thm_ui_pwrspc_options(gui_id, trObj, historyWin, statusBar)
;
;INPUT:
;  gui_id: The GUI id that should be the top level id of the Data Processing
;          window.
;  trObj: The timerange object that is created in THM_GUI_NEW.
;  historyWin: The history window object.
;  statusBar: The status bar object for the Data Processing window.
;  
;KEYWORDS:
;  none
;
;OUTPUT:
;  opt_struct: The anonymous structure contain options and keyword settings for
;              THM_UI_NEW_PWRSPC.
;-


function thm_ui_pwrspc_options_check_input, state

  Compile_Opt idl2, hidden
  
  fail = 0
  
  if finite(state.bins) then begin
    if state.bins lt 1 then begin
      fail = 1
      state.statusBar->update, 'Bins input must be greater than 0.  Reset to default'
      state.bins=3D
      widget_control, state.binsSpin, set_value=state.bins
    endif
  endif else begin
    fail = 1
    state.statusBar->update, 'Bins input invalid.  Reset to default'
    state.bins=3D
    widget_control, state.binsSpin, set_value=state.bins
  endelse
  
  return, fail
end

pro thm_ui_pwrspc_options_event, event

  Compile_Opt idl2, hidden

  Widget_Control, event.TOP, Get_UValue=state, /No_Copy

  ;Put a catch here to insure that the state remains defined

  err_xxx = 0
  Catch, err_xxx
  IF (err_xxx NE 0) THEN BEGIN
    Catch, /Cancel
    Help, /Last_Message, Output = err_msg
    if is_struct(state) then begin
      FOR j = 0, N_Elements(err_msg)-1 DO state.historyWin->update,err_msg[j]
      x=state.gui_id
      histobj=state.historyWin
    endif
    Print, 'Error--See history'
    ok=error_message('An unknown error occured and the window must be restarted. See console for details.',$
       /noname, /center, title='Error in Power Spectra Options')
    Widget_Control, event.TOP, Set_UValue=state, /No_Copy
    widget_control, event.top,/destroy
    if widget_valid(x) && obj_valid(histobj) then begin 
      thm_gui_error,x,histobj
    endif
    RETURN
  ENDIF

  ;kill request block
  IF (Tag_Names(event, /Structure_Name) EQ 'WIDGET_KILL_REQUEST') THEN BEGIN  

    ;Print, 'Power Spectra Options widget killed' 
    state.historyWin->Update,'THM_UI_PWRSPC_OPTIONS: Widget killed' 
    Widget_Control, event.TOP, Set_UValue=state, /No_Copy
    Widget_Control, event.top, /Destroy
    RETURN 
  ENDIF
  
  Widget_Control, event.id, Get_UValue=uval
  
  state.historyWin->update,'THM_UI_PWRSPC_OPTIONS: User value: '+uval  ,/dontshow
  
  CASE uval OF
    'APPLY': BEGIN
      fail = thm_ui_pwrspc_options_check_input(state)
      if ~fail then begin
        
        if state.settime then begin
          state.tbegin = state.tr_obj->getstarttime()
          state.tend = state.tr_obj->getendtime()
        endif else begin
          state.tbegin = 0
          state.tend = 0
        endelse
        
        if state.tbegin eq state.tend then state.trange=[0,0] $
          else state.trange=[state.tbegin, state.tend]
          
        state.success=1
        
        *state.opt_struct_ptr = {dynamic:state.dynamic, suffix:state.suffix, $
                                 nboxpoints:state.nboxpoints, $
                                 nshiftpoints:state.nshiftpoints, $
                                 trange:state.trange, tbegin:state.tbegin, $
                                 tend:state.tend, bins:long(state.bins), $
                                 noline:state.noline, nohanning:state.nohanning, $
                                 notperhz:state.notperhz, success:state.success}
        
        Widget_Control, event.TOP, Set_UValue=state, /No_Copy
        Widget_Control, event.top, /Destroy
        return
      end
    END
    'BINS': BEGIN
      if finite(event.value) then begin
        state.bins = event.value
        mess = 'Bins set to ' + strcompress(string(long(state.bins)))
        state.statusBar->update, mess
        state.historyWin->update, 'THM_UI_PWRSPC_OPTIONS: ' + mess
      endif else begin
        state.bins = event.value
        state.statusBar->update, ''
      endelse
    END
    'BOXSIZE': BEGIN
      state.nboxpoints = long(state.hanning_size[event.index])
      
      mess = 'Window Size set to' + strcompress(string(state.nboxpoints))+ ' points.'
      state.statusBar->update, mess
      state.historyWin->update, 'THM_UI_PWRSPC_OPTIONS: ' + mess
    END
    'CANC': BEGIN
      state.historyWin->update,'Power Spectra Options Cancelled',/dontshow
      state.success=0
      *state.opt_struct_ptr = {success:state.success}
      Widget_Control, event.TOP, Set_UValue=state, /No_Copy
      Widget_Control, event.top, /Destroy
      return
    END
    'DYNAMIC':BEGIN
      state.dynamic = event.select
      widget_control, state.nboxptsList, sensitive=state.dynamic
      widget_control, state.nshiftptsList, sensitive=state.dynamic
      widget_control, state.settimeBase, sensitive=state.dynamic
      if state.dynamic then begin
        mess = 'Dynamic power spectra selected.'
      endif else begin
        mess = 'Dynamic power spectra de-selected.'
      endelse
      
      state.statusBar->update, mess
      state.historyWin->update, 'THM_UI_PWRSPC_OPTIONS: ' + mess
    END
    'HELP': BEGIN
 
      gethelppath,path
      xdisplayfile, path+'thm_ui_new_pwrspc.txt', group=state.gui_id, /modal, done_button='Done', $
                    title='HELP: Power Spectra Options'
    END
    'NOHANN': BEGIN
      state.nohanning = event.select

      if event.select then begin
        mess = 'Hanning window turned off.'
      endif else begin
        mess = 'Hanning window turned on.'
      endelse

      state.statusBar->update, mess
      state.historyWin->update, 'THM_UI_PWRSPC_OPTIONS: ' + mess
    END
    'NOLINE': BEGIN
      state.noline = event.select

      if event.select then begin
        mess = 'No Line turned on.'
      endif else begin
        mess = 'No Line turned off.'
      endelse

      state.statusBar->update, mess
      state.historyWin->update, 'THM_UI_PWRSPC_OPTIONS: ' + mess
    END
    'NOTPERHZ': BEGIN
      state.notperhz = event.select

      if event.select then begin
        mess = 'Not Per Hz turned on.'
      endif else begin
        mess = 'Not Per Hz turned off.'
      endelse

      state.statusBar->update, mess
      state.historyWin->update, 'THM_UI_PWRSPC_OPTIONS: ' + mess
    END
    'SETTIME': BEGIN
      state.settime = event.select
      widget_control, state.timeBase, sensitive=state.settime

      if event.select then begin
        mess = 'Set Time Range turned on.'
      endif else begin
        mess = 'Set Time Range turned off.'
      endelse

      state.statusBar->update, mess
      state.historyWin->update, 'THM_UI_PWRSPC_OPTIONS: ' + mess
    END
    'SHIFT_PTS': BEGIN
      state.nshiftpoints = long(state.hanning_size[event.index])

      mess = 'Window Shift set to' + strcompress(string(state.nshiftpoints))+ ' points.'
      state.statusBar->update, mess
      state.historyWin->update, 'THM_UI_PWRSPC_OPTIONS: ' + mess
    END
    'TIME': BEGIN
      ;nothing to implement at the moment
    END
;    'STARTCAL': BEGIN
;      widget_control, state.trcontrols[0], get_value= val
;      start=thm_ui_timefix(val)
;      state.tr_obj->getproperty, starttime = start_time       
;      if ~is_string(start) then start_time->set_property, tstring=start
;      thm_ui_calendar, 'Choose date/time: ', start_time, state.gui_id
;      start_time->getproperty, tstring=start
;      widget_control, state.trcontrols[0], set_value=start
;
;      mess = 'Start Time set to ' + start
;      state.statusBar->update, mess
;      state.historyWin->update, 'THM_UI_PWRSPC_OPTIONS: ' + mess
;    END
;    'STOPCAL': BEGIN
;      widget_control, state.trcontrols[1], get_value= val
;      endt=thm_ui_timefix(val)
;      state.tr_obj->getproperty, endtime = end_time       
;      if ~is_string(endt) then end_time->set_property, tstring=endt
;      thm_ui_calendar, 'Choose date/time: ', end_time, state.gui_id
;      end_time->getproperty, tstring=endt
;      widget_control, state.trcontrols[1], set_value=endt
;
;      mess = 'End Time set to ' + endt
;      state.statusBar->update, mess
;      state.historyWin->update, 'THM_UI_PWRSPC_OPTIONS: ' + mess
;    END
    'SUFFIX': BEGIN
      widget_control, event.id, get_value=temp_string
      state.suffix = strcompress(/remove_all, temp_string)
    END
;    'TSTART': BEGIN ; Start Time entry box
;      widget_control,event.id,get_value=value
;      t0 = thm_ui_timefix(value)
;      If(is_string(t0)) Then Begin
;        ;get both times for limit checking
;        state.tr_obj->GetProperty, startTime=st ;st is starttime object (thm_ui_time__define)
;        state.tr_obj->GetProperty, endTime=et   ;et is endtime object
;        ;set start time value
;        st->SetProperty, tstring = value
;        ;return a warning if the time range is less than zero, or longer than 1 week
;        et->getproperty, tdouble=t1
;        st->getproperty, tdouble=t0
;
;        mess = 'Start Time set to ' + value
;        state.statusBar->update, mess
;        state.historyWin->update, 'THM_UI_PWRSPC_OPTIONS: ' + mess
;      Endif
;    END
;    'TEND': BEGIN ; End Time entry box
;      widget_control,event.id,get_value=value
;      t0 = thm_ui_timefix(value)
;      If(is_string(t0)) Then Begin
;        state.tr_obj->GetProperty, startTime=st ;st is starttime object (thm_ui_time__define)
;        state.tr_obj->GetProperty, endTime=et ;et is endtime object (thm_ui_time__define)
;        ;Set end time value
;        et->SetProperty, tstring = value
;        ;return a warning if the time range is less than zero, or longer than 1 week
;        et->getproperty, tdouble=t1
;        st->getproperty, tdouble=t0
;
;        mess = 'End Time set to ' + value
;        state.statusBar->update, mess
;        state.historyWin->update, 'THM_UI_PWRSPC_OPTIONS: ' + mess
;      Endif
;    END
    ELSE: print, 'Not yet implemented"
  ENDCASE    

  Widget_Control, event.top, Set_UValue=state, /No_Copy

  RETURN
end

function thm_ui_pwrspc_options, gui_id, trObj, historyWin, statusBar

  compile_opt idl2
  

  tlb = widget_base(/col, title='Power Spectra Options', group_leader=gui_id, $
                    /modal, /floating, /base_align_center, /tlb_kill_request_events)

; Base skeleton          
  mainBase = widget_base(tlb, /col, /align_center, tab_mode=1)
    dynamicBase = widget_base(mainBase, /row, /nonexclusive)
    suffixBase = widget_base(mainBase, /row)
    nboxptsBase = widget_base(mainBase, /row)
    nshiftptsBase = widget_base(mainBase, /row)
    settimeBase = widget_base(mainBase, /col)
      timeButtonBase = widget_base(settimeBase, /row, /nonexclusive)
      timeBase = widget_base(settimeBase, /col, /frame)
;        tstartBase = widget_base(timeBase, /row)
;        tendBase = widget_base(timeBase, /row)
    binsBase = widget_base(mainBase, /row)
    optionsBase = widget_base(mainBase, /row, /nonexclusive)
    buttonBase = widget_base(mainBase, /row, /align_center)

; Set defaults
  dynamic=1
  suffix='_dpwrspc'
  hanning_size=[' 32',' 64',' 128',' 256',' 512',' 1024',' 2048',' 4096', $
                ' 8192',' 16384']
  nboxpoints=256L
  nboxpointsList= where(nboxpoints eq long(hanning_size))
  nshiftpoints=128L
  nshiftpointsList = where(nshiftpoints eq long(hanning_size))
  settime=0
  tbegin=0
  tend=0
  trange=[0,0]
  bins=3D
  noline=0
  nohanning=0
  notperhz=0
  success=0
  
; Widgets
  dynamicButton = widget_button(dynamicBase, value='Dynamic', uval='DYNAMIC')
  widget_control, dynamicButton, set_button=dynamic
  
  suffixLabel = widget_label(suffixBase, value = 'Suffix: ')
  suffixId = widget_text(suffixBase, value = suffix, xsize = 22, ysize = 1, $
                         uvalue = 'SUFFIX', /editable, /all_events)
  
  nboxptsLabel = widget_label(nboxptsBase, value='Window Size: ')
  nboxptsList = widget_combobox(nboxptsBase, uval='BOXSIZE', value=hanning_size)
  widget_control, nboxptsList, set_combobox_select=nboxpointsList

  nshiftptsLabel = widget_label(nshiftptsBase, value='Window Shift: ')
  nshift = hanning_size
  nshiftptsList = widget_combobox(nshiftptsBase, uval='SHIFT_PTS', value=nshift)
  widget_control, nshiftptsList, set_combobox_select=nshiftpointsList

; Time range-related widgets
  timeButton = widget_button(timeButtonBase, value='Set Time Range: ', uval='SETTIME')
  widget_control, timeButton, set_button=settime, sensitive=dynamic
  widget_control, timeBase, sensitive=settime

  getresourcepath,rpath
  cal = read_bmp(rpath + 'cal.bmp', /rgb)
  thm_ui_match_background, tlb, cal  

; Start/Stop Time objects
  st_text = '2007-03-23/00:00:00.0'
  et_text = '2007-03-24/00:00:00.0'

  if obj_valid(trObj) && (obj_class(trObj) eq 'THM_UI_TIME_RANGE') then begin
  ; create new time range object
    tr_obj = obj_new('THM_UI_TIME_RANGE')
    ok = tr_obj->SetStartTime(trObj->getstarttime())
    ok = tr_obj->setendtime(trObj->getendtime())
  endif else begin
    tr_obj = Obj_New("THM_UI_TIME_RANGE", startTime=st_text, endTime=et_text)
    startt->setproperty,tstring=st_text
    stopt->setproperty,tstring=et_text
    ;timerange=tr_obj
  endelse
 

  trWidget = thm_ui_time_widget(timebase,statusBar,historyWin,timeRangeObj=tr_obj, $
                                uvalue='TIME',uname='time', oneday=0)

;  tstartLabel = Widget_Label(tstartBase,Value='Start Time: ')
;  geo_struct = widget_info(tstartlabel,/geometry)
;  labelXSize = geo_struct.scr_xsize
;  tstartText = Widget_Text(tstartBase, Value=st_text, /Editable, /Align_Left, /All_Events, $
;                           UValue='TSTART')
;  startcal = widget_button(tstartbase, val = cal, /bitmap, tab_mode=0, uval='STARTCAL', uname='startcal', $
;                           tooltip='Choose date/time from calendar.')
;  tendLabel = Widget_Label(tendBase,Value='End Time: ', xsize=labelXSize)
;  tendText = Widget_Text(tendBase,Value=et_text, /Editable, /Align_Left, /All_Events, $
;                         UValue='TEND')
;  stopcal = widget_button(tendbase, val = cal, /bitmap, tab_mode=0, uval='STOPCAL', uname='stopcal', $
;                          tooltip='Choose date/time from calendar.')
  trControls=[trwidget]
  
  nolineButton = widget_button(optionsBase, value='No Line', uval='NOLINE')
  nohannButton = widget_button(optionsBase, value='No Hanning', uval='NOHANN')
  notperhzButton = widget_button(optionsBase, value='Not Per Hz', uval='NOTPERHZ')

  binsSpin = thm_ui_spinner(binsBase, increment=1, value=bins, uval='BINS', text_box_size=4, $
                            /all_events, label='Bins: ')
  
; Main window buttons
  applyButton = Widget_Button(buttonBase, Value='Accept and Close', UVal='APPLY')
  cancelButton = widget_button(buttonBase, Value='Cancel', UVal='CANC')
  helpButton = widget_button(buttonBase, Value='Help', UVal='HELP') 
  
; Create structure to hold options
  opt_struct = {dynamic:dynamic, suffix:suffix, nboxpoints:nboxpoints, $
                nshiftpoints:nshiftpoints, trange:trange, tbegin:tbegin, $
                tend:tend, bins:bins, noline:noline, nohanning:nohanning, $
                notperhz:notperhz, success:success}
  opt_struct_ptr = ptr_new(opt_struct)

  state = {tlb:tlb, gui_id:gui_id, historyWin:historyWin, statusBar:statusBar, $
           hanning_size:hanning_size, dynamic:dynamic, suffix:suffix, $
           nboxpoints:nboxpoints, nshiftpoints:nshiftpoints, settime:settime, $
           trange:trange, tbegin:tbegin, tend:tend, tr_obj:tr_obj, $
           trControls:trControls, bins:bins, noline:noline, nohanning:nohanning, $
           notperhz:notperhz, success:success, opt_struct_ptr:opt_struct_ptr, $
           ;widget IDs
           settimeBase:settimeBase, timeBase:timeBase, nboxptsList:nboxptsList, $
           nshiftptsList:nshiftptsList, binsSpin:binsSpin}

  Centertlb, tlb         
  Widget_Control, tlb, Set_UValue=state, /No_Copy
  Widget_Control, tlb, /Realize
  XManager, 'thm_ui_pwrspc_options', tlb, /No_Block
  
  opt_struct = *opt_struct_ptr
  ptr_free, opt_struct_ptr

  RETURN, opt_struct
end