; Copyright (c) 1998-2006 C.G. Zomba, A.P. Hitchcock  All rights reserved
;+
; NAME:
;	ZSTACK_COLOR.PRO
;
;LAST CHANGED: ----------------------------------- 23-feb-06
;
; AUTHORS:
;	Carl G. Zimba (Photons Unlimited)
;
; PURPOSE:
;       A modal dialog widget allowing the user to specify
;       the RGB color triple specifying the color. The return
;       value of the function is the color triple.
;
; CATEGORY:
;       Graphics, Color Specification.
;
; CALLING SEQUENCE:
;       color = Zstack_PickColor(colorindex)
;
; INPUTS:
;	NONE
;
; KEYWORD PARAMETERS:
;       GROUP_LEADER: The group leader for this widget program. This
;              keyword is required for MODAL operation. If not supplied
;              the program is a BLOCKING widget. Be adviced, however, that
;              the program will NOT work if called from a blocking widget
;              program, unless a GROUP_LEADER is supplied.
;       STARTINDEX: Sixteen pre-determined colors are loaded The STARTINDEX
;              is the index in the color table where these 16 colors will
;              be loaded. By default, it is !D.Table_Size - 17.
;       TITLE: The title on the program's top-level base. By default the
;              title is "Pick a Color".
;       CANCEL: A keyword that is set to 1 if the CANCEL button is selected
;              and to 0 otherwise.
; OUTPUTS:
;	NONE
; COMMON BLOCKS:
;	zstack_color_common
;		bottom_color_index			:	index of lowermost color of gradient colorscale
;		top_color_index				:	index of uppermost color of gradient colorscale
;		black_color_index			:	index of black color
;		white_color_index			:	index of white color
;		plot_bkgd_color_index			:	color index for plot background, either black or white
;		plot_axes_color_index			:	color index for plot axes, either whilte or black
;		image_border_color_index		:	color index for image border in zstack_buildlist and zstack_profile dialog windows
;		dragbox_color_index			:	color index for dragbox used to define subregion for alignment
;		corr_ctr_color_index			:	color index for crosshair showing center of correlation function
;		corr_max_color_index			:	color index for crosshair showing maximum of correlation function
;		x_shift_color_index			:	color index for plotting of x-shift
;		y_shift_color_index			:	color index for plotting of y-shift
;		shift_cursor_color_index		:	color index for cursor in shift plot, indicating file number
;		tune_fiducial_color_index		:	color index for fiducial points in closeup of shifted image in zstack_tune dialog window
;		spectra_color_index			:	color indices (14) for plotting of spectra
;		spectra_cursor_color_index		:	color index for cursor in spectra plot, indicating x-ray energy
;		profile_color_index			:	color index for plotting of intensity profile and cursor in profile image indicating row or column
;		profile_cursor_color_index		:	color index for cursor in profile image, indicating x-ray energy
;		profile_spectrum_color_index	:	color index for plotting of profile spectrum
;		test1_color_index			:	color index #1 for testing
;		test2_color_index			:	color index #2 for testing
;		test3_color_index			:	color index #3 for testing
; SIDE EFFECTS:
;
; RESTRICTIONS:
;
; PROCEDURE:
;	Called by ZSTACK_ANALYZE.PRO (not true)
; EXAMPLE:
;
; MODIFICATION HISTORY:
;	Modified from PICKCOLOR.PRO written by David Fanning, http://www.dfanning.com
; (23-feb-06 aph) try to get working to allow selecting colors in axis
;-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Zstack_PickColor_CenterTLB, tlb

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

Device, Get_Screen_Size=screenSize
xCenter = screenSize(0) / 2
yCenter = screenSize(1) / 2
geom = Widget_Info(tlb, /Geometry)
xHalfSize = geom.Scr_XSize / 2
yHalfSize = geom.Scr_YSize / 2
Widget_Control, tlb, XOffset = xCenter-xHalfSize, $
   YOffset = yCenter-yHalfSize
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Zstack_PickColor_Select_Color, event

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

; This event handler permits color selection by clicking on a color window.
Widget_Control, event.top, Get_UValue=info, /No_Copy
   ; Get the color names from the window you clicked on.
Widget_Control, event.id, Get_UValue=thisColorName
   ; Get the color value and load it as the current color.
index = Where(info.names EQ thisColorName)
info.currentColor = index[0]
r = info.red[index]
g = info.green[index]
b = info.blue[index]
; Load the current color.
WSet, info.currentWID
PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=info.currentColor
WSet, info.newWID
PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=info.currentColor
; Update the slider values to this color value.
Widget_Control, info.redID, Set_Value=r
Widget_Control, info.greenID, Set_Value=g
Widget_Control, info.blueID, Set_Value=b
Widget_Control, event.top, Set_UValue=info, /No_Copy
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Zstack_PickColor_Sliders, event

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

; This event handler allows the user to mix their own color.
Widget_Control, event.top, Get_UValue=info, /No_Copy
   ; Get the color slider values.
Widget_Control, info.redID, Get_Value=red
Widget_Control, info.greenID, Get_Value=green
Widget_Control, info.blueID, Get_Value=blue
   ; Load the new color as the current color.
;WSet, info.currentWID
;TVLCT, red, green, blue, info.currentColor
;PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=info.currentColor
WSet, info.newWID
TVLCT, red, green, blue, info.currentColor
PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=info.currentColor
Widget_Control, event.top, Set_UValue=info, /No_Copy
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Zstack_PickColor_Buttons, event
; This event handler responds to CANCEL and ACCEPT buttons.

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

Widget_Control, event.top, Get_UValue=info, /No_Copy
Widget_Control, event.id, Get_Value=buttonValue
CASE buttonValue OF
	'Cancel' : BEGIN
		TVLCT, info.r, info.g, info.b ; Restore old color table.
		; Load the drawing colors.
		FOR j=0, bottom_color_index-1 DO BEGIN
			WSet, info.wids[j]
			PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color = j	;startIndex + j
		ENDFOR
		; Load the current color.
		WSet, info.currentWID
		PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=info.currentColor
		WSet, info.newWID
		PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=info.currentColor
		; Load the specific definition colors.
		FOR j=0,n_elements(zstack_color_def_names)-1 DO BEGIN
			WSet, info.ColorWID[j]
			PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=zstack_color_def_indices[j]
		ENDFOR
		Widget_Control, event.top, Set_UValue=info, /No_Copy
      ENDCASE
	'Accept' : BEGIN
		TVLCT, r, g, b, /Get ; Get the new color table.
		; Load the drawing colors.
		FOR j=0, bottom_color_index-1 DO BEGIN
			WSet, info.wids[j]
			PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color = j	;startIndex + j
		ENDFOR
		; Load the current color.
		WSet, info.currentWID
		PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=info.currentColor
		WSet, info.newWID
		PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=info.currentColor
		; Load the specific definition colors.
		FOR j=0,n_elements(zstack_color_def_names)-1 DO BEGIN
			WSet, info.ColorWID[j]
			PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=zstack_color_def_indices[j]
		ENDFOR
		Widget_Control, event.top, Set_UValue=info, /No_Copy
	ENDCASE
;save_color_filename_label = widget_text(buttonbase,value='',xsize=20,/editable)
;save_color_label = widget_button(buttonbase,value='Save Colors')
;read_color_label = widget_button(buttonbase,value='Read Colors')
;browse_color_label = widget_button(buttonbase,value='Browse *.clr')
;	'Save Colors' : BEGIN
;		zstack_pickcolors_save
;	END
;	'Read Colors' : BEGIN
;		zstack_pickcolors_read, color_filename
;	END
;	'Browse *.clr' : BEGIN
;		on_ioerror, browse_color_label_oops
;		cd,current=current_directory
;		dummy = dialog_pickfile(filter='*.clr', /read, /fix_filter, /must_exist, $
;				path=data_directory, get_path=data_directory, $
;				title='Select color table file (*.clr) :')
;		IF (dummy EQ '') THEN BEGIN
;			data_directory = current_directory
;				; sets data_directory to initial directory if CANCEL is chosen during dialog
;				; without this, data_directory becomes null string
;			GOTO, browse_color_label_oops
;				; trap if CANCEL is chosen in dialog
;		ENDIF
;		widget_control, save_color_filename_label, $
;				set_value = ' '+color_filename
;
;		zstack_pickcolors_read, color_filename
;
;		browse_color_label_oops :
;	END
	'Cancel All' : BEGIN
		TVLCT, info.r_old, info.g_old, info.b_old ; Restore old color table.
		; Load the drawing colors.
		FOR j=0, bottom_color_index-1 DO BEGIN
			WSet, info.wids[j]
			PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color = j	;startIndex + j
		ENDFOR
		; Load the current color.
		WSet, info.currentWID
		PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=info.currentColor
		WSet, info.newWID
		PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=info.currentColor
		; Load the specific definition colors.
		FOR j=0,n_elements(zstack_color_def_names)-1 DO BEGIN
			WSet, info.ColorWID[j]
			PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=zstack_color_def_indices[j]
		ENDFOR
		Widget_Control, event.top, Set_UValue=info, /No_Copy
      ENDCASE
	'Accept All' : BEGIN
		TVLCT, r, g, b, /Get ; Get the new color table.
		Widget_Control, event.top, /Destroy ; Exit
      ENDCASE
ENDCASE
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Zstack_PickColor_Definitions, event

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

; This event handler allows the user to mix their own color.
Widget_Control, event.top, Get_UValue=info, /No_Copy
   ; Get the color names from the window you clicked on.
definition_index = where(info.colormenuID EQ event.id)
definition_index = definition_index[0]
;print,'definition_index : ',definition_index
index = event.index - 1
;print,'*',index,event.index
WSet, info.colorWID[definition_index]
PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=index
;print,'1 zstack_color_def_indices : ', zstack_color_def_indices
CASE definition_index OF
	0 : BEGIN
		image_blgd_color_index = index
	END
	1 : BEGIN
		image_border_color_index = index
	END
	2 : BEGIN
		plot_bkgd_color_index = index
	END
	3 : BEGIN
		plot_axes_color_index = index
	END
	4 : BEGIN
		dragbox_color_index = index
	END
	5 : BEGIN
		corr_ctr_color_index = index
	END
	6 : BEGIN
		corr_max_color_index = index
	END
	7 : BEGIN
		x_shift_color_index = index
	END
	8 : BEGIN
		y_shift_color_index = index
	END
	9 : BEGIN
		shift_cursor_color_index = index
	END
	10 : BEGIN
		tune_fiducial_color_index = index
	END
	11 : BEGIN
		spectra_cursor_color_index = index
	END
	12 : BEGIN
		profile_color_index = index
	END
	13 : BEGIN
		profile_cursor_color_index = index
	END
	14 : BEGIN
		profile_spectrum_color_index = index
	END
	15 : BEGIN
		test1_color_index = index
	END
	16 : BEGIN
		test2_color_index = index
	END
	17 : BEGIN
		test3_color_index = index
	END
	ELSE : BEGIN
		print,'Unknown definition index : zstack_pickcolor'
	END
ENDCASE
zstack_color_def_indices = [	image_blgd_color_index, $
						image_border_color_index, $
						plot_bkgd_color_index, $
						plot_axes_color_index, $
						dragbox_color_index, $
						corr_ctr_color_index, $
						corr_max_color_index, $
						x_shift_color_index, $
						y_shift_color_index, $
						shift_cursor_color_index, $
						tune_fiducial_color_index, $
						spectra_cursor_color_index, $
						profile_color_index, $
						profile_cursor_color_index, $
						profile_spectrum_color_index, $
						test1_color_index, $
						test2_color_index, $
						test3_color_index	]
;print,'2 zstack_color_def_indices : ', zstack_color_def_indices

Widget_Control, event.top, Set_UValue=info, /No_Copy
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Zstack_PickColor, currentColor,  $
   Group_Leader_ID=groupLeader, Cancel=cancelled
;@zstack_common
;@zstack_color_common
;@zstack_display_common  ; NB if put these in this procedure following code is not read correctly

; --------  Device must support windows.
IF (!D.FLAGS AND 256) EQ 0 THEN BEGIN
   Message, 'Device must support windows. Returning...', /Continue
   cancelled = 1
   RETURN  ;, -1
 ENDIF
; Working in decomposed color space with defined number of colors.
; Save decomposed state and restore it, if possible.

IF Float(!Version.Release) GE 5.2 THEN BEGIN
	 Device, Get_Decomposed=decomposedState
ENDIF ELSE decomposedState = 0
Device, Decomposed=0
; Check parameters.
IF N_Elements(startIndex) EQ 0 THEN startIndex = !D.Table_Size - (bottom_color_index + 1)
startIndex = startIndex < (!D.Table_Size - (bottom_color_index + 1))
IF N_Elements(currentColor) EQ 0 THEN currentColor = 0
currentColor = currentColor >1 <15
; Get the current color tables so they can be restored on exit.
TVLCT, r_old, g_old, b_old, /Get	; colors for restoring if Cancel All is chosen
TVLCT, red, green, blue, /Get		;
TVLCT, r, g, b, /Get				; colors for restoring if Cancel is chosen
names = ['Color 00', 'Color 01', 'Color 02', 'Color 03', $
		'Color 04', 'Color 05', 'Color 06', 'Color 07', $
		'Color 08', 'Color 09', 'Color 10', 'Color 11', $
		'Color 12', 'Color 13', 'Color 14', 'Color 15']
   ; Create the widgets. TLB is MODAL or BLOCKING.
IF N_Elements(groupLeader) EQ 0 THEN BEGIN
   tlb = Widget_Base(row=1, /Base_Align_Center, $
   				title='ZSTACK Color Palette Specifications' )
ENDIF ELSE BEGIN
   tlb = Widget_Base(row=1, /Base_Align_Center, /Modal, Group_Leader=groupLeader, $
   				title='ZSTACK Color Palette Specifications' )
ENDELSE
col1 = widget_base(tlb,/col)
col2 = widget_base(tlb,/col)
col3 = widget_base(tlb,/col)
colorbaseID = Widget_Base(col1, col=1, /frame, Event_Pro='Zstack_PickColor_Select_Color')
label = widget_label(colorbaseID,value='Color Palette')
row = widget_base(colorbaseID,/row)
drawID = LonArr(bottom_color_index+1)
FOR j=0,bottom_color_index-1 DO BEGIN
	eachcolorbaseID = widget_base(colorbaseID,row=1)
	labelID = widget_label(eachcolorbaseID,value=names[j])
	drawID[j] = Widget_Draw(eachcolorbaseID, XSize=20, YSize=15, $
			UValue=names[j], Button_Events=1)
ENDFOR
dialogbase = widget_base(col2, col=1,/frame)
row = widget_base(dialogbase,/row,/align_center)
col2a = widget_base(row,/col)
currentID = Widget_Base(col2a, Column=1, Base_Align_Center=1)
labelID = Widget_Label(currentID, Value='Current Color')
currentColorID = Widget_Draw(currentID, XSize=60, YSize=15)
col2b = widget_base(row,/row)
newID = Widget_Base(col2b, Column=1, Base_Align_Center=1)
labelID = Widget_Label(newID, Value='New Color')
newColorID = Widget_Draw(newID, XSize=60, YSize=15)
row = widget_base(dialogbase,/row)
col2c = widget_base(row,/col)
sliderbase = Widget_Base(col2c, COLUMN=1, FRAME=1, BASE_ALIGN_CENTER=1, $
   EVENT_PRO='Zstack_PickColor_Sliders')
label = Widget_Label(sliderbase, Value='Specify a Color')
; Set the current color values in sliders.
redID = Widget_Slider(sliderbase, Scr_XSize=200, Value=r[currentColor], $
   Max=255, Min=0, Title='Red')
greenID = Widget_Slider(sliderbase, Scr_XSize=200, Value=g[currentColor], $
   Max=255, Min=0, Title='Green')
blueID = Widget_Slider(sliderbase, Scr_XSize=200, Value=b[currentColor], $
   Max=255, Min=0, Title='Blue')
buttonbase = Widget_Base(col2c, ROW=1, Align_Center=1, Event_Pro='Zstack_PickColor_Buttons')
cancelID = Widget_Button(buttonbase, VALUE='Cancel')
acceptID = Widget_Button(buttonbase, VALUE='Accept')
;	row = Widget_Base(col2, /row, /Align_Center,/frame)
;	buttonbase = widget_base(row,/col, Event_Pro='Zstack_PickColor_Buttons')
;	label = widget_label( buttonbase, value='Color Filename (*.clr) :' )
;	save_color_filename_label = widget_text(buttonbase,value='',xsize=20,/editable)
;	save_color_label = widget_button(buttonbase,value='Save Colors')
;	read_color_label = widget_button(buttonbase,value='Read Colors')
;	browse_color_label = widget_button(buttonbase,value='Browse *.clr')
row = Widget_Base(col2, /row, /Align_Center,/frame)
col2d = widget_base(row,/col)
labelID = widget_label(col2d,value='Accept all changes ?')
buttonbase = Widget_Base(col2d, ROW=1, Align_Center=1, Event_Pro='Zstack_PickColor_Buttons')
cancelID = Widget_Button(buttonbase, VALUE='Cancel All')
acceptID = Widget_Button(buttonbase, VALUE='Accept All')
colorbaseID = widget_base(col3, col=1,/frame, event_pro='Zstack_PickColor_Definitions')
label = widget_label(colorbaseID,value='Specific Color Definitions')
row = widget_base(colorbaseID,/row)
colormenuID = LonArr(n_elements(zstack_color_def_names))
colordrawID = LonArr(n_elements(zstack_color_def_names))
FOR j=0,n_elements(zstack_color_def_names)-1 DO BEGIN
	eachcolorbaseID = widget_base(colorbaseID,row=1)
	colormenuID[j] = Widget_droplist(eachcolorbaseID, $
			UValue=zstack_color_def_indices[j], value=['Select Color',names])
	colordrawID[j] = Widget_Draw(eachcolorbaseID, XSize=20, YSize=15)
	labelID = widget_label(eachcolorbaseID,value=zstack_color_def_names[j])
ENDFOR
; Center the TLB.
Zstack_PickColor_CenterTLB, tlb
Widget_Control, tlb, /Realize
; Load the drawing colors.
wids = IntArr(bottom_color_index)
FOR j=0, bottom_color_index-1 DO BEGIN
   Widget_Control, drawID[j], Get_Value=thisWID
   wids[j] = thisWID
   WSet, thisWID
   PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color = j	;startIndex + j
ENDFOR
; Freeze black and white colors
widget_control, drawID[0], sensitive = 0					; always black
widget_control, drawID[bottom_color_index-1], sensitive = 0	; always white
; Load the current color.
Widget_Control, currentColorID, Get_Value=currentWID
WSet, currentWID
TVLCT, r[currentColor], g[currentColor], b[currentColor], currentColor
PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=currentColor
Widget_Control, newColorID, Get_Value=newWID
WSet, newWID
TVLCT, r[currentColor], g[currentColor], b[currentColor], currentColor
PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=currentColor
; Load the specific definition colors.
ColorWID = IntArr(n_elements(zstack_color_def_names))
FOR j=0,n_elements(zstack_color_def_names)-1 DO BEGIN
	widget_control,colormenuID[j], set_droplist_select=zstack_color_def_indices[j]+1
	Widget_Control, colordrawID[j], Get_Value=thisWID
	ColorWID[j] = thisWID
	WSet, thisWID
	PolyFill, [0,0,1,1,0], [0,1,1,0,0], /Normal, Color=zstack_color_def_indices[j]
ENDFOR
; Pointer to hold the form information.
ptr = Ptr_New({cancel:1.0, r:r_old[currentColor], g:g_old[currentColor], $
         b:b_old[currentColor]})
; Info structure for program information.
info = {	ptr:ptr, $					; The pointer to the form information.
		r_old:r_old, $				; The old color table.
		g_old:g_old, $
		b_old:b_old, $
		r:r, $ 					; The new color table.
		g:g, $
		b:b, $
		redID:redID, $				; The IDs of the color sliders.
		greenID:greenID, $
		blueID:blueID, $
		names:names, $				; The color names.
		red:red, $					; The red color values.
		green:green, $				; The green color values.
		blue:blue, $				; The blue color values.
		currentColor:currentColor, $	; The current color index.
		currentWID:currentWID, $		; The current color window index number.
		newWID:newWID, $			; The current color window index number.
		wids:wids, $				; The window index number of the drawing colors.
		ColorMenuID:ColorMenuID, $		; The window index number of the color definition menus
		ColorWID:ColorWID $			; The window index number of the definition colors.
       }
Widget_Control, tlb, Set_UValue=info, /No_Copy
XManager, 'Zstack_PickColor', tlb ; Block here until widget program is destroyed.
; Retrieve the color information.
colorInfo = *ptr
Ptr_Free, ptr
cancelled = colorInfo.cancel
; Restore decomposed state if possible.
IF Float(!Version.Release) GE 5.2 THEN Device, Decomposed=decomposedState
RETURN
END