
;+
; $Id: tool2a.pro,v 1.36 2011/06/28 13:58:40 cooper Exp $
; NAME:
;	TOOL2
;
; PURPOSE:
;	A post-processing tool for jMaps, especially composite jMaps.
;
; CATEGORY:
;	JMAPS
;
; CALLING SEQUENCE:
;	TOOL2 [, filename]
;
; INPUTS:
;	None
;
; OPTIONAL INPUTS:
;	None
;	
; KEYWORD PARAMETERS:
;	None
;
; OUTPUTS:
;	None
;
; EXAMPLE:
;	tool2
;
; MODIFICATION HISTORY:
; 	Written by:	Jeff Walters, Aug 2001
;-
; $Log: tool2a.pro,v $
; Revision 1.36  2011/06/28 13:58:40  cooper
; Added button to call wgraph to fit ht curves
;
; Revision 1.35  2011/06/03 17:59:24  cooper
; corrected mistake from last update
;
; Revision 1.34  2011/06/03 16:13:57  cooper
; can now cancel loading in new maps
;
; Revision 1.33  2011/04/06 18:27:40  sheeley
; nr - finish previous fix by adding common dir_common
;
; Revision 1.32  2011/03/23 22:01:26  nathan
; define jmap_dir if input filename defined
;
; Revision 1.31  2010/06/29 16:54:23  cooper
; Added button to call jmap_in_situ
;
; Revision 1.30  2009/12/10 22:16:13  nathan
; fix dpi
;
; Revision 1.29  2009/12/10 22:04:59  nathan
; init dpi
;
; Revision 1.28  2009/12/08 18:32:48  mcnutt
; added ps_save resolution options to widget
;
; Revision 1.27  2009/12/07 21:19:07  nathan
; Removed non-functioning save buttons, added Save as GIF button
;
; Revision 1.26  2009/12/07 17:16:37  nathan
; define common blocks that are in multidisplay
;
; Revision 1.25  2009/12/04 21:36:05  nathan
; move multidisplay and plotmap routines to multidisplay2a.pro
;
; Revision 1.24  2009/12/04 15:55:11  nathan
; left stop in
;
; Revision 1.23  2009/12/04 15:52:40  nathan
; Limit size of output image to 1000 dpi; retain save_dir in common block
;
; Revision 1.22  2009/09/14 20:21:34  nathan
; Modifications to print section and syncjmapwithmovie.dat test to make more
; generally usable.
;
; Revision 1.21  2009/07/14 19:54:12  cooper
; changed color of sync point to yellow for better visibility
;
; Revision 1.20  2009/07/13 19:11:00  cooper
; changed save location of data file for sync with movie
;
; Revision 1.19  2009/07/13 16:14:13  cooper
; added capability to sync with scc_wrunmoviem
;
; Revision 1.18  2009/07/13 16:11:22  cooper
; added capability to sync with scc_wrunmoviem
;
; Revision 1.17  2009/06/22 19:57:48  cooper
; changed default distance units to solar radii
;
; Revision 1.16  2009/06/16 15:14:42  cooper
; altered call to wave_dir2a to allow for satellite info
;
; Revision 1.15  2009/06/15 16:16:25  cooper
; modified widget, added satellite info
;
; Revision 1.14  2008/08/08 20:21:59  sheeley
; removed window from device command
;
; Revision 1.13  2008/08/07 22:26:43  sheeley
; Changed Distance to Arc Length
;
; Revision 1.12  2008/08/07 22:12:33  sheeley
; Changed Angle to Elongation
;
; Revision 1.11  2008/07/15 16:12:54  sheeley
; replace print with read
;
; Revision 1.10  2008/07/15 16:10:30  sheeley
; fixed quote error
;
; Revision 1.9  2008/07/15 16:03:24  sheeley
; modified to allow multiple printers
;
; Revision 1.8  2008/06/27 15:07:24  sheeley
; shifted cursor symbol down one pixel
;
; Revision 1.7  2008/06/27 15:01:25  sheeley
; nr - default /ARROW_CURSOR
;
; Revision 1.5  2008/06/26 20:43:02  sheeley
; added alignment=0.5 to xyouts to put the symbol right on the tip of the arrow
;
; Revision 1.4  2008/06/26 19:15:50  nathan
; define common dir_common (so can be run without defining it elsewhere)
;
; Revision 1.3  2008/02/06 23:13:01  nathan
; added ARROW_CURSOR keyword
;


FUNCTION boxsize_error, size, box, target
   n = fix(size / box)
   e = (size - n*box)^2 + (box - target)^2
   boxsize_error = e
   return, boxsize_error
END

FUNCTION best_box_size, size, target, max_deviation
;*** This function returns the best box size to use
;*** for a given map length and a target box size.  The
;*** function minimizes an error metric that is defined
;*** in BOXSIZE_ERROR.  The error is a function of the 
;*** number of leftover pixles at the edge of a map and
;*** the distance from the preset target distance.

   n = 2*fix(max_deviation*2) ;make n even
   
   x = target - (n / 2) + indgen(n)
   
   e = fltarr(n)
   
   FOR i=0, n-1 DO BEGIN
      e(i) = boxsize_error(size, x(i), target)
   ENDFOR
   
   min = min(e, index)
   
   best_box_size = x(index)
   
   RETURN, best_box_size

END
  
FUNCTION dev_filter2, img, factor, BOX = box, C2 = c2
;***
;*** Modifiy the two constants below to change the box
;*** size.  

   SZ_RADIAL = 15
   SZ_TIME = 100
   MIN_THRESH = 3
;___________________
   
   s = size(img)
   img = FLOAT(BYTSCL(img))
   img = img - mean(img)
   cols = s(1)
   rows = s(2)
   nimg = img
   ;*** For use with the tool, the dev_filter does not look for the
   ;*** occulting disk.
   ;start = 30+38*KEYWORD_SET(c2)
   start = 0
   
   IF KEYWORD_SET(box) THEN BEGIN
      ;** 
      ;** Box Method
      ;** 
      
      ;** Calculate the box sizes.
      ;**
      ;** SZ_RADIAL and SZ_TIME will be adjusted slightly so that
      ;** a they are as close to the preset values as possible
      ;** but edge effects are minimized.  See best_box_size.pro
      ;** for details on how this is done
      
      stripx = best_box_size(cols-start, SZ_RADIAL, 1)
      stripy = best_box_size(rows, SZ_TIME, FIX(0.15*SZ_TIME))
      
      nnimg=dblarr(cols,rows)
   
      FOR i=start, cols - stripx,stripx DO BEGIN
         FOR j=0,rows-stripy,stripy DO BEGIN
            result = MOMENT(nimg(i:stripx-1+i, j:stripy-1+j))
            sd = result(1)
            IF (sd ge MIN_THRESH) THEN BEGIN
               sd =  (SQRT(sd))^(factor)
               nnimg(i:stripx-1+i, j:stripy-1+j) = nimg(i:stripx-1+i, j:stripy-1+j) / (sd) ;- MEDIAN(nimg(i:stripx-1+i, j:stripy-1+j) / (sd))
            ENDIF
         ENDFOR
      ENDFOR
   
      IF (i+1 LT cols) THEN BEGIN  
        FOR j=0,rows-stripy,stripy DO BEGIN
          result=MOMENT(nimg(i-stripx:cols-1,j:j+stripy-1))
          sd=result(1)
          IF (sd ge MIN_THRESH) THEN BEGIN
             sd=(SQRT(sd))^(factor)
             nnimg(i-stripx:cols-1,j:j+stripy-1)=nimg(i-stripx:cols-1,j:j+stripy-1)/(sd) ;- median(nimg(i-stripx:cols-1,j:j+stripy-1)/(sd))
          ENDIF
         ENDFOR
      ENDIF

      IF (j+1 LT rows) THEN BEGIN  
         FOR i=start, cols - stripx,stripx DO BEGIN
            result=MOMENT(nimg(i:i+stripx-1,j-stripy:rows-1))
            sd=result(1)
            IF (sd ge MIN_THRESH) THEN BEGIN
               sd=(SQRT(sd))^(factor)
               nnimg(i:i+stripx-1,j-stripy:rows-1)=nimg(i:i+stripx-1,j-stripy:rows-1)/(sd) ;- median(nimg(i:i+stripx-1,j-stripy:rows-1)/(sd))
            ENDIF
         ENDFOR
      ENDIF

      nnimg(0:start)=MEDIAN(nnimg)
      RETURN, nnimg
   ENDIF ELSE BEGIN
      ;** 
      ;** Column
      ;**
      FOR i=start, cols - 1 DO BEGIN
         result = MOMENT(nimg(i-1:i, *))
         sd = (SQRT(result(1)))^factor
         IF (sd ge 0.001) THEN nimg(i, *) = img(i, *) / (sd)
      ENDFOR
   ENDELSE
     nimg(0:start, *)=MEDIAN(nimg)
     help


   RETURN, nimg
END

FUNCTION default_opt_strct
;*** Purpose: Create a structure that is used internally
;*** to store various processing options.

   s = {opts, $
   	dev:0, $
   	dev_factor:1.0, $
   	point:0, $
   	point_box:3, $
   	point_tol:5, $
   	point_iter:1, $
   	chop:0, $
   	chop_tol:5.0, $
   	dn:0, $
   	dn_coeff:4, $
   	dn_tol:0.5, $
   	smooth:0, $
   	smooth_sz:5 }
    
    default_opt_strct = replicate(s, 1)

    RETURN, default_opt_strct
END


FUNCTION ht_str, x, y

common PM1, files, ximsize, yimsize, margins, borders, xoffset, yoffset, nimcols, nimrows, curr_x, curr_y,dpi
COMMON Tool2_Common, map, map_pix, newmap, new_pix, h, draw_mode, opts, allopts, prevmode, $
	edit_mode, plotted, save_region, movie_files, movie_frame, crop_hdr, start_time, end_time, $
	units, xscale, yscale, curr_pos, curr_pix, hts, vels, gauge_vel, vel_mode, busy, satellite, mvi_point
COMMON WIDGET_ID, main1, draw6, draw6_id, reg_fields, scale_fields, coord_fields, plot_fields, ps_fields, $
	unit_fields, dev_fields, point_fields, chop_fields, denoise_fields, smooth_fields, file_fields, sync_fields
COMMON DIR_COMMON, mvi_dir, jmap_dir, save_dir, diff_dir, image_dir

  ht = hts[0]
  s = size(map)
  ht.plot_num = 0
  ht.time = start_time + (end_time-start_time) * float(x) / s[1]
  ht.height = h.min_r + (h.max_r - h.min_r) * float(y) / s[2]
  RETURN, ht

END


PRO Redisplay, m
;*** Purpose: Used internally to redisplay a jmap in the 
;*** TOOL2 widget's DRAW widget.

COMMON Tool2_Common
COMMON WIDGET_ID

   s = size(m)
   IF(s[0] LT 2) THEN RETURN
   xsize = FLOOR(s(1)*xscale)
   ysize = FLOOR(s(2)*yscale)
   IF(xsize EQ 0 OR ysize EQ 0) THEN RETURN
   
   WIDGET_CONTROL, draw6, DRAW_XSIZE=xsize
   WIDGET_CONTROL, draw6, DRAW_YSIZE=ysize

	IF(edit_mode LT 0) THEN curr = 'Editing All Regions' $
	ELSE curr = 'Editing Region ' + STRTRIM(STRING(edit_mode+1),2)
	WIDGET_CONTROL, reg_fields[7], SET_VALUE=curr
   
   WSET, draw6_id
   LOADCT, 0, /SILENT
   tvscl, congrid(m, xsize, ysize)

   LOADCT, 4, /SILENT
   thickness = 3
   IF(draw_mode) THEN BEGIN
	   x1 = 0
	   x2 = floor(n_elements(m[*,0])*xscale)
	   IF(edit_mode LT 0) THEN BEGIN
		y1 = 0
		y2 = floor(n_elements(m[0,*])*yscale)
	   ENDIF ELSE BEGIN
		y1 = floor(((edit_mode LT h.nreg-1) ? h.border[edit_mode+1,3] : h.border[edit_mode,2]) * yscale)
		y2 = floor(h.border[edit_mode,3] * yscale)
	   END
	   x2 = x2 - thickness
	   y2 = y2 - thickness
	   PLOTS, [x1, x2, x2, x1, x1], [y1, y1, y2, y2, y1], /DEVICE, THICK=thickness, COLOR=255
	
	   IF(~save_region[0]) THEN BEGIN
		nht = n_elements(hts)
		FOR i=1, nht-1 DO BEGIN
			x = hts[i].time * xscale
			y = hts[i].height * yscale
			XYOUTS, x, y-1, '+',alignment=0.5, COLOR=0, /DEVICE
			XYOUTS, x, y-1, 'O',alignment=0.5, COLOR=150, /DEVICE
		ENDFOR
		IF(datatype(mvi_point) NE 'UND') THEN BEGIN
			x=mvi_point.time
			y=mvi_point.height
			XYOUTS, x, y-1, '[(',alignment=1., COLOR=255, /DEVICE
			XYOUTS, x, y-1, ')]',alignment=0., COLOR=255, /DEVICE
		ENDIF
	   ENDIF ELSE BEGIN
		PLOTS, [save_region[2], save_region[3], save_region[3], save_region[2], save_region[2]]*xscale, $
			[save_region[4], save_region[4], save_region[5], save_region[5], save_region[4]]*yscale, $
			/DEVICE, THICK=thickness, COLOR=150
	   ENDELSE
   ENDIF
   IF(vel_mode) THEN BEGIN
	slope = gauge_vel
	convert_units, slope, units[1], 1
	IF(units[1] EQ 0 OR units[1] EQ 1) THEN slope = slope / 3600.
	time_scale = (end_time - start_time) / h.nx
	ht_scale = (h.max_r - h.min_r) / h.ny
	slope = slope * (time_scale / ht_scale) * (yscale / xscale)
	x1 = curr_pix[0]*xscale - h.nx * xscale
	x2 = curr_pix[0]*xscale + h.nx * xscale
	y1 = curr_pix[1]*yscale - slope * h.nx * xscale
	y2 = curr_pix[1]*yscale + slope * h.nx * xscale
	PLOTS, [x1, x2], [y1, y2], /DEVICE, THICK=thickness, COLOR=150
   ENDIF
   LOADCT, 0, /SILENT
END


PRO draw_coords, ev

COMMON Tool2_Common
COMMON WIDGET_ID

  IF(busy OR datatype(h) EQ 'UND') THEN RETURN

  IF(ev.release EQ 1) THEN BEGIN
	curr_pix = [(ev.x/xscale) < (h.nx-1), (ev.y/yscale) < (h.ny-1)]
	IF(~draw_mode) THEN redisplay, newmap
  ENDIF

  xsize = h.nx * xscale
  ysize = h.ny * yscale

  curr_time = (start_time + (end_time-start_time)*float(ev.x) / xsize)
  curr_ht = h.min_r + (h.max_r - h.min_r)*float(ev.y) / ysize
  convert_units, curr_ht, 1, units[0]

  time_str = utc2str(tai2utc(curr_time))
  mid_pos = strpos(time_str, 'T')
  IF(mid_pos GT 0) THEN time_str = strmid(time_str, 0,mid_pos) + ' ' + strmid(time_str, mid_pos+1)
  WIDGET_CONTROL, coord_fields[3], $
	SET_VALUE='Pixel value: (' + time_str + ', ' + strtrim(string(curr_ht),2) + ')'
  WIDGET_CONTROL, coord_fields[4], $
	SET_VALUE='Pixel coordinates: (' + strtrim(string(ev.x),2) + ', ' + strtrim(string(ev.y),2) + ')'

  IF(~draw_mode)THEN RETURN
  IF(~vel_mode) THEN BEGIN
  CASE ev.release OF
	1: BEGIN  ;left-click
		IF(~save_region[0]) THEN BEGIN
			ht = hts[0]
			ht.time = ev.x / xscale
			ht.height = ev.y / yscale
			ht.plot_num = 0 ; can be used for multiple plots
			hts = [hts, ht]
			print, 'added point (',ht.time,',',ht.height,')'
		ENDIF ELSE BEGIN
			second = save_region[1] MOD 2
			other = 2 + save_region[1] + (-1)^second
			IF(save_region[1] LE 1) THEN tmp = (ev.x / xscale) > 0 < (h.nx-1) $  ; horizontal boundary
			ELSE tmp = (ev.y / yscale) > 0 < (h.ny-1)
			IF((second AND tmp GT save_region[other]) OR $
			   (~second AND tmp LT save_region[other])) THEN $
				save_region[2 + save_region[1]] = tmp
		ENDELSE
		END
	2: BEGIN  ;middle-click
		IF(~save_region[0]) THEN BEGIN
			time=ev.x
			height=ev.y
			posang=h.pa
			mvi_point={time:time,height:height,posang:posang}
			time=curr_time
			height=curr_ht
			sav_point=[time,height,posang]
			OPENW, lun,concat_dir(getenv('HOME'),'syncjmapwithmovie.dat'), /get_lun
			printf,lun, sav_point
			free_lun,lun
		ENDIF & END
	4: BEGIN  ;right-click
		IF(save_region[0]) THEN BEGIN
			save_region[1] = (save_region[1] + 1) MOD 4
			tags = ['Left', 'Right', 'Bottom', 'Top']
			WIDGET_CONTROL, plot_fields[10], SET_VALUE=' Cropping ' + tags[save_region[1]]
			undefine, tags
		ENDIF
		END
	ELSE:
  ENDCASE
  ENDIF
  IF(ev.release GT 0) THEN redisplay, newmap
END

PRO set_opts, opt
;*** Purpose: Set options shown in the widget to the values
;*** contained in opt. 
COMMON WIDGET_ID

 WIDGET_CONTROL, dev_fields[0], SET_VALUE=opt.dev
 WIDGET_CONTROL, dev_fields[1], SET_VALUE=opt.dev_factor
 WIDGET_CONTROL, point_fields[0], SET_VALUE=opt.point
 WIDGET_CONTROL, point_fields[1], SET_VALUE=opt.point_box
 WIDGET_CONTROL, point_fields[2], SET_VALUE=opt.point_tol
 WIDGET_CONTROL, point_fields[3], SET_VALUE=opt.point_iter
 WIDGET_CONTROL, chop_fields[0], SET_VALUE=opt.chop
 WIDGET_CONTROL, chop_fields[1], SET_VALUE=opt.chop_tol
 WIDGET_CONTROL, denoise_fields[0], SET_VALUE=opt.dn
 WIDGET_CONTROL, denoise_fields[1], SET_VALUE=opt.dn_coeff
 WIDGET_CONTROL, denoise_fields[2], SET_VALUE=opt.dn_tol
 WIDGET_CONTROL, smooth_fields[0], SET_VALUE=opt.smooth
 WIDGET_CONTROL, smooth_fields[1], SET_VALUE=opt.smooth_sz

END

PRO get_opts, opt
;*** Collect the options from the widget and store them 
;*** in the structure OPT.
COMMON WIDGET_ID

   WIDGET_CONTROL, dev_fields[0], GET_VALUE=a
   WIDGET_CONTROL, dev_fields[1], GET_VALUE=b
   WIDGET_CONTROL, point_fields[0], GET_VALUE=c
   WIDGET_CONTROL, point_fields[1], GET_VALUE=d
   WIDGET_CONTROL, point_fields[2], GET_VALUE=e
   WIDGET_CONTROL, point_fields[3], GET_VALUE=f
   WIDGET_CONTROL, chop_fields[0], GET_VALUE=g
   WIDGET_CONTROL, chop_fields[1], GET_VALUE=h
   WIDGET_CONTROL, denoise_fields[0], GET_VALUE=i
   WIDGET_CONTROL, denoise_fields[1], GET_VALUE=j
   WIDGET_CONTROL, denoise_fields[2], GET_VALUE=k
   WIDGET_CONTROL, smooth_fields[0], GET_VALUE=l
   WIDGET_CONTROL, smooth_fields[1], GET_VALUE=m
   
   opt.dev = a
   opt.dev_factor= b
   opt.point= c
   opt.point_box= d
   opt.point_tol= e
   opt.point_iter= f
   opt.chop= g
   opt.chop_tol= h
   opt.dn= i
   opt.dn_coeff= j
   opt.dn_tol= k
   opt.smooth= l
   opt.smooth_sz= m

END
   
FUNCTION process, img, opts
;*** Purpose: Look into the opts structure to determine
;*** what processing options to use.  Then, proces the image
;*** according to the options

   nimg = img
   IF opts.point THEN BEGIN
      jpoint_filter, img, opts.point_box, opts.point_tol, $
         opts.point_iter, nimg
   ENDIF
   
   IF opts.dev THEN BEGIN
      nimg = dev_filter2(TRANSPOSE(nimg), opts.dev_factor, /BOX)
      nimg = TRANSPOSE(nimg)
   ENDIF
   
   IF opts.dn THEN BEGIN
      nimg = denoise(nimg, opts.dn_coeff, opts.dn_tol)
   ENDIF
   
   IF opts.chop THEN BEGIN
      nimg = chop(nimg, opts.chop_tol)
   ENDIF
   
   IF opts.smooth THEN BEGIN
      nimg = smooth(nimg, opts.smooth_sz)
   ENDIF
   
   RETURN, nimg
END

FUNCTION COVER_OCC_DISK, map, r_max
;*** Purpose: Covers the occulting disk
;*** with the median color of the image.
;*** r_max is the top height of the map.

   newmap = map
   RATIO = (2.0/6.3)
   
   cover_ratio = RATIO *(6.3/r_max)
   
   occ_disk_top = cover_ratio*n_elements(map(0,*))
   
   median_color = median(map)
   
   newmap(*,0:occ_disk_top) = median_color
   
   RETURN, newmap
END


FUNCTION plot_vals, hdr

COMMON Tool2_Common

IF(n_elements(hts) LE 1) THEN RETURN, 0
IF(datatype(hdr) EQ 'UND') THEN hdr = h

curr_hts = hts[1:*]
curr_hts.time = start_time + (end_time-start_time) * curr_hts.time / float(hdr.nx)
curr_hts.height = hdr.min_r + (hdr.max_r - hdr.min_r) * curr_hts.height / float(hdr.ny)

curr_hts = curr_hts[sort(curr_hts.time)]

RETURN, curr_hts

END


PRO convert_units, val, unit1, unit2

IF(unit1 EQ 2) THEN val = val / 695500.
IF((unit2 EQ 0 OR unit2 EQ 2) AND unit1 EQ 1) THEN val = 215. * val * !pi/180.
IF(unit2 EQ 1 AND (unit1 EQ 0 OR unit1 EQ 2)) THEN val = (val / 215.) * 180./!pi
IF(unit2 EQ 2) THEN val = val * 695500. ;695500 km per solar radius

END


PRO show_plot

COMMON Tool2_Common

get_units, labels

;convert to proper units
hdr = h
tmp = hdr.min_r
convert_units, tmp, 1, units[0]
hdr.min_r = tmp
tmp = hdr.max_r
convert_units, tmp, 1, units[0]
hdr.max_r = tmp

curr_hts = plot_vals(hdr)
ht = n_elements(curr_hts)

IF ht EQ 0 THEN RETURN

vels = get_vel(curr_hts)
vel = n_elements(vels)

tmp = vels.vel
convert_units, tmp, units[0], units[1]
vels.vel = tmp
curr_hts.time = (curr_hts.time - curr_hts[0].time) / 3600.
IF(units[1] EQ 0 OR units[1] EQ 1) THEN vels.vel = vels.vel * 3600.

;** Display plots of the recorded data
window, 1, xsize = 600, ysize = 200, xpos = 0, ypos = 0, TITLE = 'Height-Time Data'
plot, curr_hts.time, curr_hts.height, XTITLE = 'Time (Hours)', YTITLE = labels[0], PSYM = 4, charsize=1.5

plotted = 1
  
IF(vel GT 0) THEN BEGIN
	window, 2, xsize = 400, ysize = 200, xpos = 620, ypos = 0, TITLE = 'Velocity Data'
	plot, vels.height, vels.vel, XTITLE = labels[0], YTITLE = labels[1], PSYM = 4, charsize=1.5
	plotted = 2
ENDIF

END


PRO crop_map, hdr, MAP=m, PIXELS=pixels, PREV=prev

COMMON Tool2_Common

hdr = h
IF(datatype(newmap) EQ 'UND') THEN newmap = map

IF(save_region[3] GT 0 AND save_region[5] GT 0) THEN BEGIN
	m = newmap[save_region[2]:save_region[3], save_region[4]:save_region[5]]
	hdr.nx = save_region[3]-save_region[2]+1
	hdr.ny = save_region[5]-save_region[4]+1
	ht1 = ht_str(save_region[2], save_region[4])
	ht2 = ht_str(save_region[3], save_region[5])
	hdr.start_time = double(ht1.time)
	hdr.end_time = double(ht2.time)
	hdr.min_r = ht1.height
	hdr.max_r = ht2.height
	hdr.nreg = 0
	hdr.width[*] = 0.0
	hdr.reg_dim[*] = 0
	hdr.border[*] = 0
	curr_pix = 0
	curr_new = 0
	FOR i=0,h.nreg-1 DO BEGIN
		n_pix = h.reg_dim[i,0]*h.reg_dim[i,1]
		curr_pix = curr_pix + n_pix
		IF(save_region[3] LE h.border[i,0] OR save_region[2] GE h.border[i,1] OR $
		   save_region[5] LE h.border[i,2] OR save_region[4] GE h.border[i,3]) THEN CONTINUE
		region = reform(new_pix[curr_pix-n_pix:curr_pix-1], h.reg_dim[i,0], h.reg_dim[i,1])
		x_ext = floor(float(save_region[2:3]+[0,1]-h.border[i,0]) * h.reg_dim[i,0]/(h.border[i,1]-h.border[i,0]))
		y_ext = floor(float(save_region[4:5]+[0,1]-h.border[i,2]) * h.reg_dim[i,1]/(h.border[i,3]-h.border[i,2]))
		x_ext = x_ext > 0 < h.reg_dim[i,0]
		y_ext = y_ext > 0 < h.reg_dim[i,1]
		hdr.border[hdr.nreg,0:1] = (h.border[i,0:1]-save_region[2]) > 0 < hdr.nx
		hdr.border[hdr.nreg,2:3] = (h.border[i,2:3]-save_region[4]) > 0 < hdr.ny
		hdr.reg_dim[hdr.nreg,*] = [x_ext[1]-x_ext[0], y_ext[1]-y_ext[0]]
		hdr.width[hdr.nreg] = h.width[i]
		region = (temporary(region))[x_ext[0]:x_ext[1]-1, y_ext[0]:y_ext[1]-1]
		n_pix = (x_ext[1]-x_ext[0]) * (y_ext[1]-y_ext[0])
		IF(hdr.nreg EQ 0) THEN pixels = reform(region,n_pix) ELSE pixels = [temporary(pixels), reform(region,n_pix)]
		curr_new = curr_new + n_pix
		hdr.nreg = hdr.nreg + 1
	ENDFOR
ENDIF

END


PRO load_map, filename, RESET=reset

COMMON Tool2_Common
COMMON WIDGET_ID
common PM1
	undefine, map
	undefine, newmap
	undefine, map_pix
	undefine, new_pix
	map = read_jmap2a(filename, HEADER=h, PIXELS=map_pix)
	start_time=h.start_time ; anytim2tai(h.start_time)
        end_time=h.end_time ; anytim2tai(h.end_time)
        time=(end_time-start_time)/3600.
        vertical=h.max_r-h.min_r
        satellite=h.satellite
        ;help,h,/str
	WIDGET_CONTROL, coord_fields[0], SET_VALUE='Pos. Angle: ' + strtrim(string(h.pa),2)
	WIDGET_CONTROL, coord_fields[1], SET_VALUE='Total time (hr): ' + strtrim(string(time),2)
	WIDGET_CONTROL, coord_fields[2], SET_VALUE='Total span (deg): ' + strtrim(string(vertical),2)
	IF(datatype(satellite) NE 'UND') THEN WIDGET_CONTROL, coord_fields[5], SET_VALUE='Satellite: '+satellite

	IF(keyword_set(RESET)) THEN BEGIN

  	IF(h.nx GT 1000) THEN BEGIN
		xscale = 1000. / h.nx
		WIDGET_CONTROL, scale_fields[1], SET_VALUE=xscale
	ENDIF
	IF(h.ny GT 256) THEN BEGIN
		yscale = 256. / h.ny
		WIDGET_CONTROL, scale_fields[2], SET_VALUE=yscale
	ENDIF

	opts = default_opt_strct()
	opts = replicate(opts, h.nreg)
	edit_mode = -1

	;for clicked-path height/time storage
	ht_struct = {ht, plot_num: -1, time: -1.0, height: 0.0}		
	hts = REPLICATE(ht_struct, 1)
	vels = 0

	FOR i=1, plotted DO WDELETE, i
	plotted = 0

	save_region[1] = 0
	save_region[2] = 0
	save_region[3] = h.nx-1
	save_region[4] = 0
	save_region[5] = h.ny-1

	ENDIF

	newmap = map
	new_pix = map_pix
	REDISPLAY, newmap
END



PRO get_units, labels

COMMON Tool2_Common

labels = strarr(n_elements(units))
CASE units[0] OF
	1: labels[0] = 'Elongation (degrees)'
	0: labels[0] = 'Arc Length (R!DSun!N)'
	2: labels[0] = 'Arc Length (km)'
ENDCASE
CASE units[1] OF
	0: labels[1] = 'Velocity (R!Dsun!N/hr)'
	1: labels[1] = 'Angular Velocity (Deg/hr)'
	2: labels[1] = 'Velocity (km/sec)'
ENDCASE

END


PRO process_map
COMMON tool2_common
COMMON widget_id

IF(datatype(h) EQ 'UND') THEN RETURN

tmp = default_opt_strct()
get_opts, tmp
IF(edit_mode GE 0) THEN opts[edit_mode] = tmp ELSE opts[*] = tmp
undefine, tmp
            
WIDGET_CONTROL, /HOURGLASS
newmap = map
new_pix = map_pix
curr_pix = 0
FOR i=0, h.nreg-1 DO BEGIN
	n_pix = h.reg_dim[i,0]*h.reg_dim[i,1]
	map2 = reform(map_pix[curr_pix:curr_pix+n_pix-1], h.reg_dim[i,0], h.reg_dim[i,1])
	map2 = PROCESS(temporary(map2), opts[i])
	new_pix[curr_pix:curr_pix+n_pix-1] = reform(bytscl(map2), n_pix)
	map2 = CONGRID(BYTSCL(temporary(map2)), h.border[i,1]-h.border[i,0], h.border[i,3]-h.border[i,2])
	newmap[h.border[i,0]:h.border[i,1]-1, h.border[i,2]:h.border[i,3]-1] = map2
	curr_pix = curr_pix + n_pix
ENDFOR

;newmap = COVER_OCC_DISK(newmap,h.max_r) ;nrs 8/30/01
REDISPLAY, newmap

END


PRO MAIN1_Event, Event

COMMON DIR_COMMON
COMMON tool2_common
COMMON widget_id
common PM1

IF datatype(save_dir) EQ 'UND' THEN IF datatype(jmap_dir) NE 'UND' THEN save_dir=jmap_dir

  IF(busy) THEN RETURN

  WIDGET_CONTROL,Event.Id,GET_UVALUE=Ev
  
  ;*******
  ;*** Constants
  ;***
  ;***
  STR = '__Tool2_________ '
  START_STR ='_________________________________________________________________'
  CASE Ev OF 
  'next_reg': IF(h.nreg GT 0) THEN BEGIN
	edit_mode = edit_mode - 1
	IF(edit_mode LT 0) THEN edit_mode = h.nreg-1
	redisplay, newmap
	ENDIF
  'prev_reg': IF(h.nreg GT 0) THEN BEGIN
	edit_mode = edit_mode + 1
	IF(edit_mode GT h.nreg-1) THEN edit_mode = 0
	redisplay, newmap
	ENDIF
  'all_reg': BEGIN
	edit_mode = -1
	redisplay, newmap
	END
  'set_opts': BEGIN
	tmp = default_opt_strct()
	get_opts,tmp
	IF(edit_mode LT 0) THEN opts[*] = tmp $
	ELSE opts[edit_mode] = tmp
	undefine, tmp
	END
  'get_opts': BEGIN
	IF(edit_mode GE 0) THEN set_opts, opts[edit_mode]
	END
  'process_button': BEGIN
	busy = 1
	process_map
	busy = 0
	END
  'process_all': IF(datatype(movie_files) NE 'UND') THEN BEGIN
	busy = 1
	FOR i=0,n_elements(movie_files)-1 DO BEGIN
		ind = (i+1) MOD n_elements(movie_files)
		load_map, movie_files[ind]
		process_map
		break_file, movie_files[ind], disk, dir, name, ext
		IF(strpos(dir,'edits/') LT 0) THEN dir = dir + 'edits/'
		IF(strmid(name,strlen(name)-2,2) NE '_t') THEN name = name + '_t'
		newpath = dir + name + ext
		write_jmap2a, new_pix, newpath, h
		movie_files[ind] = newpath
		redisplay, newmap
	ENDFOR
	load_map, movie_files[0]
	redisplay, newmap
	busy = 0
	ENDIF
  'reset': BEGIN
	newmap = map
	redisplay, newmap
	END
  'draw_mode': BEGIN
	IF event.select THEN draw_mode = 1 ELSE draw_mode = 0
	redisplay, newmap
	END
  'run_movie': IF(datatype(movie_files) NE 'UND') THEN BEGIN
	FOR i=0,n_elements(movie_files)-1 DO BEGIN
		load_map, movie_files[i] ; map = read_jmap2a(movie_files[i])
		;redisplay, newmap
		wait, 0.1
	ENDFOR
	load_map, movie_files[0] ; map = read_jmap2a(h.filename)
	redisplay, newmap
	ENDIF
  'movie_frame': IF(datatype(movie_files) NE 'UND') THEN BEGIN
	movie_frame = event.value > 0 < (n_elements(movie_files)-1)
	load_map, movie_files[movie_frame] ; map = read_jmap2a(movie_files[movie_frame])
	newmap=map
	redisplay, newmap
	ENDIF
  'scalex': BEGIN
	xscale = event.value
	redisplay, newmap
	END
  'scaley': BEGIN
	yscale = event.value
	redisplay, newmap
	END
  'resize': IF(datatype(h) NE 'UND') THEN BEGIN
	IF(h.nx GT 1000) THEN xscale = 1000. / h.nx ELSE xscale = 1.
	IF(h.ny GT 256) THEN yscale = 256. / h.ny ELSE yscale = 1.
	WIDGET_CONTROL, scale_fields[1], SET_VALUE=xscale
	WIDGET_CONTROL, scale_fields[2], SET_VALUE=yscale
	redisplay, newmap
	ENDIF
  'calc': BEGIN	 sat=h.satellite
	nht = n_elements(hts)
	IF(nht LE 3) THEN message, 'Must have at least 3 data points', /INF $
	ELSE show_plot
	END
  'remove': BEGIN
	nht = n_elements(hts)
	IF(nht GT 1) THEN hts = hts[0:nht-2]
	redisplay, newmap
	END
  'remove_all': BEGIN
	hts = hts[0]
	redisplay, newmap
	END
  'save_plot': IF(n_elements(hts) GT 1) THEN BEGIN
	file = DIALOG_PICKFILE(FILTER = '*.ht', PATH = save_dir)
	curr_hts = plot_vals()
	IF (MAX(curr_hts.plot_num) eq 0) THEN BEGIN
		ht_convert, HTS = curr_hts, OUTFILE = file, START_TIME = utc2str(tai2utc(h.start_time)), ANGLE = h.pa
	ENDIF ELSE BEGIN
		FOR i = 0, MAX(curr_hts.plot_num) DO BEGIN
			tempfile = STR_SEP(file, '.')
			tempfile(0) = tempfile(0) + '_' +STRTRIM(STRING(i+1), 2) 
			tempfile = tempfile(0) + '.' +tempfile(1)
			ht_convert, HTS = curr_hts, utc2str(tai2utc(h.start_time)), OUTFILE = tempfile, $
				PLOT_NUM = i, ANGLE = h.pa
		ENDFOR
	ENDELSE
	break_file,file,vol,dir,fi,su
	save_dir=dir
	ENDIF
  'load_plot': BEGIN
	END
  'hide_plot': BEGIN
	FOR i=1, plotted DO WDELETE, i
	plotted = 0
	END
  'run_wgraph':	BEGIN
		IF n_elements(hts) LE 1 THEN return
		file='idltemp.ht'
		curr_hts=plot_vals()
		ht_convert,hts=curr_hts,outfile=file,start_time=utc2str(tai2utc(h.start_time)),angle=h.pa
		file='idltemp.ht'
		wgraph,f=file
		spawn,'rm -f '+file
		END
  'plot_delta': BEGIN
      IF(n_elements(hts) GT 1) THEN BEGIN
        break_file, h.filename, disk, dir, name
         ;if  ~(stregex(name,'1b') NE -1) then tempsat='b' 
         ;if  ~(stregex(name,'2b') NE -1) then tempsat='b' 
         ;if ~(stregex(name,'c2') NE -1)  then tempsat='earth'
         ;if ~(stregex(name,'c3') NE -1) then tempsat='earth' 
         ;if ~(stregex(name,'2a') NE -1)  then tempsat='a' 
         ;if ~(stregex(name,'1a') NE -1)  then tempsat='a'
         ;if ~(datatype(tempsat) EQ 'UND') then sat=tempsat else sat='a'
         ;sat=''
         ;read,'enter spacecraft name (a, b, or earth) ',sat
	 hassat=0
	 IF(h.satellite NE '') THEN BEGIN sat=h.satellite & hassat=1
         ENDIF ELSE BEGIN if ((h.pa ge 0.) and (h.pa le 179.)) then sat='a'
         if ((h.pa ge 180.) and (h.pa lt 360.)) then sat='b'
         ENDELSE
         print, 'sat = ',sat

	file = 'idltemp.ht'
	curr_hts = plot_vals()
	ht_convert, HTS=curr_hts, OUTFILE=file, START_TIME=utc2str(tai2utc(h.start_time)), ANGLE=h.pa
	file = 'idltemp.ht' 
	;IF(hassat) THEN	d = wave_dir2a(file, delta=delta, vr=vr, t0=t0,sat=sat,/HASSAT) $
	;   ELSE 
        d = wave_dir2a(file, delta=delta, vr=vr, t0=t0,sat=sat)
       
	t0 = anytim2tai(t0)
	del = delta*!pi/180
        pa = h.pa*!pi/180
;        if ~(datatype(tempsat) EQ 'UND') then sat=tempsat 
;        if (datatype(tempsat) EQ 'UND') then begin
;           if ((h.max_r GT 8) and (h.pa GT 20) and (h.pa LT 160)) then sat='a'
;           if ((h.max_r GT 8) and (h.pa GT 110) and (h.pa LT 340)) then sat='b'
;           if (datatype(sat) EQ 'UND') then sat='a';default
;        endif
        rs=30*.696e6  
        tss=t0+rs/vr
        place=get_stereo_lonlat(string(utc2str(tai2utc(tss))),string(sat),/degrees)
        b0 = place[2]*!pi/180
	theta = acos(sin(del)*sin(b0) + cos(b0)*cos(del)*cos(pa)) * 180/!pi
	phi = acos((sin(del)*cos(b0) - cos(del)*sin(b0)*cos(pa)) / sin(!pi*theta/180)) * 180/!pi
	read_names, file, file_arr
	openw, lu, file, /get_lun
	FOR i=0,n_elements(file_arr)-1 DO printf,lu,file_arr[i]
	printf,lu,'# Vr  Delta  To  Theta  Phi Ts'
	printf,lu,vr,format='(f7.2)'
	printf,lu,delta,format='(f7.2)'
	printf,lu,utc2str(tai2utc(t0)),format='(e16.10)'
	printf,lu,theta,format='(f7.2)'
	printf,lu,phi,format='(f7.2)'
	printf,lu,utc2str(tai2utc(tss)),format='(e16.10)'
	close,lu
	free_lun,lu

	ENDIF
	END

  'save_delta': BEGIN

	file = findfile('idltemp.ht')
	IF(file[0] EQ '') THEN BEGIN
		message, 'No height-time file saved currently saved'
		RETURN
	ENDIF
	file = dialog_pickfile(PATH=save_dir)
	IF(file[0] EQ '') THEN RETURN
	spawn,'cp idltemp.ht ' + file[0]
	break_file,file,vol,dir,fi,su
	save_dir=dir

	END
  'crop_mode': IF(datatype(h) NE 'UND') THEN BEGIN
	IF(Event.Select) THEN sel = 1 ELSE sel = 0
	CASE Event.Value OF
	0: BEGIN
		save_region[0] = sel
		IF(save_region[0]) THEN BEGIN
			save_region[1] = 0
			WIDGET_CONTROL, plot_fields[10], SET_VALUE=' Cropping Left'
		ENDIF ELSE WIDGET_CONTROL, plot_fields[10], SET_VALUE='              '
		END
	ENDCASE
	redisplay, newmap
	ENDIF
  'use_prev': IF(datatype(h) NE 'UND') THEN BEGIN
	IF(datatype(crop_hdr) EQ 'UND') THEN print, '%TOOL: No previous time interval saved' $
	ELSE BEGIN
		time1 = crop_hdr.start_time > start_time
		time2 = crop_hdr.end_time < end_time
		IF(time1 GE end_time OR time2 LE start_time) THEN BEGIN
			print, '%TOOL: previous and current time intervals do not overlap'
			RETURN
		ENDIF
		save_region[2] = floor(h.nx * float(time1-start_time) / (end_time-start_time)) > 0 < (h.nx-1)
		save_region[3] = floor(h.nx * float(time2-start_time) / (end_time-start_time)) > 0 < (h.nx-1)
		redisplay, newmap
	ENDELSE
	ENDIF
  'reset_crop': IF(datatype(h) NE 'UND' && save_region[0]) THEN BEGIN
	save_region[1] = 0
	save_region[2] = 0
	save_region[3] = h.nx-1
	save_region[4] = 0
	save_region[5] = h.ny-1
	WIDGET_CONTROL, plot_fields[10], SET_VALUE=' Cropping Left'
	redisplay, newmap
	ENDIF
  'ps_add': IF(datatype(h) NE 'UND') THEN BEGIN
	crop_map, crop_hdr, PIXELS=cmap
	break_file, h.filename, disk, dir, name, ext
	IF(strpos(dir,'edits/') LT 0) THEN dir = dir + 'edits/'
	newpath = dir + name + '_crop' + ext
	write_jmap2a, cmap, newpath, crop_hdr
	files = [files, newpath]
	for i=0,n_elements(files)-1 DO print,'FILES[',trim(i),']=',files[i]
	ENDIF
  'ps_remove': IF(datatype(h) NE 'UND') THEN BEGIN
	nf = n_elements(files)
	IF(nf GT 1) THEN BEGIN
		last = files[nf-1]
		files = files[0:nf-2]
		spawn,'/bin/rm ' + last
	for i=0,n_elements(files)-1 DO print,'FILES[',trim(i),']=',files[i]
	ENDIF
	ENDIF
  'ps_preview': IF(datatype(h) NE 'UND') THEN BEGIN
	WINDOW, 0, xsize = 460, ysize = 600
	MULTIDISPLAY2a, 'PREVIEW'
	ENDIF
  'ps_print': IF(datatype(h) NE 'UND') THEN BEGIN
	dpi=1
	IF(n_elements(files) LE 1) THEN print, '%TOOL: No maps currently in file' $
	ELSE MULTIDISPLAY2a, 'PRINT'
	ENDIF
  'ps_save': IF(datatype(h) NE 'UND') THEN BEGIN
        if strpos(event.value,'dpi') gt -1 then dpi=fix(strmid(event.value,0,strpos(event.value,'dpi'))) else dpi=1
	IF(n_elements(files) LE 1) THEN print, '%TOOL: No maps currently in file' $
	ELSE MULTIDISPLAY2a, 'SAVE'
	ENDIF
  'dist_unit': BEGIN
	units[0] = event.index
	redisplay, newmap
	END
  'vel_unit': BEGIN
	max_vel = [10.0, 4.0, 2000.0]  ; Rsun/hr, deg/hr, km/s
	gauge_vel = gauge_vel * max_vel[event.index] / max_vel[units[1]]
	units[1] = event.index
	WIDGET_CONTROL, unit_fields[4], SET_VALUE=[gauge_vel, -max_vel[units[1]], max_vel[units[1]]]
	redisplay, newmap
	END
  'gauge_vel': BEGIN
	gauge_vel = event.value
	redisplay, newmap
	END
  'gauge_show': BEGIN
	vel_mode = event.select ? 1 : 0
	redisplay, newmap
	END
  'dev_button':
  'dev_factor':
  'point_button':
  'point_size':
  'point_iter':
  'chop_button':
  'chop_tol':
  'denoise_button':
  'denoise_coeff':
  'denoise_tol':
  'smooth_button':
  'smooth_size':
  'load': BEGIN
	PRINT, START_STR
	filename = DIALOG_PICKFILE(TITLE='Load jMap', PATH=jmap_dir, FILTER = '*.jmp',/MULTIPLE_FILES)
	IF(datatype(filename) NE 'UND' AND filename[0] NE '') THEN BEGIN
	load_map, filename[0], /reset
	movie_files = filename
	break_file, filename[0], disk, dir, name, ext
	IF(strpos(dir,'edits/') LT 0) and ~(is_dir(dir+'edits')) THEN BEGIN
		spawn, 'mkdir ' + dir + 'edits/'
		spawn, 'chmod g+w ' + dir + 'edits/'
	ENDIF
	jmap_dir=dir
	
	WIDGET_CONTROL, reg_fields[10], SET_SLIDER_MIN=0, SET_SLIDER_MAX=n_elements(movie_files)-1, SET_VALUE=0
    	ENDIF
	END
  'save': IF(datatype(h) NE 'UND') THEN BEGIN
	crop_map, crop_hdr, PIXELS=save_map
	write_jmap2a, save_map, h.filename, crop_hdr
	ENDIF
  'save_as': BEGIN
    	IF(datatype(h) NE 'UND') THEN BEGIN
	    IF n_elements(files) LE 1 THEN BEGIN
		crop_map, crop_hdr, PIXELS=cmap
		break_file, h.filename, disk, dir, name, ext
		IF(strpos(dir,'edits/') LT 0) THEN dir = dir + 'edits/'
		newpath = dir + name + '_crop' + ext
		write_jmap2a, cmap, newpath, crop_hdr
		files = [files, newpath]
		for i=0,n_elements(files)-1 DO print,'FILES[',trim(i),']=',files[i]
	    ENDIF	   
	   
	    window,0,xsize=800,ysize=68*2 + nimrows*464
	    MULTIDISPLAY2a, 'GIF'
	ENDIF
    	END
  'save_dat': BEGIN
	datfilename = DIALOG_PICKFILE(PATH=save_dir, TITLE='Save jMap', FILTER = '*.dat')
	IF(datfilename NE '') THEN BEGIN
	    crop_map, crop_hdr, PIXELS=save_map
	    OPENW, lu, datfilename, /GET_LUN
	    WRITEU, lu, BYTSCL(save_map)
	    CLOSE, lu
	    FREE_LUN, lu
	    xstr = STRTRIM(STRING(crop_hdr.nx),2)
	    ystr = STRTRIM(STRING(crop_hdr.ny),2)
	    start_doy = STRTRIM(STRING(UTC2DOY(ANYTIM2UTC(h.start_time),/FRAC)),2)
	    end_doy = STRTRIM(STRING(UTC2DOY(ANYTIM2UTC(h.end_time),/FRAC)),2)
	    PRINT, str, 'Map size: ',xstr,' by ',ystr
	    PRINT, str, 'File saved as ',datfilename,'.'  
	    PRINT, str, 'Starting Day of Year: ',start_doy
	    PRINT, str, 'Ending Day of Year:   ',end_doy 
	    break_file,datfilename,vol,dir,fi,su
	    save_dir=dir
	ENDIF
	END
  'interface':BEGIN
	IF(file_test(concat_dir(getenv('HOME'),'syncjmapwithmovie.dat')) GT 0) THEN BEGIN
		temp=fltarr(3)
		OPENR,lun,concat_dir(getenv('HOME'),'syncjmapwithmovie.dat'),/get_lun
		READF,lun,temp
		free_lun,lun
		tempangs=[0,10.]
		posang=temp[2]
		FOR i=0, n_elements(movie_files)-1 DO BEGIN ;find correct position angle
			tempmap=read_jmap2a(movie_files[i],HEADER=h,/nodata)
			tempdiff=ABS(posang-h.pa)
			IF(tempdiff LT tempangs[1]) THEN tempangs=[i,tempdiff]
		ENDFOR
		IF(tempangs[1] EQ 10) THEN print, 'No jMap with p.a. within 10 degrees'$
		ELSE BEGIN
		xsize = h.nx * xscale
  		ysize = h.ny * yscale
		time=(temp[0]-start_time)*xsize/(end_time-start_time)
		height=(temp[1]-h.min_r)*ysize/(h.max_r-h.min_r)
		mvi_point={time:time,height:height,posang:posang}
		load_map,movie_files[tempangs[0]]
		WIDGET_CONTROL,reg_fields[10],set_value=tempangs[0]
		ENDELSE
	ENDIF ELSE print,'%% Point data does not exist'
	END
  'remove_pnt': BEGIN
	undefine,mvi_point
	redisplay,newmap
	END
  'insitu':jmap_in_situ,movie_files[movie_frame],/getang
  'quit': BEGIN
	undefine, h
	undefine, map
	undefine, newmap
	undefine, opts
	undefine, newopts
	undefine, reg_fields
	undefine, scale_fields
	undefine, coord_fields
	undefine, plot_fields
	undefine, ps_fields
	undefine, unit_fields
	undefine, dev_fields
	undefine, point_fields
	undefine, chop_fields
	undefine, denoise_fields
	undefine, smooth_fields
	undefine, file_fields
	undefine, sync_fields
	undefine, mvi_point
	WIDGET_CONTROL, MAIN1, /DESTROY
	WHILE !D.WINDOW GE 0 DO WDELETE
	nf = n_elements(files)
	FOR i=1,nf-1 DO spawn,'/bin/rm ' + files[i]
	PRINT, START_STR
	END
  ELSE:
  ENDCASE
END


; DO NOT REMOVE THIS COMMENT: END MAIN1
; CODE MODIFICATIONS MADE BELOW THIS COMMENT WILL BE LOST.



PRO tool2a, filename, GROUP=Group, ARROW_CURSOR=arrow_cursor

COMMON Tool2_Common
COMMON WIDGET_ID
common PM1
COMMON DIR_COMMON
  ;******
  undefine, newmap
  prevmode=2
  edit_mode = -1
  busy = 0
  xscale = 1.0
  yscale = 1.0
  curr_pix = [0,0]
  ;for clicked-path height/time storage
  ht_struct = {ht, plot_num: -1, time: -1.0, height: 0.0}		
  hts = REPLICATE(ht_struct, 1)
  vels = 0
  plotted = 0
  draw_mode = 1
  vel_mode = 0
  gauge_vel = 0.0

    ;IF keyword_set(ARROW_CURSOR) THEN BEGIN
    	print,'Using arrow for cursor instead of crosshair. Position is under the edge of arrow tip.'
	device,/CURSOR_ORIGINAL   	; uses arrow pointer
	wdelete				; nbr, 8/8/08 - remove window from device command
    ;ENDIF

;** save_region: to store crop region for saving purposes--
;** 1st entry is boolean, whether in crop mode; 2nd is bound currently being edited (left,right,bottom,top)
;** other four are x1, y1, x2, y2 of crop region
  save_region = intarr(6)

  ;for PostScript layouts
  nimrows = 1
  nimcols = 1
  ximsize = 6.0
  yimsize = 3.0
  margins = 0.25
  borders = [.6, .6, 1.25, 1.25]   ; left, right, bottom, top
  curr_x = ximsize
  curr_y = yimsize
  files = ''
  movie_frame = 0
  units = [1,2]

  IF(DATATYPE(opts) EQ 'UND') THEN opts = default_opt_strct()

  IF N_ELEMENTS(Group) EQ 0 THEN GROUP=0
  junk   = { CW_PDMENU_S, flags:0, name:'' }


  MAIN1 = WIDGET_BASE(GROUP_LEADER=Group, COLUMN=1, MAP=1, TITLE='jMap Tool2', UVALUE='MAIN1')

  draw_base = WIDGET_BASE(MAIN1, COLUMN=1, MAP=1, TITLE='display', UVALUE='draw_base')

  draw6 = WIDGET_DRAW(draw_base, FRAME=3, RETAIN=2, UVALUE='disp_window', X_SCROLL_SIZE=1000, $
      Y_SCROLL_SIZE=256, XSIZE = 1001, YSIZE = 257, EVENT_PRO='DRAW_COORDS', /MOTION_EVENTS, /BUTTON_EVENTS)

  reg_base = WIDGET_BASE(MAIN1, ROW=1, MAP=1, TITLE='mode', UVALUE='reg_base')

	reg_fields = WIDGET_BUTTON(reg_base, UVALUE='prev_reg', VALUE='Previous', XSIZE=80, YSIZE=30)
	reg_fields = replicate(reg_fields, 12)
	reg_fields[1] = WIDGET_BUTTON(reg_base, UVALUE='next_reg', VALUE='Next', XSIZE=80, YSIZE=30)
	reg_fields[2] = WIDGET_BUTTON(reg_base, UVALUE='all_reg', VALUE='All', XSIZE=80, YSIZE=30)
	reg_fields[3] = WIDGET_BUTTON(reg_base, UVALUE='get_opts', VALUE='Recall', XSIZE=80, YSIZE=30)
	reg_fields[4] = WIDGET_BUTTON(reg_base, UVALUE='set_opts', VALUE='Set', XSIZE=80, YSIZE=30)
	reg_fields[5] = WIDGET_BUTTON(reg_base, FRAME=3, UVALUE='process_button', VALUE='Process', XSIZE=120, YSIZE=40)
	reg_fields[6] = WIDGET_BUTTON(reg_base, UVALUE='reset', VALUE='Reset JMap', XSIZE=80, YSIZE=30)
	reg_fields[7] = WIDGET_LABEL(reg_base, VALUE='Editing All Regions')
	reg_fields[8] = CW_BGROUP(reg_base, ['Show Lines'], UVALUE='draw_mode', /NONEXCLUSIVE, SET_VALUE=[1])

  mov_base = WIDGET_BASE(MAIN1, ROW=1, MAP=1, UVALUE='mov_base')

	reg_fields[9] = WIDGET_BUTTON(mov_base, UVALUE='run_movie', VALUE='Run Movie')
	reg_fields[10] = WIDGET_SLIDER(mov_base, UVALUE='movie_frame', MINIMUM=0, MAXIMUM=1, VALUE=0, XSIZE=140, /DRAG)
	reg_fields[11] = WIDGET_BUTTON(mov_base, UVALUE='process_all', VALUE='Process All')

  scale_base = WIDGET_BASE( MAIN1, ROW=1, MAP=1, UVALUE='scale_base')

	scale_fields = WIDGET_LABEL(scale_base, VALUE='Scale')
	scale_fields = replicate(scale_fields, 5)
	scale_fields[1] = CW_FSLIDER(scale_base, MINIMUM=0.0, MAXIMUM=2.0, VALUE=1.0, UVALUE='scalex', $
		XSIZE=200, SCROLL=.005, /DRAG)
	scale_fields[2] = CW_FSLIDER(scale_base, MINIMUM=0.0, MAXIMUM=2.0, VALUE=1.0, UVALUE='scaley', $
		XSIZE=200, SCROLL=.005, /DRAG)
	scale_fields[3] = WIDGET_BUTTON(scale_base, UVALUE='resize', VALUE='Resize to Fit')

  coord_base = WIDGET_BASE( MAIN1, ROW=1, MAP=1, UVALUE='coord_base')
	coord_fields = WIDGET_LABEL(coord_base, VALUE='Pos. Angle:     ')	
	coord_fields = replicate(coord_fields, 6)
	coord_fields[1] = WIDGET_LABEL(coord_base, VALUE='Total span (deg):         ')
	coord_fields[2] = WIDGET_LABEL(coord_base, VALUE='Total time (hr):          ')  
	coord_fields[3] = WIDGET_LABEL(coord_base, VALUE='Pixel value:                                      ')
	coord_fields[4] = WIDGET_LABEL(coord_base, VALUE='Pixel coordinates:               ')
 	scale_fields[4]=WIDGET_LABEL(scale_base, VALUE='            ') ;to shift over Satellite label for nicer appearance
	coord_fields[5] = WIDGET_LABEL(scale_base, VALUE='Satellite:         ')

  plot_base = WIDGET_BASE(MAIN1, ROW=1, MAP=1, UVALUE='plot_base')

	plot_fields = WIDGET_LABEL(plot_base, VALUE='Trajectory:  ')
	plot_fields = REPLICATE(plot_fields, 13)
	plot_fields[1] = WIDGET_BUTTON(plot_base, UVALUE='calc', Value='Plot Data')
	plot_fields[2] = WIDGET_BUTTON(plot_base, UVALUE='remove', VALUE='Remove Last')
	plot_fields[3] = WIDGET_BUTTON(plot_base, UVALUE='remove_all', VALUE='Remove All')
	plot_fields[4] = WIDGET_BUTTON(plot_base, UVALUE='save_plot', VALUE='Save Plots')
	plot_fields[5] = WIDGET_BUTTON(plot_base, UVALUE='hide_plot', VALUE='Hide Plot')
	plot_fields[6] = WIDGET_BUTTON(plot_base, UVALUE='plot_delta', VALUE='Run WAVE_DIR')
	plot_fields[12] = WIDGET_BUTTON(plot_base, UVALUE='run_wgraph', VALUE='Run WGraph')
	plot_fields[11] = WIDGET_BUTTON(plot_base, UVALUE='save_delta', VALUE='Save Fit')
	plot_fields[7] = CW_BGROUP(plot_base, ['Crop Mode'], /NONEXCLUSIVE, UVALUE='crop_mode')
	plot_fields[8] = WIDGET_BUTTON(plot_base, UVALUE='use_prev', VALUE='Use Previous')
	plot_fields[9] = WIDGET_BUTTON(plot_base, UVALUE='reset_crop', VALUE='Revert to Full')
	plot_fields[10] = WIDGET_LABEL(plot_base, VALUE='                ')

  ps_base = WIDGET_BASE(MAIN1, ROW=1, MAP=1, UVALUE='ps_base')

	ps_fields = WIDGET_LABEL(ps_base, VALUE='PostScript File: ')
	ps_fields = replicate(ps_fields, 14)
	ps_fields[1] = WIDGET_LABEL(ps_base, VALUE='   Rows')
	ps_fields[2] = WIDGET_TEXT(ps_base, UVALUE='ps_rows', VALUE='1', /EDITABLE, XSIZE=5)
	ps_fields[3] = WIDGET_LABEL(ps_base, VALUE='Columns')
	ps_fields[4] = WIDGET_TEXT(ps_base, UVALUE='ps_cols', VALUE='1', /EDITABLE, XSIZE=5)
	ps_fields[5] = WIDGET_BUTTON(ps_base, UVALUE='ps_add', VALUE='Add Map')
	ps_fields[6] = WIDGET_BUTTON(ps_base, UVALUE='ps_remove', VALUE='Remove Last')
	ps_fields[7] = WIDGET_BUTTON(ps_base, UVALUE='ps_preview', VALUE='Preview File')
	ps_fields[8] = WIDGET_BUTTON(ps_base, UVALUE='ps_print', VALUE='Print File')

        desc = ['1,\Save File','0\Full Res','0\1200dpi', '0\800dpi','0\400dpi']
	ps_fields[9] = CW_PDMENU(ps_base, desc, UVALUE='ps_save', /RETURN_NAME)
	;ps_fields[9] = WIDGET_BUTTON(ps_base, UVALUE='ps_save', VALUE='Save File')

	ps_fields[10] = WIDGET_LABEL(ps_base, VALUE='Width(in): ')
	ps_fields[11] = WIDGET_TEXT(ps_base, UVALUE='ps_width', VALUE=strtrim(string(ximsize),2), XSIZE=8, /EDITABLE)
	ps_fields[12] = WIDGET_LABEL(ps_base, VALUE='Height(in): ')
	ps_fields[13] = WIDGET_TEXT(ps_base, UVALUE='ps_height', VALUE=strtrim(string(yimsize),2), XSIZE=8, /EDITABLE)

  unit_base = WIDGET_BASE(MAIN1, ROW=1, MAP=1, UVALUE='unit_base')

	unit_fields = WIDGET_LABEL(unit_base, UVALUE='unit_label', VALUE='Physical Units: ')
	unit_fields = replicate(unit_fields, 6)

	unit_fields[1] = WIDGET_DROPLIST(unit_base, UVALUE='dist_unit', VALUE=['Solar Radii', 'Degrees','Kilometers'])
	unit_fields[2] = WIDGET_DROPLIST(unit_base, UVALUE='vel_unit', VALUE=['Rsun / Hr', 'Deg / Hr', 'Km / sec'])
	WIDGET_CONTROL, unit_fields[1], SET_DROPLIST_SELECT=units[0]
	WIDGET_CONTROL, unit_fields[2], SET_DROPLIST_SELECT=units[1]
	unit_fields[3] = WIDGET_LABEL(unit_base, UVALUE='vel_label', VALUE='Gauge Speed: ')
	unit_fields[4] = CW_FSLIDER(unit_base, UVALUE='gauge_vel', MINIMUM=-2000.0, MAXIMUM=2000.0, VALUE=0.0, XSIZE=200, /drag, SCROLL=5)
	unit_fields[5] = CW_BGROUP(unit_base, UVALUE='gauge_show', ['Draw Line'], /NONEXCLUSIVE, SET_VALUE=[0])
	units[0] = WIDGET_INFO(unit_fields[1], /DROPLIST_SELECT)
	units[1] = WIDGET_INFO(unit_fields[2], /DROPLIST_SELECT)

  process_base = WIDGET_BASE(MAIN1, ROW=1, FRAME=5, MAP=1, TITLE='process', UVALUE='process_base')

  dev_base = WIDGET_BASE(process_base, COLUMN=1, FRAME=1, MAP=1, TITLE='dev_base', UVALUE='dev_base')

	dev_fields = CW_BGROUP(dev_base, ['Std. Dev. Filter'], ROW=1, NONEXCLUSIVE=1, UVALUE='dev_button')
	dev_fields = replicate(dev_fields, 2)
	dev_fields[1] = CW_FIELD(dev_base, VALUE='1.0', /ROW, /FLOAT, /RETURN_EVENTS, TITLE='Factor', $
		UVALUE='dev_factor', XSIZE = 6)

  point_base = WIDGET_BASE(process_base, COLUMN=1, FRAME=1, MAP=1, TITLE='point_base', UVALUE='point_base')

	point_fields = CW_BGROUP(point_base, ['Point Filter'], ROW=1, NONEXCLUSIVE=1, UVALUE='point_button')
	point_fields = replicate(point_fields, 4)
	point_fields[1] = CW_FIELD(point_base, VALUE='3', ROW=1, INTEGER=1, /RETURN_EVENTS, TITLE='Box Size', $
		UVALUE='point_size', XSIZE=10)
	point_fields[2] = CW_FIELD(point_base, VALUE='5', ROW=1, INTEGER=1, /RETURN_EVENTS, TITLE='Tolerance', $
		UVALUE='FIELD30', XSIZE=10)
	point_fields[3] = CW_FIELD(point_base, VALUE='1', ROW=1, INTEGER=1, /RETURN_EVENTS, TITLE='Iterations', $
		UVALUE='point_iter', XSIZE=10)

  chop_base = WIDGET_BASE(process_base, COLUMN=1, FRAME=1, MAP=1, TITLE='chop_base', UVALUE='chop_base')

	chop_fields = CW_BGROUP(chop_base, ['Chop'], ROW=1, /NONEXCLUSIVE, UVALUE='chop_button')
	chop_fields = replicate(chop_fields, 2)
	chop_fields[1] = CW_FIELD(chop_base, VALUE='5.0', ROW=1, FLOAT=1, RETURN_EVENTS=1, TITLE='Tolerance', $
		UVALUE='chop_tol', XSIZE=8)

  denoise_base = WIDGET_BASE(process_base, COLUMN=1, FRAME=1, MAP=1, TITLE='denoise_base', UVALUE='denoise_base')

	denoise_fields = CW_BGROUP(denoise_base, ['Denoise'], ROW=1, NONEXCLUSIVE=1, UVALUE='denoise_button')
	denoise_fields = replicate(denoise_fields, 3)
	denoise_fields[1] = CW_FIELD(denoise_base, VALUE='4', ROW=1, INTEGER=1, RETURN_EVENTS=1, TITLE='Coeff', $
		UVALUE='denoise_coeff', XSIZE=6)
	denoise_fields[2] = CW_FIELD(denoise_base, VALUE='0.5', ROW=1, FLOAT=1, RETURN_EVENTS=1, TITLE='Tolerance', $
		UVALUE='denoise_tol', XSIZE=10)

  smooth_base = WIDGET_BASE(process_base, COLUMN=1, FRAME=1, MAP=1, TITLE='smooth_base', UVALUE='smooth_base')

	smooth_fields = CW_BGROUP(smooth_base, ['Smooth'], ROW=1, NONEXCLUSIVE=1, UVALUE='smooth_button', SET_VALUE=0)
	smooth_fields = replicate(smooth_fields, 2)
	smooth_fields[1] = CW_FIELD(smooth_base, VALUE='5', ROW=1, INTEGER=1, RETURN_EVENTS=1, TITLE='Size', $
		UVALUE='smooth_size', XSIZE=10)
	
  sync_base = WIDGET_BASE(process_base, Column=1, FRAME=1, MAP=1, TITLE='sync_base', UVALUE='smooth_base')
	sync_fields = WIDGET_LABEL(sync_base, VALUE='Sync with Movie')
	sync_fields=replicate(sync_fields,3)
	sync_fields[1] = WIDGET_BUTTON(sync_base, UVALUE='interface', VALUE='Sync')
	sync_fields[2] = WIDGET_BUTTON(sync_base, UVALUE='remove_pnt', VALUE='Remove') 

  file_base = WIDGET_BASE(MAIN1, ROW=1, SPACE=20, FRAME=3, MAP=1, TITLE='file', UVALUE='file_base')

	file_fields = WIDGET_BUTTON(file_base, UVALUE='load', VALUE='LOAD', XSIZE=80, YSIZE=30)
	file_fields = replicate(file_fields, 6)
	;file_fields[1] = WIDGET_BUTTON(file_base, UVALUE='save', VALUE='Save')
	file_fields[2] = WIDGET_BUTTON(file_base, UVALUE='save_as', VALUE=' Save Plot As GIF ')
	;file_fields[3] = WIDGET_BUTTON(file_base, UVALUE='save_dat', VALUE='Save to .DAT')
	file_fields[5] = WIDGET_BUTTON(file_base, UVALUE='insitu', VALUE='Get In-situ Data')
	file_fields[4] = WIDGET_BUTTON(file_base, UVALUE='quit', VALUE='Quit')

  WIDGET_CONTROL, MAIN1, /REALIZE

  ; Get drawable window index

  WIDGET_CONTROL, DRAW6, GET_VALUE=DRAW6_Id

  IF(datatype(filename) NE 'UND') THEN BEGIN
	load_map, filename[0], /reset
	movie_files = filename
	break_file, filename[0], disk, dir, name, ext
	jmap_dir=dir
	IF(strpos(dir,'edits/') LT 0) THEN BEGIN
		spawn, 'mkdir ' + dir + 'edits/'
		spawn, 'chmod g+w ' + dir + 'edits/'
	ENDIF
	
	WIDGET_CONTROL, reg_fields[10], SET_SLIDER_MIN=0, SET_SLIDER_MAX=n_elements(movie_files)-1, SET_VALUE=0
  ENDIF
  
  XMANAGER, 'MAIN1', MAIN1

END
