;+ 
; NAME:	 
;	BOX 
; PURPOSE: 
;	Draws a rubber band box according to cursor motion, returns corners. 
; CATEGORY: 
;	Who Knows -- Need a list of the valid responses 
; CALLING SEQUENCE: 
;	BOX,xv,yv [,ratio=ratio,/device [,/data ] ] 
; INPUTS: 
;	ratio	Ratio of the length of the box sides 
;	/device	Specifies use of device coordinates 
;	/data	Specifies use of data coordinates 
; OUTPUTS: 
;	xv	2 point vector of x-coordinate for opposite box corners 
;	yv	2 point vector of y-coordinate for opposite box corners 
; COMMON BLOCKS: 
;	NONE 
; SIDE EFFECTS: 
;	Makes user think SHE/HE is a terminator. 
; RESTRICTIONS: 
;	Display must be able to support DEVICE,SET_GRAPH=6 
; PROCEDURE: 
;	STRAIGHTFORWARD (seems to be the default value of this field). 
; MODIFICATION HISTORY: 
;	Written Early 1991 by J. M. Zawodny, NASA LaRC 
;		zawodny@arbd0.larc.nasa.gov 
;- 
 
pro BOX,xv,yv,ratio=ratio,device=devi,data=data 
 
   ; check keyword compatability 
	if(keyword_set(device) and keyword_set(data)) then begin 
		print,' BOX cannot be called with both /DEVICE and /DATA' 
		return 
	endif 
 
   ; keep it quiet 
	quiet=!quiet 
	!quiet=1 
   ; save ther current graphics mode 
	device,get_graph=oldg,set_graph=6 
 
   ; wait for the initial click 
	cursor,x0,y0,/down,data=data,device=devi 
   ; Initialize 
	xo=x0 
	yo=y0 
   ; Have to plot the first point as a dot 
	plots,[x0,x0,xo,xo,x0],[y0,yo,yo,y0,y0],data=data,device=devi 
 
   ; sit here and watch for the cursor button to be released 
again:	cursor,xdummy,ydummy,/nowait,data=data,device=devi 
	if(!err ne 0) then goto,again 
 
loop: 
   ; make sure the window gets updated (wait forces a flush) 
	wait,.001 
 
   ; monitor the cursor for movements or the second click 
	cursor,cx,cy,/change,data=data,device=devi 
   ; if it was the second click we're done 
	if(!err eq 1) then goto,done 
   ; otherwise update the coordinates 
	dx = cx-x0 
	dy = cy-y0 
 
  ; check aspect ratio ? 
	if keyword_set(ratio) then begin 
	; be careful of division by zero 
		if(dx*dy eq 0) then begin 
			dx = 0 
			dy = 0 
		endif else begin 
		; two possible sides 
			ay = abs(1.*dx/ratio) 
			ax = abs(1.*dy*ratio) 
		; select largest rectangle 
			if(ax gt abs(dx)) then dx=ax*dx/abs(dx) $ 
				else dy=ay*dy/abs(dy) 
		endelse 
		 
	endif 
 
   ; values of the opposite vertex 
	x1 = x0+dx 
	y1 = y0+dy 
 
   ; erase the old box 
	plots,[x0,x0,xo,xo,x0],[y0,yo,yo,y0,y0],data=data,device=devi 
   ; draw the new box 
	plots,[x0,x0,x1,x1,x0],[y0,y1,y1,y0,y0],data=data,device=devi 
   ; save the new coordinates 
	xo=x1 
	yo=y1 
   ; keep going back until we get the second click 
	goto,loop 
 
done: 
   ; restore graphics mode 
	device,set_graph=oldg 
   ; create output arrays 
	xv=[x0,x1] 
	yv=[y0,y1] 
   ; special processing? 
	if (not keyword_set(device)) then begin 
	; for output in data coordinates order according to !n.CRANGE 
		if(((!x.crange(1)-!x.crange(0)) * dx) lt 0) then xv=reverse(xv) 
		if(((!y.crange(1)-!y.crange(0)) * dy) lt 0) then yv=reverse(yv) 
	endif else begin 
	; device coordinates are always non-real 
		xv=long(xv) 
		yv=long(yv) 
	; for device coordinates use ascending order 
		if(x0 gt x1) then xv=reverse(xv) 
		if(y1 gt y0) then yv=reverse(yv) 
	endelse 
   ;clean up and return 
	!quiet=quiet 
	return 
end 
 
