; Copyright (c) 1998-2008 A.P. Hitchcock  All rights reserved
;+
;NAME:
;		PLOTBUF
;
;LAST CHANGED: -----------------------------------  15-Jun-08
;
; PURPOSE:
;	This procedure plots AXIS structure format data (1d, 2d, 3d, 4d)
; where 1d are y(x) - typically spectral or profile plots
;		2d are z(x,y) - images
;		3d are images without own (x,y) scales,
;			typically standard format images (jpg etc) with own color scales
;		4d are f(x,y,z) 3-d volume data (e.g. stacks) (not yet implemented)
;
; CATEGORY:
;	Image display. AXIS captive
;
; CALLING SEQUENCE:
; 	PLOTBUF, BufNum, Zvalues = Zvalues, same_scale=same_scale, _extra=e
;
; INPUTS:
;	BUFNUM	Number of AXIS buffer to plot
;           (0-9 are standard; 10 thumbnail composite)
;
; KEYWORDS:
;	ZVALUES:	[zmin, zmax] to allow forcing Z-range
;	SAME_SCALE:	switch if set, keeps same (x,y) scale as in prior plot
;	_EXTRA:		other paramaters to pass to splot, splot2d etc
; 	Note - many other plot paramaters are passed via axis_com variables
;
; OUTPUTS:
;	plot on MainImg window in aXis2000
;
; COMMON BLOCKS:
;	AXIS_COM	standard set of common blocks
;
; MODIFICATION HISTORY:
; (07-aug-97 aph) - generates MainImg plot using SPLOT or SPLOT2D
;				    updates buffer labels; updates thumbnails
; (28-dec-97 aph) - added '3d' type = tif, gif, etc image
; (12-apr-98 aph) - added '4d' type = (E,distance) plot (line scans)
; (19-jun-98 aph) - split out of AXIS_C for code space reasons
; (28-Dec-98 aph) - Zmin, Zmax for 2d plots
; (03-Jan-99 aph) - Zmin, Zmax for 1d plots
; (08-Jan-99 aph) - add 5% top/bottom margin for 1d plots
; (25-Jun-99 aph) - try for consistent image/spectra color table
; (29-jun-99 aph) - adapt 'FIRST_PLOT' to set user-selected colors;
;                 - type = '3d' uses internal color tables
; (04-jul-99 aph) - search for color scale error on image -> spectra
; (06-jul-99 aph) - correct image plotting to preserve orientation of (x,y) scales (forced increasing)
; (08-jul-99 aph) - only redo thumbs if CurBuf NE 0; update labels though !
; (13-jul-99 aph) - thumb_plot reset for any use of PlotBuf; add same_scale keyword
; (26-jul-99 aph) - leave all decisions about updating Thumbs and Labels to ThumbLbs
; (12-aug-99 aph) - kluge fix 'relax to white background' problem
; (19-sep-99 aph) - change first to first_plot (common conflict); ax_wait
; (28-oct-99 aph) - update Zmin, Zmax on plot
; (16-nov-99 aph) - implement color bar, gamma for image Z-scales; X,Y controls
; (19-nov-99 aph) - do not clear axis communication box
; (31-jan-00 aph) - reactivate 3d as a simple 'transcribe' for images
; (16-apr-00 aph) - add TRUE=1 to corrctly display 3-channel images (3,x,y)
; (30-nov-00 cgz) Replaced call of wdivide with explicit !p.multi statement
; (19-dec-00 cgz) substituted ax_white_color_index with ax_plot_axes_color_index
;			substituted ax_black_color_index with ax_plot_bkgd_color_index
;			commented out !p.background statement
; (30-dec-00 aph) corrected placement of make_square to get line-outs right
;				Zrange larger/smaller than data size implemented
;				AXIS standard header added
; (06-oct-01 aph) sensitive for G_lbl
; (28-dec-01 aph) blank out pixel display when clearing from 2d display
; (17-feb-02 aph) add scale bar and size
; (29-apr-02 aph) nm bar if less than 1 um; not thick
; (12-may-02 aph) correct header name format
; (22-mar-06 aph) increase character size
; (22-dec-07 aph) remove date, time
; (15-jun-08 aph) ignore NaN and Infinities when setting plot ranges
;-

PRO PlotBuf, BufNum, Zvalues = Zvalues, same_scale=same_scale, _extra=e

@axis_com
on_error,2

XYZ_format = '(g10.3)'    ; format for limit control boxes
CurBuf=Bufnum
Thumb_plot = 0
HANDLE_VALUE, Data(CurBuf),tmp	;Retrieve data from handle
IF n_tags(tmp) NE 0 THEN BEGIN  ;Check if there is any data in the handle
	SetGraf, 'XZPlot' & erase 	; erase the line-out windows
	SetGraf, 'YZPlot' & erase
	SetGraf, 'MainImg'  ; ensure main screen is the draw window
	!p.multi=[0, 1, 1] 	; reset after multi-plot display (zoom~thumbails)
	ax_wait				; change cursor to an hourglass
	if First_Plot EQ 1 THEN BEGIN
		TVLCT, UserR, UserB, UserG	; load current user-defined color table
		ax_color					; establish special colors at the top
		First_Plot = 0
	  endif
	  !p.charsize=0.7
	  if NOT keyword_set(same_scale) then begin
		  !x.range=0 				;Reset the zoom to force autoscaling
		  !y.range=0
	  endif
; ------- (22-dec-07 aph)  removed addition of time & date from the header ------------------
	  Label(CurBuf) = tmp.dl      ; save Label info (at read-in)
	  tmp.dl = Label(CurBuf) ; + '    ' + strmid(systime(0),11,8) + '  '+strmid(systime(0),8,2)+'-'+strmid(systime(0),4,3) + '-'+strmid(systime(0),20,4)

; --------- (4d is saved for volume data; now just treat as a 2d image (aph 4-jul-99)
	  if tmp.t EQ '4d' then begin
	  	tmp = {t:'2d', d:tmp.di, x:tmp.xi, y:tmp.y, xl:tmp.xl, yl:tmp.yl, dl:tmp.dl}
	  endif

	  CASE tmp.t OF     ; check the TYPE
; ------------ '3d' are images without (x,y) scales -------------------
	  '3d': BEGIN
	 ; ------------ plot 1-channel (with RGB) and 3-channel ('true color') images ---
	 ;  typically from *.TIF or *.BMP files (IDL 5.2 does not support 3-channel gif)
	 	erase, ax_plot_bkgd_color_index		;ax_black_color_index
	 	ax_colorbar, /destroy
	 	ts = size(tmp.d)	; determine of 3-channel or 1-channel
	 	main = 360*gr_scale
	 	if ts(0) EQ 3 then begin	;image is true color (3-channel); assume pixel interleaved
		 	t_scl = main/max([ts(2),ts(3)])
		 	nx = fix(t_scl*ts(2))   &  ny = fix(t_scl*ts(3))
		 	t_image = intarr(3, nx, ny)
		 	for i=0,2 do $
		 		t_image(i,*,*) = congrid(reform(tmp.d(i,*,*)),nx, ny, /interp)
		 	tvlct, tmp.R, tmp.G, tmp.B
		 	tv, t_image, /true
	 	endif else begin	; image is 1-d with R,G,B maps
		 	t_scl = main/max([ts(1),ts(2)])
		 	nx = fix(t_scl*ts(1))   &  ny = fix(t_scl*ts(2))
	 		t_image = congrid(tmp.d, nx, ny, /interp)
	    	tvscl, t_image  ;ax_imscl(tmp.d)
		endelse
		first_plot = 1
	    Last_Img = 1
		WIDGET_CONTROL, Zmin, sensitive = 0
	  	WIDGET_CONTROL, Zmax, sensitive = 0
	  	WIDGET_CONTROL, G_slider, sensitive = 0
	  	WIDGET_CONTROL, G_lbl, sensitive = 0
		WIDGET_CONTROL, /CLEAR_events
	 END
; ------------- 2d are IMAGE data with (x,y) scales ------------
	  '2d': BEGIN
			IF keyword_set(Zvalues) then begin
				cnt = long(0) & index = lonarr(1) ; declare long for big images
				index = where(tmp.d LT Zvalues(0),cnt)		; clip at Zmin
				if cnt GT 0 THEN tmp.d(index) = Zvalues(0)
				index = where(tmp.d GT Zvalues(1),cnt)		; clip at Zmax
				if cnt GT 0 THEN tmp.d(index) = Zvalues(1)
				tmp.d(0,0) = Zvalues(0)	; kluge to allow out-of-range Z-scaling
				tmp.d(n_elements(tmp.x)-1,n_elements(tmp.y)-1) = Zvalues(1)
			ENDIF
			make_square,tmp   ; do before setting Xrng, Yrng so side plots correct
		    Xrng(0) = tmp.x(0)  & Xrng(1) = tmp.x(n_elements(tmp.x)-1)
		    Yrng(0) = tmp.y(0)  & Yrng(1) = tmp.y(n_elements(tmp.y)-1)
		   	splot2d, tmp
		    Xscl(CurBuf,*) = !X.S
		   	Yscl(CurBuf,*) = !Y.S
		   	Zscl(CurBuf,*) = !Z.S
		   	Last_Img = 1				; paramater to identify last plot was an image
			IF NOT keyword_set(Zvalues) then begin
				zvalues = fltarr(2)
			    Zvalues(0) = min(tmp.d, /nan)
			    Zvalues(1) = max(tmp.d, /nan)
			ENDIF
		   	Zrng = Zvalues    ; DO NOT default to 0 as Z-min
			WIDGET_CONTROL, XXmin, Set_Value=string(Xrng(0),format=XYZ_format)
		   	WIDGET_CONTROL, XXmax, Set_Value=string(Xrng(1),format=XYZ_format)
			WIDGET_CONTROL, YYmin, Set_Value=string(Yrng(0),format=XYZ_format)
		   	WIDGET_CONTROL, YYmax, Set_Value=string(Yrng(1),format=XYZ_format)
			WIDGET_CONTROL, Zmin, Set_Value=string(Zvalues(0),format=XYZ_format)
		   	WIDGET_CONTROL, Zmax, Set_Value=string(Zvalues(1),format=XYZ_format)
			WIDGET_CONTROL, XXmin, sensitive = 1
		  	WIDGET_CONTROL, XXmax, sensitive = 1
			WIDGET_CONTROL, YYmin, sensitive = 1
		  	WIDGET_CONTROL, YYmax, sensitive = 1
			WIDGET_CONTROL, Zmin, sensitive = 1
		   	WIDGET_CONTROL, Zmax, sensitive = 1
		  	WIDGET_CONTROL, G_slider, sensitive = 1
		  	WIDGET_CONTROL, G_lbl, sensitive = 1
		    SetGraf, 'MainImg', /set
		    if scale_bar then begin
		    	length = Xrng(1)-Xrng(0)
		    	test = alog10(length/10.)-floor(alog10(length/10.))
		    	bar = 2*10^(alog10(length/10.)-test)
		    	if test GT 0.3 then bar = 5*10^(alog10(length/10.)-test)
		    	if test GT 0.7 then bar = 10*10^(alog10(length/10.)-test)
		    	xlo = bar_pos(0)*length+xrng(0)
		    	xhi = xlo + bar
		    	ybar = bar_pos(1)*(Yrng(1)-Yrng(0))+Yrng(0)
		    	oplot, [xlo,xhi], [ybar,ybar], thick = 5, color = ax_white_color_index
				if bar GE 1.0 then $
		    	   xyouts, 0, 2, string(bar, format = '(I4," um")'), $
		    	   color = ax_black_color_index, /device, charthick = 1.0, charsize = 0.8 $
		    	  else xyouts, 0, 2, string(1000*bar, format = '(I4," nm")'), $
		    	   color = ax_black_color_index, /device, charthick = 1.0, charsize = 0.8
		    endif
		   	ax_colorbar
		   	WIDGET_CONTROL, /CLEAR_events
	  END
; ------- 1d is SPECTRAL data (for ONE plot only!! - use Refresh for multiple)
	'1d': BEGIN
		ResetPlots
		ax_colorbar, /destroy
		; parse the file for non-monotonic, and plot multi-section if needed
		del = tmp.x(1:*) - tmp.x(0:*)
		sect = where(del LT 0,nplot)
		IF NOT keyword_set(Zvalues) AND NOT keyword_set(same_scale) then begin
			y_ht = max(tmp.d, /nan) - min(tmp.d, /nan)  ; -------- set vertical scales
												; /nan skips NaN or Infinity values
		    Zrng(0) = min(tmp.d, /nan)-0.05*y_ht
		    Zrng(1) = max(tmp.d, /nan)+0.05*y_ht
		ENDIF
		if nplot GT 0 then begin
			PlotSect, CurBuf, AUTOSCALE=1; , split=1      ; subroutine for multi-section
			endif else begin                        ; single region plot
	; inform user of the current y-axis limits (saved in Zrng in general)
		   	splot, tmp, color=bcolor(CurBuf), charsize=0.9, thick=2, yrange = Zrng, $
		   	       xstyle=1, ystyle=1,psym=Line_sym
		endelse
		Xrng = !x.crange           ; establish range values for first plot (overplot)
		Yrng = !y.crange
		Zrng = !y.crange			; save y-vales in Zrng (used to store vertical scaling)
		Xscl(CurBuf,*) = !X.S
		Yscl(CurBuf,*) = !Y.S
		Zscl(CurBuf,*) = !Z.S
		SetGraf, 'MainImg', /SET
		wset, YZPlot   & erase		; blank out XZ and YZ plots
		wset, XZPlot   & erase
		wset, MainImg
		Last_Img = 0
		WIDGET_CONTROL, XXmin, Set_Value=string(Xrng(0),format=XYZ_format)
	   	WIDGET_CONTROL, XXmax, Set_Value=string(Xrng(1),format=XYZ_format)
		WIDGET_CONTROL, YYmin, Set_Value=string(Yrng(0),format=XYZ_format)
	   	WIDGET_CONTROL, YYmax, Set_Value=string(Yrng(1),format=XYZ_format)
		WIDGET_CONTROL, XXmin, sensitive = 1
	  	WIDGET_CONTROL, XXmax, sensitive = 1
		WIDGET_CONTROL, YYmin, sensitive = 1
	  	WIDGET_CONTROL, YYmax, sensitive = 1
		WIDGET_CONTROL, Zmin, sensitive = 0
	  	WIDGET_CONTROL, Zmax, sensitive = 0
	  	WIDGET_CONTROL, G_slider, sensitive = 0
	  	WIDGET_CONTROL, G_lbl, sensitive = 0
		tmp.dl = Label(CurBuf) ; recover label without date info
		HANDLE_VALUE, pData(0), tmp, /set   ;Put the MODIFIED data in temporary buffer 0
		WIDGET_CONTROL, /CLEAR_events
	END
	ELSE: WIDGET_CONTROL, Uprompt, SET_VALUE='Unknown data format (PlotBuf)'
	ENDCASE

	ThumbLbls  ; update thumbnails and buffer labels

ENDIF ELSE BEGIN
; otherwise, erase lineouts and MainImg
	ax_colorbar, /destroy
	Setgraf, 'XZPlot'  & ERASE
	Setgraf, 'YZPlot'  & ERASE
	Setgraf, 'MainImg' & ERASE
	WIDGET_CONTROL, XXmin, sensitive = 0
  	WIDGET_CONTROL, XXmax, sensitive = 0
	WIDGET_CONTROL, YYmin, sensitive = 0
  	WIDGET_CONTROL, YYmax, sensitive = 0
	WIDGET_CONTROL, Zmin, sensitive = 0
  	WIDGET_CONTROL, Zmax, sensitive = 0
	gamma = 1.0
    GAMMA_CT, gamma
  	WIDGET_CONTROL, G_slider, SET_value = 50
    WIDGET_CONTROL, g_lbl, SET_VALUE = STRING(gamma, format='(f5.2)')
    ax_color
  	WIDGET_CONTROL, G_slider, sensitive = 0
	WIDGET_CONTROL, G_lbl, sensitive = 0
	WIDGET_CONTROL, /CLEAR_events
	ThumbLbls        ; update thumbnails and buffer labels
ENDELSE

; in all cases reset the cursor flag and display
WIDGET_CONTROL,CursorX,SET_VALUE='   '
WIDGET_CONTROL,CursorY,SET_VALUE='   '
WIDGET_CONTROL,CursorZ,SET_VALUE='   '
WIDGET_CONTROL,PIXELX,SET_VALUE='  '
WIDGET_CONTROL,PIXELY,SET_VALUE='  '

WIDGET_CONTROL,delX,SET_VALUE='   '
WIDGET_CONTROL,delY,SET_VALUE='   '
WIDGET_CONTROL,delR,SET_VALUE='   '
WIDGET_CONTROL,delZ,SET_VALUE='   '
WIDGET_CONTROL, /CLEAR_events
click1 = 0   ; reset pattern of line generation
profl = 0    ; reset profile

ax_wait, /off
END