pro xdate_set2wid, topwid
; 
;   Name: xdate_set2wid 
; 
;   Purpose: initialize to time in WID (from other application), if present
;
;   Input Parameters:
;       topwid - widget ID of xdate base widget 
;
;   Method: 
;       if an application supplies a text WID to xdate, then this routines
;       reads the current value and updates the xdate status (sliders,etc)
;
top=get_wuvalue(topwid)		; has .time, .day , wid and date_range fields
if top.labelstr ne '' then widget_control, set_value=top.labelstr, top.label
if top.wid ne 0 then begin
   val=(get_wvalue(top.wid))(0)
   if val ne '' then begin
      newtim=anytim2ints(val)               
      if newtim.time ne top.time or newtim.day ne top.day then begin
         top.day=newtim.day  > top.date_range(0) <  top.date_range(1)
         top.time=newtim.time
         widget_control,top.text,set_value=val		; display new date
         widget_control,top.datefines,set_value=0	; reset fine tuning 
         widget_control,top.dates, set_value=top.day	; move date slider
         widget_control,top.times, set_value=top.time/60000./30.
         widget_control,set_uvalue=top, topwid
      endif
   endif
endif

return
end

pro timebut_events,event

top=get_wuvalue(event.top)
val=(get_wvalue(event.id))(0)

times=strsplit(val,':')

if times(0) ne '' then top.time=fix(times(0)) * 3600000.  else begin
   cur=get_wvalue(top.text)
   vals=strtrim(str2arr(val,' '),2)
   exestr='new=timegrid(cur,' + vals(1) + '=' + vals(0) + ')'
   exestatus=execute(exestr)
   top.time = new.time > 0 <  86400000l
endelse

out=fmt_tim(top)                                ; string format
widget_control,set_value=out,top.text
if top.wid ne 0 then widget_control,set_value=out,top.wid

widget_control, set_value=round(top.time/60000./60*2),top.times

return
end
pro xdate_event,event
;
;   xdate_event - main event routine for xdate widget
;

xdate_set2wid,event.top

top=get_wuvalue(event.top)
val=strtrim(strupcase(get_wvalue(event.id)),2)
cur=get_wvalue(top.text)	; read current time

factor=fix(strmid(val,0,1) + '1')
types=['DAY','MONTH','YEAR']
mag=  [1,30,365]		    ; only approximate, I know, esp. month

which=where(strpos(types,strmid(val,1,20)) ne -1, ss)
if ss gt 0 then offset = mag(which(0))*factor else offset = 0

top.day=top.day + offset > top.date_range(0) <  top.date_range(1)

out=fmt_tim(top)
widget_control,top.text,set_value=out			; display new date
widget_control,top.datefines,set_value=0		; reset fine tuning 
widget_control,top.dates, set_value=top.day		; move date slider

if top.wid ne 0 then widget_control,set_value=out,top.wid  ; auxillary output

widget_control,set_uvalue=top,event.top			; save changes

return
end

pro slider_event, event

; -------------- process slider events ----------------

uval=get_wuvalue(event.id)
top=get_wuvalue(event.top)
stype=uval.type

case stype of
   "DATE" : begin
       top.day=event.value
       widget_control,top.datefines,set_value=0         ; reset fine tuning
       widget_control,set_uvalue=top.day,top.text     ; update fine ref time
    endcase
   "DATE FINE": begin
      widget_control,get_uvalue=day,top.text          ; get fine ref time
      if n_elements(day) eq 0 then begin
         day=top.day > top.date_range(0) < top.date_range(1)
         widget_control,set_uvalue=day, top.text
      endif
      top.day=  day + event.value                       ; and add tuner value
    endcase
   "TIME" : top.time=event.value*60000.*30.             ; 30 min granularity
    else: message,/info,'???'
endcase

out=fmt_tim(top)                                ; string format
widget_control,set_value=out,top.text

if top.wid ne 0 then widget_control,set_value=out,top.wid

widget_control,set_uvalue=top,event.top ; update uvalue
return
end


function xdate, base, group_leader=group_leader, wid=wid, register=register, $
	starttime=starttime, stoptime=stoptime
;+ 
;   Name: xdate
;
;   Purpose: Time input widget for Yohkoh - uses sliders for date and time
;
;   Input Parameters:
;      
;   Output Parameters:
;      function returns widget ID of xdate widget
;
;   Note: widget 'uvalue' of xdate WID is a structure including
;         .time and .day fields which are updated by the event handler.
;
;   Keyword Parameters:
;      wid - optional widget_text WID from calling application - if present,
;            the current xdate value is written to this text area
;            (it follows that the calling application can read this via
;             widget_control, get_value=last_xdate, WID)
;  
;      group_leader - leader/parent application (for auto-kill)
;      register - if set, register this application (default lets parent do it)
;
;   Calling Sequence:
;      time_wid=xdate( [wid=wid] )
;
;   History:
;      24-mar-1995 (SLF) 
;      26-mar-1995 (SLF) various - startup from text in WID, if supplied
;                                  dont hard code start/stop times
;      
;   Restrictions:
;      generally called by another widget application
;
;   TODO: user supplied start and stop times.
;-
; 
if not keyword_set(base) then $
   b0=widget_base(/column,title='TIME WIDGET',/frame) else b0=base

bl=widget_label(b0,value='Select Time',/frame)

bb0=widget_base(b0,/row)
xmenu,['-DAY','-MONTH','-YEAR'],bb0,/row, buttons=main1
bb0l=widget_label(bb0,value='<< Delta-Date>>',/frame)
xmenu,['+DAY','+MONTH','+YEAR'],bb0,/row, buttons=main2
mainbuts=[main1,main2]

bt=widget_text(b0,value=string(replicate(32b,120)),ysize=1, $
   font=get_xfont(/fixed,closest=20,/only_one))

b1=widget_base(b0,/column,event_pro='slider_event')

if not keyword_set(starttime) then starttime=get_yo_dates(/launch)
if not keyword_set(stoptime)  then stoptime =ut_time()
startday=gt_day(starttime)
stopday=gt_day(stoptime)

help,startday,stopday
b1s=widget_slider(b1,title='Date',min=startday, max=stopday,/suppress,/drag)
b11s=widget_slider(b1,min=-15,title='Date (Fine Tune)', max=15,value=0, $
   /drag, /suppress)

; time to nearest 30 minutes
b2=widget_base(b0,/column,event_pro='slider_event')
b2s=widget_slider(b2,title='Time',min=0,max=1440./30,/suppress,/drag)

b3=widget_base(b0,/column,event_pro='timebut_events')
hour4=strmid(timegrid('00:00 1-jan','23:30 1-jan',/string,hour=4),11,5)
xmenu,['-30 MIN',hour4,'+30 MIN'],b3,/row,buttons=timebuts

if n_elements(wid) eq 0 then wid=0
topstr={top:b0,			$
        label:bl,		$
        text:bt,		$
        mainbuts:mainbuts,	$
        base1:b1,		$
        dates:b1s,		$
        datefines:b11s,		$
        base2:b2,		$
        times:b2s,		$
        timebuts:timebuts,	$
	day:0,			$ 			; days since 79
        time:0l,		$       		; msod
        date_range:[startday,stopday],	$       ; min/max for dates 
        labelstr:'',		$			; change lable
	wid:wid			$			; text wid for output   
	}

uvals={topid:bl, type:'', value:0l}	 	; for passing info 

; event types
uvals.type='DATE'
widget_control,set_uval=uvals,topstr.dates
uvals.type='DATE FINE'
widget_control,set_uval=uvals,topstr.datefines
uvals.type='TIME'
widget_control,set_uval=uvals,topstr.times

widget_control, set_uvalue=topstr, b0

widget_control,b0,/realize
widget_control, set_uvalue=topstr, bl
widget_control, set_uvalue=topstr,b0
if keyword_set(register) then xmanager,'xdate',b0

return,b0

end   
