;************************** xspr_rd1fov ****************************
pro xspr_rd1fov, id, uvtop , gbase
;
; 
;   Name: xspr_rd1fov
;
;   Purpose: read index/data from sda for FOVn (ss vector is uvlue)
;
;
; COMMON BLOCKS:
;   xstepper.common
;
common xspr_blk1, grid, nogos

@xstepper.common

; widget_control,id,/hourglass ; cant use on old idl (flare1-7)!!!
which=where(id eq uvtop.views.button)
nwhich=where(id ne uvtop.views.button,nwcnt)

sprfiles=get_wuvalue(uvtop.views(which).draw)
orss=get_wuvalue(uvtop.views(which).label)
info=get_wuvalue(uvtop.views(which).base)
curwind=get_wvalue(uvtop.views(which).draw)
wset,curwind
message,/info,'Reading data...'

rd_roadmap,sprfiles,rmap
;sss=grid_data(rmap(orss),min=grid)
;sss=-1 

rd_sda,sprfiles,orss,orindex,ordata
ser_num=orindex.sxt.serial_num
user_num=uniq(ser_num)

if n_elements(user_num) ne n_elements(orindex) then begin
   message,/info,'Assembling ORs'
   ordata=ass_or(ordata,orindex,subs,/only_full)
   orindex=orindex(subs)
endif

sdata=size(ordata)

if mag_fact gt 1 then begin
   if data_chk(ordata,/ndimen) eq 3 then $
      ordata=rebin(temporary(ordata),sdata(1)*mag_fact,sdata(2)*mag_fact,sdata(3),/samp) $
      else ordata=rebin(temporary(ordata),sdata(1)*mag_fact,sdata(2)*mag_fact,/samp)
endif

scube=temporary(ordata)
sinfo=get_info(orindex,/non)

widget_control,uvtop.views(which).button, set_value='**CURRENT DATA**'
for i=0, nwcnt-1 do $
  widget_control,uvtop.views(nwhich(i)).button, set_value='Read/Select'

nimages=n_elements(sinfo)

; --------------- pixmap common -------------------------
pixmap=lonarr(2,nimages)-1              ;reset pixmap common
pixpnt=0
pixcnt=0
; ----------------------------------------------------------

; ---------------- ss common --------------------------------
ssmap=lonarr(nimages)-1			;reset ss common 
sspnt=0
sscnt=0
subs=indgen(nimages)
; -----------------------------------------------------------


if n_params() eq 3 then goes_draw, rmap(orss) , gbase
message,/info,'Read Complete'

return
end

;****************************************************************************

;****************************** xspr_newsfd *********************************

pro xspr_newsfd, sprfiles, ssu

break_file, sprfiles, splogs, sppaths, spfiles, spexts, spvers
sprfile=spfiles(0) + spexts(0) + spvers(0)

; display closest sfd or sfm file in primary window
; first, look for corresponding 'sfd' file
is_spr=strpos(sprfiles(0),'spr') ne -1
is_spd=strpos(sprfiles(0),'spd') ne -1
sfd=''
case 1 of
   is_spr: sfd=str_replace(sprfiles(0),'spr','sfd')
   is_spd: sfd=str_replace(sprfiles(0),'spd','sfd')
   else:
endcase

; if not found, try closest in same directory
if not file_exist(sfd) then begin
   sfds=file_list(sppaths(0),'sfd' + '??????.????')
   break_file,sfds,sflogs,sfpaths,sffiles,sfexts,sfvers
   spfid=strmid(sprfile,3,11)
   sfd=sffiles+sfexts+sfvers
   sffids=strmid(sfd,3,11)
   timchk=tim2dset(anytim2ints(fid2ex(sffids)),anytim2ints(fid2ex(spfid)), $
        delta=dt)
   if dt(0) gt 172800. then begin
      tbeep
      message,/info,'Large time difference between input and nearest SFD'
   endif
   sfd=sfds(timchk)             ; closest in time
endif

if not file_exist(sfd) then message,'no sfd file???'

; ------------- run lastsfd to display FFI --------------------
message,/info,'Running lastsfd...'
lastsfd,index,data,usefile=sfd,/color,mag=mag, rebin=512


rd_sda,sprfiles,ssu,pfi_index,/nodata
plot_nar,index,pfi_lstyle=2,color=220,pfi_color=255, $
       fill=0, charsize=charsize, pfi_index=pfi_index,mag=mag(0)
;------------------------------------------------------------------

return
end
;****************************************************************************

;******************************** xspr_newspr *******************************

function xspr_newspr , sprfiles, spr=spr, spd=spd, nimg=nimg, ssu=ssu, $
		last=last, xshape=xshape, yshape=yshape, mag=mag, rmap=rmap, ssx=ssx

@xstepper.common

spr = keyword_set(spr)
spd = 1-keyword_set(spr)

; create seperate base for multiple pfis
if n_elements(sprfiles) eq 0 then begin
   if keyword_set(last) then sprfiles=newfiles(spr=spr, spd=spd, last=last) $
   else begin
      tbeep
      sprfiles=newfiles(spd=spd, spr=spr, /select, /one)
   endelse
endif

qtemp=!quiet
!quiet=1
rd_roadmap,sprfiles,rmap
ufov=sxt_uniqfov(rmap,counts=counts)
pfixs=0
pfiys=0
plabels=''
xshape=gt_shape_cmd(rmap,/x)
yshape=gt_shape_cmd(rmap,/y)
ssu=0

for i=0,n_elements(counts)-1 do begin
   ss=ufov.(i)
   ssu=[ssu,ss(0)]
   pfixs=[pfixs,xshape(ss(0))]
   pfiys=[pfiys,yshape(ss(0))]
   helio=gt_center(rmap(ss(0)),/helio,/string,/cmd)
   helio=strmid(helio,0,3) + ' ' + strmid(helio,3,3)
   plabels=[plabels,helio + ' #Images:' + strtrim(counts(i),2)]
endfor

ssu=ssu(1:*)
multfiles=['','...']
break_file,sprfiles,splogs,sppaths,spfiles,spexts,spvers
sprfile=spfiles(0)+spexts(0)+spvers(0)
pfixs=pfixs*mag_fact
pfiys=pfiys*mag_fact

mdraw=multi_draw(pfixs(1:*),pfiys(1:*),  title='Unique FOV :  ' +       $
        sprfile + multfiles(n_elements(sprfiles) gt 1),         $
        labels=plabels(1:*))

widget_control,mdraw.top,tlb_set_xoffset=20, tlb_set_yoffset=20
;------------- Display first PFI of each unique FOV ---------------
info=get_info(rmap,/non)
proc=(['tv','tvscl'])(scale)
wtemp=!d.window

for i=0,n_elements(mdraw.views)-1 do begin
;   rd_sda,sprfiles,grid_data(rmap(ssu(i)),min=grid),index,data
   rd_sda,sprfiles,ssu(i),index,data
   widget_control,set_uvalue=info(ufov.(i)), mdraw.views(i).base
   widget_control,set_uvalue=ufov.(i), mdraw.views(i).label
   widget_control,set_uvalue=sprfiles, mdraw.views(i).draw
   window=get_wvalue(mdraw.views(i).draw)
   wset,window
   data=temporary(data(*,*,0))
   sdata=size(data)
   if mag_fact gt 1 then data=rebin(temporary(data),sdata(1)*mag_fact, $
         sdata(2)*mag_fact,/samp)
   call_procedure,proc,data
endfor
if wtemp ne -1 then wset,wtemp
; ------------------------------------------------------------------

; force read of 1st FOV...

xspr_rd1fov, mdraw.views(0).button, mdraw

widget_control,get_uvalue=ssx,mdraw.views(0).label
nimg=n_elements(ssx)


!quiet=qtemp

return, mdraw

end
;****************************************************************************

;****************************** xspr_newss **********************************

pro xspr_newss, sss
@xstepper.common

sscnt=n_elements(sss)
ssmap=sss 
dispopt=1
return
end
;****************************************************************************

;****************************** xspr_event **********************************

pro xspr_event,event
;
;
;   Name: xspr_event
;
;   Purpose: event handler for xspr
;
;   History: slf, 30-April-1992 - prototype
;	     (based on sda_look.pro, circa oct,91)
;
;   Common Blocks:
;      sda_draw_private
;      xstepper_blk
;
;   History - 30-april-92 (see xtepper.pro documentation)
;	      19-oct-92   (fixed IMG->SS bug)
;             22-feb-93   (cleaned up backregister logic for V3.0)
;	      29-Jun-93   (allow scale/noscale for pixmaps)
;			  (reset pixmaps on QUIT (X-management))
;-
;
widget_control,event.top,get_uvalue=top_struct

;
common  xspr_event_blk, goes_win
common	sda_draw_private,utility 	; zoom window widget
@xstepper.common

menubuts=get_wvalue(xstep_str.menubuts)
freeze=xstep_str.menubuts(where(menubuts eq 'Freeze'))
movie =xstep_str.menubuts(where(menubuts eq 'Movie'))

not_md=1

case (strtrim(event_name(event),2)) of

;
;-------------------- Draw Event (Zoom Image) -----------------
   "DRAW":begin
      sizeutil=size(utility)
      newone=0
      if sizeutil(1) eq 2 then newone=(total(utility) eq 0)
;
;     ************* break this out  ***********************
      if n_elements(utility) eq 0  or newone then begin
;	 define zoom widget
         base=widget_base(/column,title='XSTEPPER Utility')
         label=widget_label(base,/frame,value='Zoom Factor')  
	 zfacts=['2','4']
         xmenu2,zfacts, base,/exclusive,/row,uvalue=long(zfacts),$
            buttons=utilbuts,/no_release
         curr_zfact=where(zoom(4) eq long(zfacts))
	 widget_control,utilbuts(curr_zfact(0)),$
	    /set_button
         draw=widget_draw(base,xsize=256,ysize=256,/button_events) 
         widget_control,base,/realize
         utility=[base,draw]		; common
;        ***********************************************************
         xmanager,'utility',base,event_handler='xstep_uevent', $
	    group_leader=event.top
	 wherez=where(strpos(menubuts,'AZoom') eq 0,count)
	 if count ne 0 then $
	    mapx,xstep_str.menubuts(wherez(0)),/map,/show,/sens
	 
      endif
      if event.press then begin 
         which = where(top_struct.views.draw eq event.id)	; views(event)
;
;	 get 'interesting' widget values
         window =get_wvalue(event.id)
         wset,window
 
	 mapx,utility(0),/map,/show,/sensitive
	 widget_control, get_value=window, utility(1)
;
;        for now, just zoom feature enabled

	 zoom_single,event.x,event.y,window=window, scale=scale, $
		fact=zoom(4)
;        center on current window
         
	 zoom(1:3)=[window,event.x, event.y]
     endif
endcase 
;------------------------------------------------------------------
;


"BUTTON":begin				; option selection 
   notmd=1
   value=get_wvalue(event.id)
   uvalue=get_wuvalue(event.id)
   uvtop=get_wuvalue(event.top)
   case strtrim(value,2) of
;
;  --------------------- Multi Draw Buttons ----------------------
;
      
      "Read/Select": begin			  ; select OR viewport
         message,/info,'OR Selected: ' + uvalue
         xspr_event,force_evt(event,xstep_str.menubuts, $
	    value= "Freeze" )
         xspr_event,force_evt(event,xstep_str.resetbuts, $
	    value= "RST-PIX" )
         xspr_event,force_evt(event,xstep_str.resetbuts, $
	    value= "RST-SS" )
	 xspr_rd1fov, event.id, uvtop, xstep_str.goes_base
	not_md=0
      endcase
      "**CURRENT DATA**": not_md=0
;-----------Display Sequence Direction Function ------------------
      "OR Window": mapx,uvtop.pfi_base,/map,/show,/sens
      "FWRD>>": begin
          delta=1
	  case dispopt of 
	     2: xspr_update_pix, event.top, nogoes=nogos

             else:xspr_update_img, event.top, nogoes=nogos
	  endcase
      endcase
;
      "<<BWRD": begin
          delta=-1
	  case dispopt of 
	     2: xspr_update_pix, event.top
             else:xspr_update_img, event.top, nogoes=nogos
	  endcase
      endcase
;----------------------------------------------------------------
;
;-------------------- Movie Function ----------------------------
;     movie mode makes xspr_update_img or xspr_update_pix a TIMER task
      "Movie"  : begin 
         mapx,uvtop.pfi_base,/map,/show,/sens
         mapx,[movie,freeze],/map,/show,sens=[0,1]
         case dispopt of
	    0: backopt='xspr_update_img'
	    1: backopt='xspr_update_img'
            2: backopt='xspr_update_pix'
	 endcase
         minprog=1
         call_procedure,backopt,event.top,nogoes=nogos
      endcase
;
;-------------------------------------------------------------------
;
;-------------- Freeze Frame (stop movie) Function -----------------
;     freeze removes xspr_update_img from background
      "Freeze": begin
          mapx,[movie,freeze],/map,/show,sens=[1,0]
          backopt=''
	  minprog=0
      endcase
;-----------------------------------------------------------------------
;
      "XLOADCT":xloadct, group=event.top
     
;   
;-------------- Title Overlay Toggle Function ----------------------
;     control title overlay.
      "OFF": begin
	 over_info=1
	 widget_control, set_value='ON', event.id
      endcase
;
      "ON":  begin
	 over_info=0
         widget_control, set_value='OFF', event.id 
      endcase
;
;--------------------------------------------------------------------
;
;-------------- Current Image to PIXMAP Function ------------------
;
      "IMG->PIX": begin
        mapx,uvtop.pfi_base,/map,/show,/sens
	curdef=where(current eq pixmap(0,*),count)	;no duplcates
	if count eq 0 then begin
	   widget_control, xstep_str.text.text, set_value= $
	      strcompress(' Creating PIXMAP for Frame: ' + $
	         string(current))
	   pixdef = where(pixmap(0,*) ge 0,ndef)
	   if ndef eq 0 then newmap=[0,-1] else begin
	       newmap=pixmap(*,pixdef)
	       newmap=[[newmap],[current,-1]]
	    endelse

	    if newmap(1,pixcnt) lt 0 then $ 
               window,/free,/pix,xsize=xs*mag_fact, ysize=ys*mag_fact
	    newmap(1,pixcnt)=!d.window
	    newmap(0,pixcnt)=current
	    order=sort(newmap(0,*))
	    pixmap(0,0)=[[newmap(*,order)]]		;time order 
	    pixcnt = pixcnt+1
            scale_proc=['tv','tvscl']
            call_procedure,scale_proc(scale),scube(*,*,current) 			;pixmap write 
	    if over_info then stepper_title,sinfo(current) else $
	       stepper_title,'Frame: ' + strtrim(string(current),2)
	    mapx,xstep_str.dispbuts(2),/map,/show,/sens
	    widget_control, xstep_str.text.text, set_value= $
	       ' PIXMAP Complete'  
            xspr_update_pix,xstep_str.top,nogoes=nogos
         endif
      endcase
;------------------------------------------------------------------
;
;--------------- Current Image to SS Function ----------------
      "IMG->SS": begin
	 widget_control,xstep_str.text.text, set_value = $
	    strcompress(' Adding Frame: ' + string(current) + ' to SS Vector')
         curdef=where(current eq ssmap,count)
	 if count eq 0 then begin
	   ssdef = where(ssmap ge 0,ndef)
           if ndef eq 0 then newmap=[current] else $ 
	      newmap=[ssmap(ssdef),current]
	   order=sort(newmap)
	   ssmap(0)=newmap(order)
	   sscnt=sscnt+1
	 endif
	 mapx,xstep_str.dispbuts(1),/map,/show,/sens
         xspr_update_img, xstep_str.top, nogoes=nogos
       endcase
;---------------------------------------------------------------------
;

;------------------- All SS to PIXMAP Function (recursive) ---------
      "SS->PIX": begin
         xspr_event,force_evt(event,xstep_str.resetbuts, $
	    value= "RST-PIX" )
         ctemp=current
	 for i=0,sscnt-1 do begin
	    current=ssmap(i)
            xspr_event,force_evt(event,xstep_str.cimgbuts, $
	       value="IMG->PIX")
	 endfor
	 current=ctemp
      endcase 
;
;-------------------------------------------------------------------
;
;------------------- All Data to PIXMAP Function (recursive) -------
      "DATA->PIX": begin
         xspr_event,force_evt(event,xstep_str.resetbuts, $
	    value= "RST-PIX" )
         ctemp=current
	 for i=0,nimages-1 do begin
	    current=subs(i)
            xspr_event,force_evt(event,xstep_str.cimgbuts, $
	       value="IMG->PIX")
	 endfor
	 current=ctemp
      endcase 
;--------------------------------------------------------------------
;
      "IMG-RNG(HI)": range(1)=current
;
;-------------------- Reset PIXMAP Function ----------------------
      "RST-PIX": begin
	 valid=where(pixmap(1,*) ge 0,count)	;identify pixmaps
	 for i=0,count-1 do $
	    wdelete,pixmap(1,valid(i)) 		;free pixmaps
         pixmap(*)=-1				;initialize common
	 pixcnt=0				;  ""
	 pixpnt=0				;  ""
         backopt=''
         minprog=0
	 mapx,xstep_str.dispbuts,/show,/map,sens=[1,(sscnt ne 0),0]
	 widget_control, xstep_str.dispbuts(0), /set_button
	 dispopt=0
      endcase
;
;-------------------------------------------------------------------
;
;------------------------- Reset SS Vector Function ----------------
      "RST-SS": begin
	 ssmap(*)=-1
	 sscnt=0
	 sspnt=0
	 mapx,xstep_str.dispbuts(1),/show,/map,sens=0
	 widget_control, xstep_str.dispbuts(0), /set_button
	 dispopt=0
         guval=get_wuvalue(xstep_str.goes_base)
         widget_control,get_uvalue=curr,guval.draw
         if n_elements(curr) ne 0 then goes_draw, curr, xstep_str.goes_base
      endcase
;--------------------------------------------------------------------
;
      "PIX-ALIGN": begin
         align_opts=$ 
	    ['+Y','-Y','+X','-X']
	 for i=0,n_elements(xstep_str.cimgbuts)-1 do begin
	   widget_control, set_value=align_opts(i), $  
	      xstep_str.cimgbuts(i) 
	 endfor
       endcase
      "QUIT":begin
         xspr_event,force_evt(event,xstep_str.resetbuts, $
	    value= "RST-PIX" )
          utility=[0,0]
         widget_control, event.top,/destroy
      endcase
;
      "HELP": widget_control,set_value=xstepper_status(), $
	  xstep_str.text.text
      
       "New SPR": begin
           xspr_event,force_evt(event,xstep_str.menubuts, $
	    value= "Freeze" )
           xspr_event,force_evt(event,xstep_str.resetbuts, $
	     value= "RST-PIX" )
           xspr_event,force_evt(event,xstep_str.resetbuts, $
	    value= "RST-SS" )
           widget_control,xstep_str.pfi_base,/destroy
           widget_control,xstep_str.text.text, $
             set_value='****** Reading New SPR/SPD file *****  
           mapx,/show,/map,sens=0,event.top
           newpfi=xspr_newspr(sprfiles, spr=spr, spd=spd, last=last, $
               mag=mag_fact, nimg=nimg, ssu=ssu,rmap=rmap, ssx=ssx)
           mapx,/show,/map,/sens,event.top
           widget_control,xstep_str.text.text, $
             set_value='***** Refresh Completed ******' 
           xstep_str.pfi_base=newpfi.top
           widget_control,set_uvalue=xstep_str, event.top
           nimages=nimg
           range=[0,nimages-1]
           current=nimages            
           xmanager,'mdraw',xstep_str.pfi_base, group_leader=event.top, $
	       event='xspr_event'
           wtemp=!d.window

           wset,get_wvalue(xstep_str.main_draw)
           widget_control,xstep_str.text.text, $
             set_value='***** Updating SFM/SFD Display ******' 
           mapx,/show,/map,sens=0,event.top
           xspr_newsfd,sprfiles,ssu 
           widget_control,xstep_str.text.text, $
             set_value='***** SFM/SFD Refresh Complete ******' 
           mapx,/show,/map,/sens,event.top
           goes_draw,rmap(ssx), xstep_str.goes_base
           if wtemp ne -1 then wset,wtemp
       endcase
;
;------------------ DATA Display Function --------------------------
      "DATA": begin
	if event.select then begin
          dispopt=0
	  temp=delta
	  delta=0
	  xspr_update_img,event.top,nogoes=nogos
	  delta=temp
	  mapx,xstep_str.cimgbuts(0:1),/map,/show,/sens
        endif
      endcase
;
;------------------------------------------------------------------
;------------------- DATA(SS) Display Function --------------------
      "DATA(SS)": begin
        if event.select then begin
	  dispopt=1
          if sscnt eq 0 then begin
             widget_control, xstep_str.text.text, set_value= $
	     '  NO  SS  Vector  Currently  Defined'
	  endif else begin
             xspr_event,force_evt(event,xstep_str.menubuts, value= "Freeze" )
             temp=delta
	     delta=0
	     xspr_update_img,event.top,nogoes=nogos
	     delta=temp
	  endelse 
	  mapx,xstep_str.cimgbuts(0:1),/map,/show
        endif
      endcase
;
;----------------------------------------------------------------------
;
;----------------- Display PIXMAP Function -------------------------
      "PIXMAP": begin
        if event.select then begin
          dispopt=2
          if pixcnt eq 0 then begin
             widget_control,  xstep_str.text.text, set_value= $
	     '  NO  PIXMAPs  Currently  Defined'
	  endif else begin
	     temp=delta
	     delta=0
	     xspr_update_pix,event.top
	     delta=temp
             xspr_event,force_evt(event,xstep_str.menubuts, value= "Freeze" )

	     widget_control,xstep_str.text.text,set_value=$
	        '  DISPLAYING  PIXMAP ' 
	     if minprog then begin
                backopt='xspr_update_pix'
             endif
	  endelse
	  mapx,xstep_str.cimgbuts(0:1),/map,/show
        endif
      endcase
;--------------------------------------------------------------------
      ">>IDL":stop		; exit to event loop
;--------------------------------------------------------------------
;
;---------------- auto reverse / wrap display functions -----------
      "Wrap": begin
         areverse=1
         widget_control,event.id,set_value="ARev"
      endcase
;
      "ARev": begin
         areverse=0
         widget_control,event.id,set_value="Wrap"
      endcase
;
;-------------------------------------------------------------------
;    
;----------------------- Auto Zoom Function -----------------------

      "AZoom-ON":begin
         zoom(0)=0
	 widget_control,event.id,set_value="AZoom-OFF"
      endcase
;
      "AZoom-OFF":begin
         zoom(0)=1
	 widget_control,event.id,set_value="AZoom-ON"
      endcase
;--------------------------------------------------------------------
      else:help,value 
   endcase
;
   if event.select and not_md then begin
      widget_control, event.id, get_uvalue=option, bad_id=destroyed
      if n_elements(option) ne 0 then top_struct.option=option
   endif
endcase
;---------------------------------------------------------------
;-------------------- Frame Rate Function (via slider) ----------
"SLIDER": begin          
   pixrate=get_wvalue(event.id) 
   endcase


"TIMER": call_procedure,backopt,event.top,nogoes=nogos

else:message,/info,"Unknown event..."
endcase

;-----------------------------------------------------------------
;
if backopt ne '' and (tag_index(top_struct,'TIMERID'))(0) ne -1 then $
   widget_control, event_pro=backopt, top_struct.timerid

widget_control, event.top, set_uvalue=top_struct, bad_id=destroyed

return
end
;****************************************************************************

;************************** xspr_update_pix *********************************

pro xspr_update_pix, topid, nogoes=nogoses
;
;
;   Name: xspr_update_pix
;
;   Purpose: background task for xstepper pixmap movie sequence
;
;   History: slf, 2-Jun-92
;
@xstepper.common		; define common block variables
if data_chk(topid,/struct) then topid=topid.top
uval=get_wuvalue(topid)
;
rate=2./(pixrate+1) 		; interframe dwell
wait,rate
new=pixpnt+delta
case 1 of
   (new lt 0): new=pixcnt-1
   (new gt pixcnt-1): new=0
   else:                                ; within range
endcase
;
; handle auto-reverse function if selected
if (areverse) and (( (new eq 0) and (delta lt 0)) or  $
   ((new eq pixcnt-1) and delta gt 0) ) then delta=-delta
;
pixpnt=new
;
; set up window
wset,curwind

if (pixmap(1,pixpnt))(0) ge 0 then $
   device,copy=[0,0,xs*mag_fact,ys*mag_fact,0,0,pixmap(1,pixpnt)]

; resubmit task if movie mode
if minprog then widget_control, timer=rate, uval.timerid, event_pro=backopt

return
end

;************************** xspr_update_img *********************************

pro xspr_update_img, topid , loud=loud, nogoes=nogos
;
;
;   Name: update_img
;
;   Purpose: update image and image parameters for xstepper and display
;
;   Input Parameters:
;      topid - widget id of toplevel (xstepper) widget
;
;   Keyword Parameters:
;      quiet - if set, inhibits status messages
;
;   History: slf, 30-Apr-92 (for xstepper)
;	     slf,  4-Jun-92 (add ssmap option)
;            slf, 19-Oct-92 (fixed interp bug)
;
if data_chk(topid,/struct) then topid=topid.top
uval=get_wuvalue(topid)
widget_control, get_uvalue=gval, uval.goes_base
widget_control, get_uvalue=rmap, gval.draw

@xstepper.common
;
if dispopt ge 2 then return

tquiet=!quiet			; save current quiet status
!quiet= not keyword_set(loud)

; set rate (more important for pixmap displays)
rate=2./(pixrate+1)

case dispopt of
   0: begin			; display DATA
         ss=subs
	 pnt=current
	 limit=nimages
      endcase 
   1: begin			; display DATA(SS)
         ss=ssmap
	 pnt=sspnt
	 limit=sscnt
      endcase
endcase
;
; first determine and update image pointer
; handle range rollovers - (wrap or auto-reverse)
new=pnt+delta
;
case 1 of  
   (new lt 0): new=(limit-1) 
   (new gt limit-1): new=0
   else:				; within range
endcase

; handle auto-reverse function if selected
if (areverse) and (( (new eq 0) and (delta lt 0)) or  $
   ((new eq limit-1) and delta gt 0) ) then delta=-delta

if dispopt eq 0 then current=new $	; update image pointer
   else sspnt=new

image=scube(*,*,ss(new))		; select current image

; set up window
wset,curwind
; select display procedure and then display

;
; if over_info then stepper_title, last_title, /blank
scale_proc=['tv','tvscl']
call_procedure,scale_proc(scale), image
; erase unused portion of screen in title area (cleaner display)
unused=!d.x_size-(xs*mag_fact)
;if unused gt 0 then begin
;   area=bytarr(unused,64)
;   tv,area,xs,0
;endif

; 
;update text information
;if selected, overlay info on graphics device
outstring=sinfo(ss(new))
if over_info then begin
   stepper_title, outstring
   last_title=outstring
endif
;
; now output to widget text window determine if break required
if xs lt 512 then begin
    break=38			; same as stepper
    infolen=strlen(outstring)
    test=strmid(outstring,break,infolen) 
    break=break+strpos(test,' ')
    outstring=[strmid(outstring,0,break),strmid(outstring,break,infolen)]
endif
outstring=strtrim(outstring,2)
;

widget_control, set_value=outstring, xstep_str.text.text
;
; zoom if feature turned on
if zoom(0) then $
   zoom_single, zoom(2), zoom(3), window=zoom(1), scale=scale, $
	fact=zoom(4)

if not keyword_set(nogos) and (n_elements(rmap) ne 0) then $
   goes_mark,rmap(ss(new)), gval

; restore callers !quiet status
!quiet=tquiet

if minprog then widget_control, timer=rate, uval.timerid

return
end
; ************************************************************************
;
; ******************************* xspr ***********************************

pro xspr, sprfiles, spr=spr, spd=spd, last=last, goes=goes, nogoes=nogoes, $
	dset_arr, xsize=xsize, ysize=ysize , labels=labels, $
	title=title , interp=interp, noscale=noscale,	mag=mag, $ 
        info_array=info_array, subscript=subscript, start=start, nosfd=nosfd
;
;+
; NAME:  xspr
;
; PURPOSE: Widget interface/ X-Windows spr/spd file reviewer
;
; INPUT PARAMETERS (positional):
;	sprfile - (default pops up an  SPD menu in $DIR_SITE_NEWDATA
;
; OPTIONAL INPUT PARAMETERS (keyword):
;	title 	    - widget title (default=XSTEPPER)
;	xsize/ysize - if present, rebin will be done  
;       noscale     - if set, turns off tvscl 
;	subscript   - indices of images to display (default=all)
;	interp      - if set, rebin uses interp (default=sample)
;	start       - Index of starting image	
;	info_array  - strarray of image info (for stepper compatibility)
;		      may be passed as optional 2nd positional param
;       goes 	    - if set, include GOES
;       nogoes      - if set, omit GOES
;
; Calling Sequence:
;    xspr [,spNfile]  - where N=d (spd files) or N=r (spr files)
;
; Calling Examples:
;    xspr
; Button Layout:
;
; ------------------------------------------------------------------------
;| QUIT | FWRD>> | <<BWRD | Movie | Freeze | AZoom-OFF | Wrap | XLOADCT   | 
; ------------------------------------------------------------------------
;| HELP | IMG->SS | IMG->PIX | DATA->PIX | SS->PIX | RST-SS | RST-PIX     |   
; ------------------------------------------------------------------------
;| Display:  <>DATA  <>DATA(SS)  <>PIXMAP    Title-Image: <> OFF          | 
; ------------------------------------------------------------------------
;
;Button Description:
;
;   --------------------------------------------------------------------------
;   QUIT 	- exits xstepper
;   FWRD>>	- steps forward 1 image (sets movie direction to forward)
;   <<BWRD	- steps backward 1 image (sets movie direction to backward)
;   Movie	- starts movie mode 
;   Freeze	- stops movie mode
;   AZoom-OFF   - toggles between Auto Zoom Off and Auto Zoom On modes
;   Wrap        - toggles between wrap around and auto reverse modes 
;   XLOADCT 	- runx XLOADCT
;   --------------------------------------------------------------------------
;   HELP	- displays text information about currently selected images
;   IMG->SS	- places current image into SS vector and advances display
;   IMG->PIX	- places current image in a pixmap 
;   DATA->PIX   - places entire data array into pixmap array (memory caution)
;   SS->PIX     - places DATA(SS) into pixmap array
;   RST-SS	- Reset (initialize) SS vector
;   RST-PIX     - Reset (initialize) PIXMAP array
;   --------------------------------------------------------------------------
;   Display:      (select from three categories of image display)
;      DATA	- Original data cube
;      DATA(SS) _ Subset of data cube ( Data(*,*,ss))
;      PIXMAP   - Offscreen Pixmaps (allows fast frame rates on most machines)
;   Title-Image:- Toggles On/Off information written to window area
;   --------------------------------------------------------------------------
;
;   Other Features:
;      clicking on image automatically opens a second window and displays
;      a zoomed copy of the current image - this second window allows selection
;      of zoom factors - clicking on zoom window will hide it.  If the display
;      selection is DATA or DATA(SS), then the zoom window may automatically 
;      track (single step or movie mode) and auto zoom if AZoom-ON is chosen
;      (auto zoom does not work while in PIXMAP display mode)
;      Image information is displayed to the text portion of the widget
;   
;
; Side Effects: widget(s) is displayed to X terminal
;
; Common Blocks: 
;      xstepper_blk     - (xstepper parameters, direction,rebin,etc)
;      sda_draw_private - (utility window info (zoom, etc)
;
;
; Restrictions: - only one instance may be run at a time due to common
;
; HISTORY: 
;          slf ~  Apr-95  (converted xstepper/browse to spd/spr use)
;          slf 23-may-95  (added GOES logic , made /goes the default)
;          slf  5-oct-95  (Fixed a few bugs; no goes data, pixmap interupt)
;
;-
; on_error,2		; return to caller
;

@xstepper.common	;define common block
common xspr_blk1,grid, nogos

nogos=keyword_set(nogose)
goes=keyword_set(goes) or (1-keyword_set(nogoes))

grid=5			; *** future use (summary)

if keyword_set(mag) then mag_fact=mag else mag_fact = 2

if xregistered('xstepper') then begin
;  because of common, only allowed 1 run/process
   message,/info,'XSTEPPER already running, returning'
   return
endif
; 

; butfont=def_font()

; setup common block start up definitions
;
; 
delta=1				;default direction = forward 
scale=n_elements(noscale) eq 0  ;set tvscl flag
;
; zoom=[flag,window,xcent,ycent,factor]
zoom=lonarr(5)			;
zoom(4)=4			; factor 4 startup
;
;
backopt=''				; background task option
dispopt=0 				; display data default option
minprog=0				; movie in progress? (no)

; ----------------- create pfi base via multi draw -------------------
mdraw=xspr_newspr(sprfiles, spr=spr, spd=spd, last=last, rmap=rmap, $
	mag=mag , nimg=nimg, ssu=ssu, xshape=xshape, yshape=yshape, ssx=ssx)
; --------------------------------------------------------------------
nimages=nimg

range=[0,nimages-1]
over_info=0				; dont overlay titles by
areverse=0				; default is wrap-around
last_title=''
;
if not keyword_set(subscript) then subscript=indgen(nimages)
nimages=n_elements(subscript)
subs=subscript
interpol=keyword_set(interp)
;
; rebin = xsize ne ss(1) or ysize ne ss(2)
;
if n_elements(start) eq 0 then current=nimages $   ;image pointer
   else current=start-1
;
if not keyword_set (title)  then title  = 'Xstepper'

; create nested structure to contain widet information
draw_str=make_str('{dummy, base:0L, label:0L, draw:0L}')
text_str=make_str('{dummy, base:0L, label:0L, text:0L}')
;
draw_str_name = tag_names(draw_str,/structure)
text_str_name = tag_names(text_str,/structure)
;
goes_base=goes_widget()

xspr_str='{dummy, top:0L, parent:0L, option:0L,' + 	$
		 'id:"",number:n_elements(xsize), ' + 		$
		 'pfi_base:0L,'			    +		$
		 'main_draw:0L,'		    +		$
                 'views:{' + draw_str_name + '},' +   		$
                 'timerid:0L,' +				$
                 'menubuts:lonarr(9),' +			$
		 'dispbuts:lonarr(3),'  +			$
		 'resetbuts:lonarr(2),' +			$
		 'cimgbuts:lonarr(4),'  +			$
                 'xsprbuts:lonarr(1),'  +			$
		 'goes_base:0L,' +			$
		 'text:{' + text_str_name +  '}}'
xspr_str=make_str(xspr_str)
;
temp=draw_str
;
base=widget_base(/column,title=title)		; 
basea=widget_base(base,/row)

event_options= $
   ['QUIT','FWRD>>','<<BWRD','Movie','Freeze',$
	'AZoom-OFF','Wrap','XLOADCT','OR Window']
if keyword_set (event_options) then begin 
   xmenu2, event_options, base, uvalue=indgen(n_elements(event_options)), $
	/frame,/row,buttons=buttons, font=butfon
endif
; desensitize a couple of items for now
widget_control,buttons(5),sensitive=0	;zoom
widget_control,buttons(4),sensitive=0	;freeze
;
; make sub-base containing current image disposition
cimgb=widget_base(base,/row,/frame)
xmenu2, ['HELP'], cimgb, /row, font=butfont
; cimglabl=widget_label(cimgb,value='  MOVE CURRENT IMAGE TO:')
cimg_options=$
   ['IMG->SS','IMG->PIX','DATA->PIX','SS->PIX']
xmenu2, cimg_options, cimgb, /row, buttons=cimgbuts,font=butfont
; menu of reset buttons
reset_options=$
   ['RST-SS','RST-PIX']
xmenu2, reset_options, cimgb,/row,buttons=resetbuts, font=butfont
xmenu2, ['New SPR'],cimgb, /row,buttons=xsprbuts, font=butfont

; make sub-base containg display option menu
dispoptb=widget_base(base,/row,/frame)
displabl=widget_label(dispoptb,value='Display:',font=butfont)
display_options= $
   ['DATA', 'DATA(SS)', 'PIXMAP']
xmenu2, display_options,dispoptb,/row,/exclusive,buttons=dispbuts, $
	font=butfont
titleopt=widget_label(dispoptb,value='Title-Image:',font=butfont)
xmenu2,/row,/exclusive,font=butfont,['OFF'],dispoptb
;
rowsize=0
i=0		; only one draw widget
   basex = widget_base(base,/column,/frame)
;
;  set up text window for info array
   text_base=widget_base(basex,/column,/frame)
   text = widget_text(text_base,ysize=2, $
	font=get_xfont(/fixed,closest=15,/only_one), /scroll)
;
;  set up draw window for image display		; assume sfd or sfm=512x512
   drawx = widget_draw(basex, /frame, xsize=512, ysize=512)
;
wxs=256
wys=256
spaces=string(replicate(32b,(wxs/32-(wxs/384*5)) ))
spaces=string(replicate(32b,wxs/32))
slide=widget_slider(base,/suppres, $
;	title='<<<Slower' + spaces + ' FRAME RATE' + spaces + 'Faster>>>', $ 
	value=50,font=butfont)
slabel=widget_label(base,/frame,font=butfont, $
   value='<<<Slower' + spaces + ' FRAME RATE' + spaces + 'Faster>>>')
   temp.base=basex
   temp.draw=drawx
   xspr_str.views(i)=temp
;
   xspr_str.text.base=text_base
   xspr_str.text.text=text
;
xspr_str.top = base
xspr_str.main_draw=drawx
xspr_str.number = n_elements(counts)
xspr_str.menubuts=buttons
xspr_str.dispbuts=dispbuts
xspr_str.cimgbuts=cimgbuts
xspr_str.resetbuts=resetbuts
xspr_str.pfi_base=mdraw.top
xspr_str.goes_base=goes_base
xspr_str.timerid=titleopt
;
widget_control,base,/realize
widget_control,base, tlb_set_xoff=550, tlb_set_yoff=20

mdraw.parent=base
mapx,dispbuts,/map,/show,sens=[1,0,0]
widget_control, dispbuts(0), /set_button	; default=DATA
widget_control,base,set_uvalue=xspr_str	; save info
widget_control,set_uvalue=mdraw, mdraw.top
xstep_str=xspr_str
wind=get_wvalue(drawx)
wset,wind					; primary window

xspr_newsfd, sprfiles, ssu

rebin=keyword_set(mag)
pixrate=50
xs=max(xshape)
ys=max(yshape)

widget_control,mdraw.top,tlb_get_size=pfisize, tlb_set_xoff=20, tlb_set_yoff=20

goessize=pfisize

if keyword_set(goes) then begin
   widget_control,goes_base,/realize
   guval=get_wuvalue(goes_base)
   guval.master_base=base
   widget_control,goes_base, set_uvalue=guval
   widget_control,tlb_set_xoffset=20,tlb_set_yoffset=pfisize(1)+20, $
      tlb_get_size=goessize,goes_base
   goes_draw, rmap(ssx), goes_base
   xmanager,'goes_widget', goes_base,/just_reg,group_leader=base
   widget_control,guval.startslide,event_pro='goes_slider_event'
   widget_control,guval.stopslide,event_pro='goes_slider_event'
   widget_control, event_pro='xspr_update_img', titleopt
   loadct,3		;*** changing color table *****
endif

widget_control,tlb_set_xoffset=goessize(0)+20, tlb_set_yoffset=20,base

xmanager,'mdraw', mdraw.top ,event='xspr_event',/just_reg , group_leader=base
xmanager,'xspr',base
return 
end
