;$Id: cropydata.pro,v 1.1 2006/07/27 17:56:32 azuah Exp $
;###############################################################################
;
; NAME:
;   cropydata
;
; PURPOSE:
;   Lets user specify x limits or domain of resolution
;   function. Displays the limits as vertical lines overplotted on a
;   display of the resolution data. Extends basic functionality
;   provided by getResLimit
;
; CATEGORY:
;   Data Analysis (PAN)
;
; AUTHOR:
;   Richard Tumanjong Azuah
;   NIST Center for Neutron Research
;   100 Bureau Drive, Gaithersburg, MD 20899
;   United States
;   azuah@nist.gov; (301) 9755604
;   July, 2006
;
; LICENSE:
;  The software in this file is written by an employee of
;  National Institute of Standards and Technology
;  as part of the DAVE software project.
;
;  The DAVE software package is not subject to copyright protection
;  and is in the public domain. It should be considered as an
;  experimental neutron scattering data reduction, visualization, and
;  analysis system. As such, the authors assume no responsibility
;  whatsoever for its use, and make no guarantees, expressed or
;  implied, about its quality, reliability, or any other
;  characteristic. The use of certain trade names or commercial
;  products does not imply any endorsement of a particular product,
;  nor does it imply that the named product is necessarily the best
;  product for the stated purpose. We would appreciate acknowledgment
;  if the DAVE software is used of if the code in this file is
;  included in another product.
;
;###############################################################################
pro cropydata_Display, sPtr
;widget_control, event.top, get_uvalue=sPtr

widget_control, (*sPtr).wSlider, get_value=xind
data = (*sPtr).data[xind,*]
y = (*sPtr).y
xlo = y[(*sPtr).limits[0] - 1]      ; limits are group nos!
xhi = y[(*sPtr).limits[1] - 1]
if ((*sPtr).zoom eq 1) then begin
   xr = (*sPtr).xr
   yr = (*sPtr).yr
endif else begin
   xmin = min((*sPtr).y,max=xmax)
   dx = 0.05*(xmax-xmin)
   xr = [xlo-dx,xhi+dx]
   
   ylo = min(data,max=yhi)
   dy = 5*(data[1] - data[0])
   yr = [ylo-dy,yhi+dy]
endelse

wset, (*sPtr).winPix
device,decomposed = 1, get_decomposed=old_dc
red = fsc_color('red')
green = fsc_color('green')
black = fsc_color('black')
white = fsc_color('white')

plot,(*sPtr).y,data,xrange=xr,linestyle = 0 $ ;,yrange=yr
     ,color=black,background=white,/xsty,psym=-4,thick=2 ;/ysty

plots,[xlo,xlo],!y.crange,linestyle = 2,color=red,thick=3
plots,[xhi,xhi],!y.crange,linestyle = 2,color=green,thick=3
device, decomposed=old_dc

wset, (*sPtr).winVis            ; set winVis as destination window
device, copy=[0,0,(*sPtr).xs,(*sPtr).ys,0,0,(*sPtr).winPix] ; copy contents of winPix to winVis

end

;###############################################################################
pro cropydata_Event, event

widget_control, event.top, get_uvalue=sPtr

wLO = widget_info(event.top, find_by_uname='LOLIM')
wHI = widget_info(event.top, find_by_uname='UPLIM')
widget_control, wLO, get_value=lo
widget_control, wHI, get_value=hi
(*sPtr).limits = [lo,hi]

uname = widget_info(event.id,/uname)
case uname of
   'GRPNOS': begin
      cropydata_Display, sPtr
   end

   'OK': begin
      (*sPtr).cancel = 0
      widget_control, event.top, /destroy
   end

   'CANCEL': begin
      (*sPtr).cancel = 1
      widget_control, event.top, /destroy
   end

   'GRLDRAW' : begin
      case event.type of
         0: begin               ; button press
            (*sPtr).mouseType = event.press
            if ((*sPtr).mouseType eq 4) then begin ; right-hand mb so reset plot to full range
               (*sPtr).zoom = 0
               cropydata_Display, sPtr
               (*sPtr).mouseType = 0 ; set mouse type to undefined value
               return
            endif
            if ((*sPtr).mouseType eq 1) then begin ; left-hand mb so record mouse location
               (*sPtr).zp1 = [event.x,event.y]
            endif
         end
         1: begin               ; button release
            if ((*sPtr).mouseType eq 1) then begin ; mouse press was a left-hand mb
               zp1 = (*sPtr).zp1
               zp2 = (*sPtr).zp2
               x = min([zp1[0], zp2[0]])
               y = min([zp1[1], zp2[1]])
               w = abs(zp1[0] - zp2[0])
               h = abs(zp1[1] - zp2[1])
               x2 = x+w
               y2 = y+h
               lc = convert_coord(x, y, /device, /to_data)
               uc = convert_coord(x2, y2, /device, /to_data)
               (*sPtr).xr = [lc[0],uc[0]]
               (*sPtr).yr = [lc[1],uc[1]]
               (*sPtr).zoom = 1
               cropydata_Display, sPtr
               (*sPtr).zp2 = [0.0,0.0] ; reset to zero
            endif
            (*sPtr).mouseType = 0
         end
         2: begin               ; mouse motion
            if ((*sPtr).mouseType eq 1) then begin ; mouse press was a left-hand mb
               (*sPtr).zp2 = [event.x, event.y]
               zp1 = (*sPtr).zp1
               zp2 = (*sPtr).zp2
               xc = [zp1[0], event.x, event.x, zp1[0], zp1[0]]
               yc = [zp1[1], zp1[1], event.y, event.y, zp1[1]]
               device, copy=[0,0,(*sPtr).xs,(*sPtr).ys,0,0,(*sPtr).winPix] ; copy contents of winPix to winVis
               plots, xc, yc, color=fsc_color('blue'), /device
            endif
         end
         else:
      endcase    
   end

   else: begin
      cropydata_Display, sPtr
   end
endcase

end


;###############################################################################
function cropydata, y, data, grpLimits, group_leader=group_leader, title=title

if (n_params() lt 2) then return, {cancel:0}

dSize = size(data)
ny = (dSize[0] eq 2)? dSize[2] : 1   
nx = dSize[1]

if (ny eq 1) then begin
   msg = 'Data contains a single group. Cannot crop in y!'
   void = dialog_message(/info,msg,dialog_parent=group_leader)
   return, {cancel:0}
endif

if (n_elements(title) eq 0) then title=''
if (n_elements(group_leader) ne 0) then begin
   modal = 1
   wTLB = widget_base(group_leader=group_leader,/tlb_frame_attr, /col,/modal,/base_align_center,title=title)
endif else begin
   modal = 0
   wTLB = widget_base(/tlb_frame_attr, /col,/base_align_center,title=title)
endelse

;prec = 6
if (n_elements(grpLimits) eq 0) then grpLimits = [1,ny]
grpLimits = fix(grpLimits)

fsize=12
msg1 = 'Enter group nos in fields and press carriage return to update display'
msg2 = 'Vertical lines show lower (red), upper (green) limits of desired range'
msg3 = "When satisfied, press 'DISMISS' button to accept changes and exit"
void = widget_label(wTLB,value=msg1)
void = widget_label(wTLB,value=msg2)
wCB0 = widget_base(wTLB,/row)
void = fsc_field(wCB0,title = 'Lowest Group',value=grpLimits[0],/highlight $
                 ,uname='LOLIM',/cr_only,xsize=fsize,event_pro='cropydata_event')
void = fsc_field(wCB0,title = 'Highest Group',value=grpLimits[1],/highlight $
                 ,uname='UPLIM',/cr_only,xsize=fsize,event_pro='cropydata_event')

wSlider = 0L
if (nx gt 1) then begin
   geom = widget_info(wTLB,/geometry)
   wSlider = widget_slider(wTLB,title='Select x index',minimum=0,maximum=nx-1,uname='GRPNOS',xsize=0.9*geom.xsize)
endif

wCB1 = widget_base(wTLB,/col)
xs = 450
ys = 350
wDraw = widget_draw(wCB1,xsize = xs,ysize = ys, uname='GRLDRAW',/button_events,/motion_events)
void = widget_label(wTLB,value=msg3)

window,/free,/pixmap,xsize=xs,ysize=ys
winPix = !d.window

wCB2 = widget_base(wTLB,/row)
tt1 = 'Refresh the display'
tt2 = 'Accept current values and exit'
tt3 = 'Exit without performing any cropping'
void = widget_button(wCB2,value='REFRESH',uname='',tooltip=tt1)
void = widget_button(wCB2,value='ACCEPT',uname='OK',tooltip=tt2)
void = widget_button(wCB2,value='CANCEL',uname='CANCEL',tooltip=tt3)

sPtr = ptr_new({limits:grpLimits,cancel:0,y:y,data:data,wSlider:wSlider $
                ,zp1:[0,0],zp2:[0,0],mouseType:0 $
                ,xr:[0.0,0.0],yr:[0.0,0.0],zoom:0 $
                ,winVis:winPix,winPix:winPix,xs:xs,ys:ys})
widget_control, wTLB, /realize, set_uvalue=sPtr
widget_control, wDraw, get_value=winVis
(*sPtr).winVis = winVis

event = {id:0L,top:wTLB,handler:0L}
widget_control, wTLB, send_event=event
;widget_control, wTLB, send_event=event

xmanager, 'cropydata', wTLB, no_block=modal

retVal = {limits:(*sPtr).limits,cancel:(*sPtr).cancel}
wdelete, (*sPtr).winPix
heap_free, sPtr



return, retVal
end

