; $Id: defroi.pro,v 1.11 2000/08/11 22:52:28 chris Exp $
;
; Copyright (c) 1987-2000, Research Systems, Inc.  All rights reserved.
;   Unauthorized reproduction prohibited.
;

Function IDACDefROI, Sx, Sy, Xverts, Yverts, Event, X0=x0, Y0=y0, ZOOM = ZOOM, $
    NOREGION = Noregion, NOFILL = Nofill, RESTORE = restore, $
    ptrInfo = ptrInfo
 ;Define an irregular Region of Interest.
;+
; NAME:         DEFROI
; PURPOSE:  Define an irregular region of interest of an image
;       using the image display system and the cursor/mouse.
; CATEGORY: Image processing.
; CALLING SEQUENCE:
;   R = Defroi(Sx, Sy, X0, Y0)
; INPUTS:
;   Sx, Sy = Size of image, in pixels.
; Optional Inputs:
;   X0, Y0 = Coordinate of Lower left corner of image on display.
;   If omitted, (0,0) is assumed.  Screen device coordinates.
;   ZOOM = zoom factor, if omitted, 1 is assumed.
; OUTPUTS:
;   Function result = vector of subscripts of pixels inside the region.
;   Side effect: The lowest bit in which the write mask is enabled
;   is changed.
; OPTIONAL OUTPUTS:
;   Xverts, Yverts = Optional output parameters which will contain
;       the vertices enclosing the region.
; KEYWORD Parameters:
;   NOREGION = Setting NOREGION inhibits the return of the
;       pixel subscripts.
;   NOFILL = if set, inhibits filling of irregular region on completion.
;   RESTORE = if set, original image on display is restored to its
;       original state on completion.
; COMMON BLOCKS:
;   None.
; SIDE EFFECTS:
;   Display is changed if RESTORE is not set.
; RESTRICTIONS:
;   Only works for interactive, pixel oriented devices with a
;       cursor and an exclusive or writing mode.
;   A region may have at most 1000 vertices.  If this is not enough
;       edit the line setting MAXPNTS.
; PROCEDURE:
;   The exclusive or drawing mode is used to allow drawing and
;   erasing objects over the original object.
;
;   The operator marks the vertices of the region, either by
;       dragging the mouse with the left button depressed or by
;       marking vertices of an irregular polygon by clicking the
;       left mouse button, or with a combination of both.
;   The center button removes the most recently drawn points.
;   Press the right mouse button when finished.
;   When the operator is finished, the region is filled using
;       the polyfill function, and the polyfillv function is used
;       to compute the subscripts within the region.
;
; MODIFICATION HISTORY:  DMS, March, 1987.
;   Revised for SunView, DMS, Nov, 1987.
;       Added additional argument checking, SNG April, 1991
;   Modified for devices without write masks: DMS, March, 1992.
;       Uses exclusive or mode rather than write masks.
;   Modified to preserve device mode, RJF, Nov 1997.
;
;-
;

COMPILE_OPT strictarr
;on_error,2     ;Return to caller if error
;-------------------------------------------------------
; This section added by sg on 11/27/01 (down to ;---)
;-------------------------------------------------------
; We need to distinguish begween calls from
; different widget procedures and wset the correct
; draw window

tags = tag_names((*ptrInfo)) ; Returns tag names in UPPER case
;print,tags
q = where(tags eq 'EDWIN',cnt)
if cnt eq 1 then wset,(*ptrInfo).edwin $    ; rinfo
    else wset,(*ptrInfo).dwin               ; pinfo

;-------------------------------------------------------

nc1 = !d.table_size-1   ;# of colors available

if sx lt 1 or sy lt 1 then $        ;Check some obvious things
    message, 'Dimensions of the region must be greater than zero.'

if sx gt !d.x_size then $
    message, 'The width of the region must be less than ' + $
    strtrim(string(!d.x_size),2)

sy = sy < !d.y_size

device, get_graphics_function=oldGrphFunc ; Remember what to restore it to
device, set_graphics_function=6           ; Set XOR mode
again:
n = 0
;print,'Left button to mark point'
;print,'Middle button to erase previous point'
;print,'Right button to close region'
maxpnts = 21            ;max # of points.
xverts = intarr(maxpnts)        ;arrays
yverts = intarr(maxpnts)
xprev = -1
yprev = -1
if n_elements(x0) le 0 then x0 = 0
if n_elements(y0) le 0 then y0 = 0
if n_elements(zoom) le 0 then zoom = 1
;
Cursor, xx, yy, /DOWN, /DEV     ;Get 1st point with wait
repeat begin
    ;print,!MOUSE.button
    xx = (xx - x0) / zoom   ;To image coords
    yy = (yy - y0) / zoom
    if (xx lt sx) and (yy lt sy) and (!MOUSE.button eq 1) and $
        ((xx ne xprev) or (yy ne yprev)) then begin     ;New point?
        xprev = xx
        yprev = yy
        if n ge (maxpnts-1) then begin
            print,'Too many points'
            n = n-1
            endif
        xverts[n] = xx
        yverts[n] = yy
        if n ne 0 then $
          plots,xverts[n-1:n]*zoom+x0,yverts[n-1:n]*zoom + y0, $
            /dev,color=nc1,/noclip
        n = n + 1
        endif
;       We use 2 or 5 for the middle button because some Microsoft
;       compatible mice use 5.
    if ((!MOUSE.button eq 2) or (!MOUSE.button eq 5)) and (n gt 0) then begin
        n = n-1
        if n gt 0 then begin  ;Remove a vertex
          plots,xverts[n-1:n]*zoom+x0,yverts[n-1:n]*zoom+y0,color=nc1,$
            /dev,/noclip
          endif
    endif
    Cursor, xx, yy, /DOWN, /DEV    ;get x,y, no wait, device coords.
    endrep until !MOUSE.button eq 4

if n lt 3 then begin
    print,'ROI - Must have 3 points for region.  Try again.'
    goto,again
    endif
xverts = xverts[0:n-1]      ;truncate
yverts = yverts[0:n-1]

if keyword_set(restore) then $
    plots, xverts*zoom+x0, yverts *zoom + y0, /dev, color=nc1, /noclip $
else if keyword_set(nofill) then $
    plots, [xverts[0],xverts[n-1]]*zoom+x0, $
           [yverts[0],yverts[n-1]]*zoom+y0,$
        /dev,color = nc1,/noclip   $     ;Complete polygon
else polyfill, xverts*zoom+x0, yverts*zoom+y0,$
        /dev,color = nc1,/noclip ;Complete polygon

if !order ne 0 then yverts = sy/zoom - 1 - yverts   ;Invert Y?
device,set_graphics=3   ;Re-enable normal copy write

if keyword_set(noregion) then a = 0 $
  else a = polyfillv(xverts,yverts,sx,sy)   ; get subscripts inside area.

device, set_graphics_function=oldGrphFunc ; Restore old grphx mode

;-------------------------------------------------------
; This section added by sg on 11/27/01 (down to ;---)
;-------------------------------------------------------
q = where(tags eq 'EDWIN',cnt)
;print,'************** In IDACDefROI, cnt=',cnt

if cnt eq 0 then begin
    ; Turn off DoROI Check Box
    IDACBaseID=(*ptrInfo).idacID
    id = widget_info(IDACBaseID,FIND_BY_UNAME='IDACDoROICB')
    widget_control,id,set_button=0
    ; Enable Profiles and Zoom menu options
    id = widget_info(IDACBaseID,FIND_BY_UNAME='IDACAnProfiles')
    widget_control,id,sensitive=1
    id = widget_info(IDACBaseID,FIND_BY_UNAME='IDACAnZoom')
    widget_control,id,sensitive=1
    ; Expose extra zoom window, if it exists
    if(*ptrInfo).newz then widget_control,(*ptrInfo).zoomID,/map
endif else begin

    ; Turn off Redef Check Box and disable it.
    ; Now that a region has either been created
    ; or redefined, the user can only do the following:
    ;   * set the rotate flag
    ;   * associate an SEC region number with the ROI (if none already)
    ;   * save and/or exit
    ROIEditBaseID = (*ptrInfo).roieditid
    id = widget_info(ROIEditBaseID,FIND_BY_UNAME='ROIEditRedefCB')
    widget_control,id,set_button=0
    widget_control,id,sensitive=0
    id = widget_info(ROIEditBaseID,FIND_BY_UNAME='ROIEditRotateCB')
    widget_control,id,sensitive=1
    id = widget_info(ROIEditBaseID,FIND_BY_UNAME='ROIEditSave')
    ;print,'Turning on Save button'
    widget_control,id,sensitive=1

endelse
(*ptrInfo).doroi = 0

;-------------------------------------------------------

return,a

end
