; Copyright (c) 1998-2015 C. Zimba & A.P. Hitchcock  All rights reserved
;+
; NAME:
;	ZSTACK_BUILDLIST.PRO
;
; LAST CHANGED: ----------------------------------- 03-Aug-15
;
; AUTHORS:
;	Carl G. Zimba (NIST), Chris Jacobsen (SUNY - Stonybrook)
; PURPOSE:
;	Construction of a list of image filenames for use by ZSTACK_ANALYZE.PRO and ZSTACK_ALIGN.PRO
;	Called by ZSTACK_ANALYZE.PRO
; CATEGORY:
;	Data analysis.
; CALLING SEQUENCE:
;	zstack_buildlist, return_filename_list,$
;			stxm=stxm, sxm=sxm, sm=sm, als=als, poly=poly
; INPUTS:
;	NONE
; KEYWORD PARAMETERS:
;	stxm = data obtained from STXM of Beamline X1A at NSLS (default)
;	sxm = data obtained from cryo-STXM of Beamline X1A at NSLS
;	sm = data obtained from ???
;	als = data obtained from Beamline 7 at ALS
;	poly = data obtained from Polymer STXM at ALS
; OUTPUTS:
;	return_filename_list = list of image files to be analyzed
;	data_source = specifies type of data:
;		STXM:1, SXM:2, SM:3, ALS:4, POLY:5
; COMMON BLOCKS:
;	zstack_common	:
;		data_source				:	type of x-ray microscopy data: STXM:1, SXM:2, SM:3, ALS:4, POLY:5
;		data_directory				:	directory of data files
;		image_stack				:	3-D matrix of multiple x-ray microscope images
;		filename_list				:	list of filename corresponding to images in image_stack
;		ev_list					:	list of x-ray energies corresponding to images in image_stack
;		msec_list					:	list of dwell times corresponding to images in image_stack
;		filename_display_list			:	list of filename, x-ray energy, and dwell time corresponding to images in image_stack
;		displayed_file_index			:	index in image_stack, filename_list, msec_list, and filename_display_list currently being displayed or processed
;		n_files					:	number of images
;		list_filename				:	name of file to save or retrieve list of data files
;		shift_filename				:	filename of alignment shifts
;		x_shift					:	array of x-coordinate alignment shifts
;		y_shift					:	array of y-coordinate alignment shifts
;		data_shifted				:	0: data was not shifted and should not be clipped, 1: data was shifted and should be clipped, -1: denotes ZSTACK_PROFILE.PRO is being run as a stand-alone procedure
;		n_clipped_cols				:	number of columns in clipped image
;		n_clipped_rows				:	number of rows in clipped image
;		clipbox					:	vector of four points defining dimensions of region unclipped by alignment: [xleft,xright,ybot,ytop]
;	zstack_build_list_common
;		zstack_build_list_par			:	variables controlling ZSTACK Buildlist dialog window
;		data_filelist				:	List of all data file within data_directory
;		this_filename				:	Name of currently selected data file
;		first_filename				:	Name of data file selected as the first file in sequence
;		last_filename				:	Name of data file selected as the last file in sequence
;		this_ev					:	X-ray energy of currently selected file
;		first_ev					:	X-ray energy of data file selected as the first file in sequence
;		last_ev					:	X-ray energy of data file selected as the last file in sequence
;		got_first					:	Logic control parameter: O: don't have first file, 1: have first file
;		got_last					:	Logic control parameter: O: don't have last file, 1: have last file
;		got_a_file					:	Logic control parameter: O: don't have a file, 1: have a file
;		delete_file_index			:	index of file to be deleted from list
;	zstack_display_common
;		zstack_display_par			:	variables controlling ZSTACK Display dialog window
;		image_zoom					:	zoom factor for displaying images
;		subimage_zoom				:	zoom factor for subimages
;		movie_delay				:	delay used to display movie images of data stacks, dependent upon machine speed
;		disp_min					:	minimum percentage intensity for display of images
;		disp_max					:	maximum percentage intensity for display of images
;		disp_gamma					:	gamma factor for display of images
;		spectrum_display			:	Display spectra as: 1: Single Beam, 2: Percent Transmittance, 3: Absorbance
;		spectrum_offset				:	Offset used to plot spectra
;		init_zoom					:	initial zoom factor for displaying images (used in ZSTACK_SAVE and ZSTACK_TUNE)
;		movie_active				:	movie of images is active: 0: NO, 1: YES
;		profile_zoom				:	zoom factor for file number axis on profile images
;		image_range				:	scale images using: 0: intensity range of each image, 1: intensity range of full image stack
;		image_ratio				:	Display images normalized by: 0: inv_image_stack, 1: i0 spectrum
;		ratio_image_index			:	index of image to use when ratio images to a constant image
;		image_scale				:	Display images normalized by: 0: inv_image_stack, 1: i0 spectrum
;		image_invert				:	invert color bar: 0: NO, 1: YES
;		temp_old_display			:	initial array of display parameters, set at beginning of ZSTACK_DISPLAY
;		temp_new_display			:	array of display parameters updated as display options are changed
;		zstack_subroutine			:	subroutine from which ZSTACK_DISPLAY was called
;		spectra_x_min				:	mimimum x-ray energy value to plot spectra
;		spectra_x_max				:	maximum x-ray energy value to plot spectra
;		spectra_y_min				:	mimimum intensity value to plot spectra
;		spectra_y_max				:	maximum intensity value to plot spectra
;		x_autoscale				:	autoscale x-ray energy scale: 0: NO, 1: YES
;		y_autoscale				:	autoscale spectra intensity scale: 0: NO, 1: YES
;	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
; EXAMPLE:
;
; MODIFICATION HISTORY:
; 20feb99, CGZ
; Modified and rewritten STACK_ANALYZE.PRO to form ZSTACK_ANALYZE.PRO
;	Added statements to include Macintosh directory structure
;	Added read and display of current directory to Buildlist dialog window
;		not working in STACK_BUILDLIST.PRO
;	Added text fields to Stack Buildlist dialog window
;		filename, wavelength, energy, dwell time, image pixel dimensions
;	Added sensitive/desensitive procedures to control buttons during buildlist activity
;	Added ability to read existing file (*.sl) containing a list of image filenames,
;		in addition to saving such a file
;	Altered saving of *.sl files so that directory is written into file header
;		older *.sl files are incompatible
;	Eliminated return_list_filename from zstack_buildlist - no apparent use
;	Added option for data from Polymer STXM
;		/poly keyword and stxm1_sxm2_sm3_als4_poly5 variable
;	Modified COMMON block structure so that common variables are shared with all zstack routines
;		i.e., zstack_common contains variables used by
;		ZSTACK_ANALYZE.PRO, ZSTACK_READLIST.PRO, ZSTACK_BUILDLIST.PRO, and ZSTACK_ALIGN.PRO
;	Common variables are now determined within ZSTACK_BUILDLIST.PRO:
;		image_stack, filename_list, ev_list, msec_list, filename_display_list
;	Modified zstack_build_list_par
;		so that they only contain only variables associated with dialog window.
;		All variables have been moved to zstack_build_list_common
;	Added browse feature for current directory
;	Added test for directory on read shift file
;
; 30sep99, CGZ
; 	Added capability to delete individual files from filename_list
;	Added delete_file_index variable to zstack_build_list_common
;
; 17apr00, CGZ
;	Added color bar to dialog window
;	Added bit to adjust widget size to not overfill screen
;		also ensures that widgets are scrollable on MS Windows platforms
;	Added bit to zstack_buildlist_stripdir
;		to alphabetize list of files when using MS Windows platforms
;	Added bit to zstack_buildlist
;		to ensure that the correct terminal character is included in data_directory
;
; (29oct00 cgz) Modified !version.os routines to use !version.os_family variable
; (29oct00 cgz) Modified buildlist browse event routine
;		so that filelist properly reflected presence of data files
; (30oct00 cgz) Cleaned up zstack_buildlist_sensitive routine
; (31oct00 cgz)
;		Modified zstack_buildlist_savelist to include dialog_pickfile so directory can be selected
;		Fixed problem, which blanked directory field, with CANCEL on browse of list_filename
;		Replaced platform-dependent code with call to zstack_analyze_extract_filename
;		Fixed widget_control, hourglass=0/1 statement - was specifying unneeded widgetID
; (13nov00 cgz)  Added calculation of initial zoom factor, based upon image size
; (22dec00 cgz)  Added ability to read in binary stack file (*.ncb)
; (03-Mar-08 MJ)  Keyword /SCROLL in widget_base() needs X_SCROLL_SIZE.
; (20-mar-08 aph) increased default Xsize of window
; (13-apr-08 aph) turn on pre-set window size (X_Scroll_size, Y_Scroll_size) only for non-Windows OS
; (07-mar-09 aph) added binary_filenmane to zstack_common
; (27-Jul-09 aph) changed commons to external files
; (20-Aug-09 aph) add axis_com common (axis_ID missing)
; (24-Aug-09 aph) REMOVED axis_com common - checking if that is why BufNum gets corrupted
; (02-Aug-15 aph) change colorbar to colorbar_dwf to avoid confusion with post8.0 COLORBAR routine
; ; (03-Aug-15 aph) changed label to zlabel since label is an array in axis_com
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_prep

@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

zstack_color

disp_min = 0
disp_max = 110
disp_gamma = 1
movie_delay = 0.02

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_sensitive

@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, zstack_build_list_par.directory_label, sensitive = 1
widget_control, zstack_build_list_par.filelist_label, sensitive = 1

IF (strlen(strtrim(this_filename,2)) EQ 0) THEN BEGIN
	widget_control, zstack_build_list_par.first_label, sensitive = 0
	widget_control, zstack_build_list_par.last_label, sensitive = 0
	widget_control, zstack_build_list_par.save_list_label,sensitive = 0
	widget_control, zstack_build_list_par.read_list_label, sensitive = 0
	widget_control, zstack_build_list_par.display_parameters_label, sensitive = 0
ENDIF ELSE BEGIN
	widget_control, zstack_build_list_par.first_label, sensitive = 1
	widget_control, zstack_build_list_par.last_label, sensitive = 1
	IF (n_files GT 1) THEN BEGIN
		widget_control, zstack_build_list_par.save_list_label,sensitive = 1
		widget_control, zstack_build_list_par.read_list_label, sensitive = 1
	ENDIF ELSE BEGIN
		widget_control, zstack_build_list_par.save_list_label,sensitive = 0
		widget_control, zstack_build_list_par.read_list_label, sensitive = 0
	ENDELSE
	widget_control, zstack_build_list_par.display_parameters_label, sensitive = 1
ENDELSE

widget_control, zstack_build_list_par.save_list_filename_label, sensitive = 1
widget_control, zstack_build_list_par.browse_list_label, sensitive = 1

IF ( (got_first EQ 1) AND $
		(got_last EQ 1) ) THEN BEGIN
	widget_control, zstack_build_list_par.add_label, sensitive = 1
ENDIF ELSE BEGIN
	widget_control, zstack_build_list_par.add_label, sensitive = 0
ENDELSE

widget_control, zstack_build_list_par.list_complete_label, sensitive = 1

IF (n_elements(filename_list) EQ 1) THEN BEGIN
;	widget_control, zstack_build_list_par.browse_directory_label, sensitive = 1
;	widget_control, zstack_build_list_par.directory_label, sensitive = 1

	widget_control, zstack_build_list_par.reset_list_label, sensitive = 0
	widget_control, zstack_build_list_par.delete_label, sensitive = 0
	widget_control, zstack_build_list_par.prev_image_label, sensitive = 0
	widget_control, zstack_build_list_par.next_image_label, sensitive = 0
	widget_control, zstack_build_list_par.play_movie_label, sensitive = 0
	widget_control, zstack_build_list_par.stack_filelist_label, sensitive = 0
ENDIF ELSE BEGIN
;	widget_control, zstack_build_list_par.browse_directory_label, sensitive = 0
;	widget_control, zstack_build_list_par.directory_label, sensitive = 0

	widget_control, zstack_build_list_par.reset_list_label, sensitive = 1
	widget_control, zstack_build_list_par.delete_label, sensitive = 1
	widget_control, zstack_build_list_par.prev_image_label, sensitive = 1
	widget_control, zstack_build_list_par.next_image_label, sensitive = 1
	widget_control, zstack_build_list_par.play_movie_label, sensitive = 1
	widget_control, zstack_build_list_par.stack_filelist_label, sensitive = 1
ENDELSE

IF (strlen(strtrim(list_filename,2)) EQ 0) THEN BEGIN
	widget_control, zstack_build_list_par.read_list_label, sensitive = 0
ENDIF ELSE BEGIN
	widget_control, zstack_build_list_par.read_list_label, sensitive = 1
ENDELSE


return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_desensitive

@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, zstack_build_list_par.directory_label, sensitive = 0
widget_control, zstack_build_list_par.filelist_label, sensitive = 0
widget_control, zstack_build_list_par.first_label, sensitive = 0
widget_control, zstack_build_list_par.last_label, sensitive = 0
widget_control, zstack_build_list_par.save_list_filename_label, sensitive = 0
widget_control, zstack_build_list_par.save_list_label, sensitive = 0
widget_control, zstack_build_list_par.read_list_label, sensitive = 0
widget_control, zstack_build_list_par.browse_list_label, sensitive = 0
widget_control, zstack_build_list_par.add_label, sensitive = 0
widget_control, zstack_build_list_par.reset_list_label, sensitive = 0
widget_control, zstack_build_list_par.list_complete_label, sensitive = 0
IF (movie_active EQ 0) THEN BEGIN
	widget_control, zstack_build_list_par.stack_filelist_label, sensitive = 0
ENDIF ELSE BEGIN
	widget_control, zstack_build_list_par.stack_filelist_label, sensitive = 1
ENDELSE
widget_control, zstack_build_list_par.delete_label, sensitive = 0

widget_control, zstack_build_list_par.prev_image_label, sensitive = 0
widget_control, zstack_build_list_par.next_image_label, sensitive = 0
widget_control, zstack_build_list_par.play_movie_label, sensitive = 0
widget_control, zstack_build_list_par.display_parameters_label, sensitive = 0

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_extract_filename, input_string, output_string

;print,'zstack_buildlist_extract_filename'

; this is an exact copy of zstack_analyze_extract_filename
;	copied here so that zstack_buildlist can be used independently of zstack_analyze
; this function extracts the directory from the input_string
; directory text is returned as output_string
; usually used after dialog_pickfile request for directory


CASE strupcase(!version.os_family) OF
	'VMS' : BEGIN
		firstpos = strpos(input_string, ']')+1
	END
	'WINDOWS' : BEGIN
		firstpos = rstrpos(input_string, '\')+1
	END
	'MACOS' : BEGIN
		firstpos = rstrpos(input_string, ':')+1
	END
	'UNIX' : BEGIN
		firstpos = rstrpos(input_string, '/')+1
	END
	ELSE : BEGIN
		print,'Unrecognized operating system'
	END
ENDCASE

IF (firstpos EQ -1) THEN BEGIN
	output_string = input_string
ENDIF ELSE BEGIN
	output_string = strmid(input_string, firstpos, (strlen(input_string)-firstpos))
ENDELSE

IF (strupcase(!version.os_family) EQ 'VMS') THEN BEGIN
	semipos = rstrpos(output_string, ';')
	IF (semipos GT 1) THEN BEGIN
		output_string = strmid(output_string,0,semipos)
	ENDIF
ENDIF

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_stripdir, filelist, stripped_filelist, stripped_directory

;print,'zstack_buildlist_stripdir'

@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

stripped_filelist = strarr(n_elements(filelist))

FOR i=0,(n_elements(filelist)-1) DO BEGIN
    temp_filename = filelist(0)

	CASE strupcase(!version.os_family) OF
		'VMS' : BEGIN
			firstpos = strpos(temp_filename, ']')+1
		END
		'WINDOWS' : BEGIN
			firstpos = rstrpos(temp_filename, '\')+1
		END
		'MACOS' : BEGIN
			firstpos = rstrpos(temp_filename, ':')+1
		END
		'UNIX' : BEGIN
			firstpos = rstrpos(temp_filename, '/')+1
		END
		ELSE : BEGIN
			print,'Unrecognized operating system'
		END
	ENDCASE

    IF (firstpos EQ -1) THEN BEGIN
        stripped_filelist(i) = filelist(i)
        IF (i EQ 0) THEN stripped_directory = ''
    ENDIF ELSE BEGIN
        stripped_filelist(i) = $
          strmid(filelist(i), firstpos, (strlen(temp_filename)-firstpos))
        IF (i EQ 0) THEN stripped_directory = $
          strmid(temp_filename,0,firstpos)
    ENDELSE

;    IF (firstpos EQ -1) THEN BEGIN
;        stripped_filelist(i) = filelist(i)
;        IF (i EQ 0) THEN stripped_directory = ''
;    ENDIF ELSE BEGIN
;        stripped_filelist(i) = $
;          strmid(filelist(i), firstpos, (strlen(temp_filename)-firstpos))
;        IF (i EQ 0) THEN stripped_directory = $
;          strmid(temp_filename,0,firstpos)
;    ENDELSE

    IF (strupcase(!version.os_family) EQ 'VMS') THEN BEGIN
        semipos = rstrpos(stripped_filelist(i), ';')
        IF (semipos GT 1) THEN BEGIN
            stripped_filelist(i) = strmid(stripped_filelist(i),0,semipos)
        ENDIF
    ENDIF
ENDFOR

; Windows version doesn't display the list of data files alphabetically
; so must explicitly sort the files into alphabetic order
; This is a quirk of Windoze
IF (strupcase(!version.os_family) EQ 'WINDOWS') THEN BEGIN
	stripped_filelist = stripped_filelist(sort(stripped_filelist))
ENDIF

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_header_num, filename, header, numstr, trailer, next_numstr

;print,'zstack_buildlist_header_num'

@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

dotpos = rstrpos(filename, '.')
trailer = strmid(filename, dotpos, (strlen(filename)-dotpos))

zerobytstr = byte('0')
zerobyte = zerobytstr(0)
ninebytstr = byte('9')
ninebyte = ninebytstr(0)

testpos = dotpos-1
teststr = strmid(filename, testpos, 1)
testbytarr = byte(teststr)
testbyte = testbytarr(0)
WHILE ((testbyte GE zerobyte) AND $
       (testbyte LE ninebyte)) DO BEGIN
    numpos = testpos
    testpos = numpos - 1
    teststr = strmid(filename, testpos, 1)
    testbytarr = byte(teststr)
    testbyte = testbytarr(0)
ENDWHILE

header = strmid(filename, 0, numpos)
numstr = strmid(filename, numpos, (dotpos-numpos))

num = 0L			; this makes num an integer (i.e. long integer)
reads, numstr, num

next_numstr = strtrim(string(num+1), 2)
next_numstr_len = strlen(next_numstr)
numstr_len = strlen(numstr)

WHILE (numstr_len GT next_numstr_len) DO BEGIN
    next_numstr = '0'+next_numstr
    next_numstr_len = next_numstr_len + 1
ENDWHILE

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_doit

;print,'zstack_buildlist_doit'

@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

;IF ((got_first EQ 0) OR (got_last EQ 0)) THEN BEGIN
;    ev_list = ''
;    msec_list = ''
;    filename_list = ''
;    filename_display_list = ''
;    widget_control, zstack_build_list_par.stack_filelist_label, set_value = ['']
;    return
;ENDIF

IF (first_filename GT last_filename) THEN BEGIN
	dummy = first_filename
	first_filename = last_filename
	last_filename = dummy
ENDIF

zstack_buildlist_header_num, first_filename, $
  header, first_numstr, trailer, next_numstr
zstack_buildlist_header_num, last_filename, $
  header, last_numstr, trailer

this_numstr = first_numstr
this_filename = header+this_numstr+trailer
next_filename = header+next_numstr+trailer
keep_going = 1		; why use this keep_going EQ 1 structure?  why not a FOR NEXT loop?
				; WHILE-DO may be better for discontinuous lists,
				; 		although not in this particular loop
				; WHILE-DO does work well if only beginning and end files are known
				;		as is the case here

zstack_buildlist_desensitive

n_cols_expected = n_cols
n_rows_expected = n_rows
	; set to values from previous stxm_read
	;	either from zstack_buildlist_readfile of first and last files
	; 	or from zstack_readlist.pro of previously stored list

print,'Reading in images. Please be patient...'
print,"... or I'll have to use my Illudium Q-36 explosive space modulator !"
start_time = systime(1.)

WHILE (keep_going EQ 1) DO BEGIN
    templist = findfile(data_directory+this_filename)
    svec = size(templist)

    IF (svec(0) NE 0) THEN BEGIN
		CASE data_source OF
			1 : BEGIN	; X1A STXM data
				read_stxm,this_filename,sd,khz
				this_ev = 12398.52/sd.wavelength
				this_msec = sd.dwell_time
				this_file_text_label = this_filename+': '+$
					strtrim(string(this_ev, format = '(f10.2)'), 2)+' eV, '+$
					strtrim(string(sd.wavelength, format = '(f10.3)'), 2)+' A'
			END
			2 : BEGIN	; X1A cryo-STXM data
				read_sxm,this_filename
				khz = float(image_data(*,*,0))
				this_ev = 1239.852/sxm_par.now_nm
				this_msec = sxm_par.msec_dwell
				this_file_text_label = this_filename+': '+$
					strtrim(string(this_ev, format = '(f10.2)'), 2)+' eV, '+$
					strtrim(string(sd.wavelength, format = '(f10.3)'), 2)+' A'
			END
			3 : BEGIN	; sm data
			END
			4 : BEGIN	; BL7 (ALS) data
			END
			5 : BEGIN	; Polymer STXM (ALS) data
			END
		ENDCASE

		;; Add this to the list
		svec = size(filename_list)
		image = fltarr(n_cols,n_rows)

		IF (svec(0) EQ 0) THEN BEGIN
			n_cols_expected = n_cols
			n_rows_expected = n_rows
;			image[0:(n_cols-1),0:(n_rows-1)] = khz
			image = khz
			image_stack = image
			filename_list = [this_filename]
			ev_list = [this_ev]
			msec_list = [this_msec]
			filename_display_list = [this_file_text_label]
		ENDIF ELSE BEGIN
			IF (n_cols NE n_cols_expected) OR $
					(n_rows NE n_rows_expected) THEN BEGIN
				print,'Skipping "'+this_filename+'" because it has '+$
					strtrim(string(n_cols),2)+'x'+$
					strtrim(string(n_rows),2)+' rather than '+$
					strtrim(string(n_cols_expected),2)+'x'+$
					strtrim(string(n_rows_expected),2)+' pixels'
			ENDIF ELSE BEGIN
;				image[0:(n_cols-1),0:(n_rows-1)] = khz
				image = khz
				image_stack = [[[temporary(image_stack)]],[[image]]]
				filename_list = [temporary(filename_list), this_filename]
				ev_list = [temporary(ev_list), this_ev]
				msec_list = [temporary(msec_list), this_msec]
				filename_display_list = $
					[temporary(filename_display_list), this_file_text_label]
			ENDELSE
		ENDELSE

		IF (this_numstr EQ last_numstr) THEN BEGIN
			keep_going = 0
		ENDIF ELSE BEGIN
			this_numstr = next_numstr
			this_filename = header+this_numstr+trailer
			zstack_buildlist_header_num, this_filename, $
					header, numstr, trailer, next_numstr
			next_filename = header+next_numstr+trailer
		ENDELSE
	ENDIF ELSE BEGIN
;		keep_going = 0	; commented out, CGZ, not needed
		; added, CGZ to deal with discontinuous lists of data files
		; i.e.,  numstr = 030, 031, 032, 033, 045, 046, 047
		this_numstr = next_numstr
		this_filename = header+this_numstr+trailer
		zstack_buildlist_header_num, this_filename, $
			header, numstr, trailer, next_numstr
		next_filename = header+next_numstr+trailer
	ENDELSE
ENDWHILE

; Elapsed time for reading in image data files
end_time = systime(1.)
total_time = end_time - start_time
minutes = fix(total_time/60)
seconds = total_time-60.*minutes
IF (minutes GT 0) THEN BEGIN
	print,'Elapsed time for reading in images: '+$
			strtrim(string(minutes),2)+' minutes '+$
			strtrim(string(seconds,format='(f10.1)'),2)+' seconds.
ENDIF ELSE BEGIN
	print,'Elapsed time for reading in images: '+$
			strtrim(string(seconds,format='(f10.1)'),2)+' seconds.
ENDELSE

print,'Sorting the list'
index_order = sort(ev_list)
ev_list = ev_list(index_order)
msec_list = msec_list(index_order)
filename_list = filename_list(index_order)
filename_display_list = filename_display_list(index_order)
image_stack = temporary(image_stack(*,*,index_order))
n_files = n_elements(filename_list)

zstack_buildlist_sensitive

widget_control,zstack_build_list_par.stack_filelist_label, set_value = filename_display_list

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_imgdisp,i_file

;print,'zstack_buildlist_imgdisp'

@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

; Center image and zoom (up or down) to fit 150 x 150 pixel window
IF (max([n_cols,n_rows]) GT 150) THEN BEGIN
	inv_zoom = ceil(max([n_cols,n_rows])/150.)
	xleft = fix((150. - n_cols/inv_zoom)/2.)
	xright = xleft + n_cols/inv_zoom
	ybot = fix((150. - n_rows/inv_zoom)/2.)
	ytop = ybot + n_rows/inv_zoom
ENDIF ELSE BEGIN
	inv_zoom = 1
	xleft = fix((150. - n_cols)/2.)
	xright = xleft + n_cols
	ybot = fix((150. - n_rows)/2.)
	ytop = ybot + n_rows
ENDELSE

this_image = image_stack(*,*,i_file)

; Invert intensity of image so that it will appear to use an inverted color table
;IF (image_invert EQ 1) THEN BEGIN
;	max_image = max(this_image)
;	this_image = max_image - temporary(this_image)
;ENDIF

; Scale image intensity to minimum and maximum values
IF (image_range EQ 0) THEN BEGIN
	min_image = min(this_image)
	this_image = temporary(this_image) - min_image
	max_image = max(this_image)
ENDIF ELSE BEGIN
	min_image = min(image_stack)
	this_image = temporary(this_image) - min_image
	max_image = max(image_stack)
ENDELSE
percent_image = 100. * this_image / max_image

; Scale raw image to fill gray scale range
display_image = (( ((percent_image - disp_min) $
			/ ((disp_max - disp_min)^disp_gamma)) >0.)<1.)
byte_image = byte( float(bottom_color_index) + $
			float(top_color_index - bottom_color_index) * $
			display_image)

; Display image, applying zoom factor
wset,zstack_build_list_par.this_image_win
erase
;tv,rebin(byte_image,n_cols/inv_zoom,n_rows/inv_zoom,/sample),ybot,xleft

	IF (inv_zoom LE 1.0) THEN BEGIN
		tv,rebin(byte_image,n_cols,n_rows,/sample),xleft,ybot
	ENDIF ELSE BEGIN
		tv,congrid(byte_image,n_cols/inv_zoom,n_rows/inv_zoom),xleft,ybot
	ENDELSE

;	IF (image_zoom GE 1.0) THEN BEGIN
;		IF ((image_zoom) EQ fix(image_zoom)) THEN BEGIN
;			tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),ybot,xleft
;		ENDIF ELSE BEGIN
;			tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),ybot,xleft
;		ENDELSE
;	ENDIF ELSE BEGIN
;		IF ( ((image_zoom*n_cols) EQ fix(image_zoom*n_cols)) AND $
;			((image_zoom*n_rows) EQ fix(image_zoom*n_rows)) ) THEN BEGIN
;			tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),ybot,xleft
;		ENDIF ELSE BEGIN
;			tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),ybot,xleft
;		ENDELSE
;	ENDELSE

; Plot image border
plots,xleft,ytop,/device,color=image_border_color_index
plots,xright,ytop,/device,color=image_border_color_index,/continue
plots,xright,ybot,/device,color=image_border_color_index,/continue
plots,xleft,ybot,/device,color=image_border_color_index,/continue
plots,xleft,ytop,/device,color=image_border_color_index,/continue

; Print image description info
;widget_control, zstack_build_list_par.filelist_label, $
;	set_list_select = i_file
widget_control, zstack_build_list_par.this_file_label, $
		set_value = ' '+filename_list(i_file)
widget_control,zstack_build_list_par.this_row_col_label,$
		set_value=' '+strtrim(string(n_rows),2)+' rows X '+$
					strtrim(string(n_cols),2)+' cols'
widget_control,zstack_build_list_par.this_ev_label,$
		set_value=' '+strtrim(string(ev_list(i_file),$
					format='(f10.2)'),2)+' eV'
widget_control,zstack_build_list_par.this_wavelength_label,$
		set_value=' '+strtrim(string(12398.52/ev_list(i_file),$
					format='(f10.3)'),2)+' A'
widget_control,zstack_build_list_par.this_dwell_label,$
		set_value=' '+strtrim(string(msec_list(i_file), $
					format='(i6)'),2)+' msec dwell'
widget_control, zstack_build_list_par.stack_filelist_label, $
		set_list_select = i_file

;IF (movie_active EQ 0) THEN BEGIN
;	widget_control, zstack_build_list_par.stack_filelist_label, $
;			set_list_select = i_file
;ENDIF ELSE BEGIN
;	widget_control, zstack_build_list_par.stack_filelist_label, sensitive = 1
;	widget_control, zstack_build_list_par.stack_filelist_label, $
;			set_list_select = i_file
;	widget_control, zstack_build_list_par.stack_filelist_label, sensitive = 0
;ENDELSE

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_colorbar

;print,'zstack_buildlist_colorbar'

@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

wset, zstack_build_list_par.colorbar_win
colorbar_dwf, color = plot_bkgd_color_index, $
	bottom = bottom_color_index, top = top_color_index, $
	ncolors = top_color_index - bottom_color_index, $
	position = [0.0,0.0,0.99,0.9], ticklen = 0.0, $
	divisions = 1, range = [0,255]

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_readfile

;print,'zstack_buildlist_readfile'

@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

CASE data_source OF
	1 : BEGIN	; STXM data from X1A/NSLS
		n_cols = 0
		this_ev = 0.
;		read_stxm,this_filename,sd,/header,/nocopybytes
		read_stxm,this_filename,sd,khz
		IF (n_cols NE 0) THEN BEGIN
			this_ev = 12398.52/sd.wavelength
		ENDIF
	END
	2 : BEGIN	; cryo-STXM data from X1A/NSLS
		n_cols = 0
		this_ev = 0.
;		read_sxm,this_filename,/header
		read_sxm,this_filename
		IF (n_cols NE 0) THEN BEGIN
			khz = float(image_data(*,*,0))
			this_ev = 1239.852/sxm_par.now_nm
		ENDIF
	END
	3 : BEGIN
	END
	4 : BEGIN	; BL7 data from ALS
	END
	5 : BEGIN	; Polymer STXM data rom ALS
	END
ENDCASE

IF (n_cols NE 0) THEN BEGIN
;    zstack_build_list_par.this_ev = this_ev
	widget_control,zstack_build_list_par.this_file_label,$
			set_value=' '+this_filename
	widget_control,zstack_build_list_par.this_row_col_label,$
			set_value=' '+strtrim(string(n_cols),2)+' rows X '+$
					strtrim(string(n_rows),2)+' cols'
	widget_control,zstack_build_list_par.this_ev_label,$
			set_value=' '+strtrim(string(this_ev,$
					format='(f10.2)'),2)+' eV'
	widget_control,zstack_build_list_par.this_wavelength_label,$
			set_value=' '+strtrim(string(12398.52/this_ev,$
					format='(f10.3)'),2)+' A'
	widget_control,zstack_build_list_par.this_dwell_label,$
			set_value=' '+strtrim(string(sd.dwell_time, $
					format='(i6)'),2)+' msec dwell'

	; Display raw image with dragbox
	wset,zstack_build_list_par.this_image_win
	erase

	; center image and zoom (up or down) to fit 150 x 150 pixel window
	IF (max([n_cols,n_rows]) GT 150) THEN BEGIN
		inv_zoom = ceil(max([n_cols,n_rows])/150.)
		xleft = fix((150. - n_cols/inv_zoom)/2.)
		xright = xleft + n_cols/inv_zoom
		ybot = fix((150. - n_rows/inv_zoom)/2.)
		ytop = ybot + n_rows/inv_zoom
	ENDIF ELSE BEGIN
		inv_zoom = 1
		xleft = fix((150. - n_cols)/2.)
		xright = xleft + n_cols
		ybot = fix((150. - n_rows)/2.)
		ytop = ybot + n_rows
	ENDELSE

	disp_max = 100.
	; prepare and display raw image
	this_image = khz
	min_image = min(this_image)
	this_image = this_image - min(this_image)
	max_image = max(this_image)
	percent_image = 100. * this_image / max(this_image)
	display_image = (( ((percent_image - disp_min) $
				/ ((disp_max - disp_min)^disp_gamma)) >0.)<1.)
	byte_image = byte( float(bottom_color_index) + $
				float(top_color_index - bottom_color_index) * $
				display_image)
;	tv,rebin(byte_image,n_cols/inv_zoom,n_rows/inv_zoom),ybot,xleft

	IF (inv_zoom LE 1.0) THEN BEGIN
		tv,rebin(byte_image,n_cols,n_rows,/sample),xleft,ybot
	ENDIF ELSE BEGIN
		tv,congrid(byte_image,n_cols/inv_zoom,n_rows/inv_zoom),xleft,ybot
	ENDELSE

;	IF (image_zoom GE 1.0) THEN BEGIN
;		IF ((image_zoom) EQ fix(image_zoom)) THEN BEGIN
;			tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),ybot,xleft
;		ENDIF ELSE BEGIN
;			tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),ybot,xleft
;		ENDELSE
;	ENDIF ELSE BEGIN
;		IF ( ((image_zoom*n_cols) EQ fix(image_zoom*n_cols)) AND $
;			((image_zoom*n_rows) EQ fix(image_zoom*n_rows)) ) THEN BEGIN
;			tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),ybot,xleft
;		ENDIF ELSE BEGIN
;			tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),ybot,xleft
;		ENDELSE
;	ENDELSE

	plots,xleft,ytop,/device,color=image_border_color_index
	plots,xright,ytop,/device,color=image_border_color_index,/continue
	plots,xright,ybot,/device,color=image_border_color_index,/continue
	plots,xleft,ybot,/device,color=image_border_color_index,/continue
	plots,xleft,ytop,/device,color=image_border_color_index,/continue

	got_a_file = 1
	zstack_buildlist_sensitive
ENDIF ELSE BEGIN
	widget_control,zstack_build_list_par.this_file_label,set_value=''
	widget_control,zstack_build_list_par.this_row_col_label,set_value=''
	widget_control,zstack_build_list_par.this_ev_label,set_value=''
	got_a_file = 0
ENDELSE

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_savelist

;print,'zstack_buildlist_savelist'

@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

get_lun,lun
on_ioerror,zstack_buildlist_savelist_oops

cd,current=current_directory
dummy = dialog_pickfile(filter='*.sl', /write, /fix_filter, $
		file=list_filename, path=data_directory, get_path=data_directory, $
		title='Save list of image files as :')
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, zstack_buildlist_savelist_oops
		; trap if CANCEL is chosen in dialog
ENDIF
zstack_buildlist_extract_filename, dummy, list_filename
widget_control, zstack_build_list_par.save_list_filename_label, set_value = ' '+list_filename
; The dialog_pickfile section above must be here (instead of zstack_buildlist_event)
;	since directory of data (i.e., current_directory) is written to file
;	and there is no common variable to transfer the value.
;	If this is moved to zstack_buildlist_event, data directory info is lost

; replaced stack_writelist with the code below, CGZ
openw,lun,list_filename
printf,lun,current_directory
; added directory to header of saved list, CGZ
; will help with retreiving files from saved lists
FOR i=0,(n_files-1) DO BEGIN
	printf,lun,filename_list(i)
ENDFOR

print,'Wrote list of files as a file "'+data_directory+list_filename+'"'

zstack_buildlist_savelist_oops :
close,lun
free_lun,lun

;data_directory = temp
;cd,data_directory

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_read_binary, filename

;print,'zstack_buildlist_read_binary'

@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

; Modified from APH code: stack_rb.pro

on_error,2


; ----------------------- Establish image stack paramaters
	e_read = 0
	dpos = strpos(filename,'.')
	E_file = strmid(filename, 0,dpos) + '.dat'

; ---------- read in paramaters from E_file
;	init_sd,sd
	on_ioerror, dat_file_oops
	openr, lun, E_file, /get_lun
;	print, 'Reading stack parameters from ', E_file
	readf, lun, n_cols, n_rows, scale
	text = string(format='(" Image size: ", i3," x ",i3," pixels")',n_cols,n_rows)
;	print, text
	readf, lun, x_start, x_stop
	readf, lun, y_start, y_stop
	text = string(format='("X-range (um):  ",f7.3,"  to  ",f7.3)',x_start, x_stop)
;	print, text
	text = string(format='("Y-range (um):  ",f7.3,"  to  ",f7.3)',y_start, y_stop)
;	print, text
	readf, lun, n_files
	print, ' # of images = ', fix(n_files)
	ev = fltarr(n_files)
	msec_list = fltarr(n_files)
	ev_list = strarr(n_files)
	readf,lun, ev_list
;				this_ev = 12398.52/sd.wavelength

	text = string(format='("E-range (eV):  ",f7.2,"  to  ",f7.2)', min(ev_list), max(ev_list))
;	print, text
	filename_list = strarr(n_files)
	readf,lun, filename_list
;	FOR i = 0, n_files - 1 print, ev_list(i)
	e_read = 1
;print,'ev_list : ',ev_list
;print,'filename_list : ',filename_list


filename_display_list = strarr(n_files)
FOR i=0,n_files-1 DO BEGIN
	filename_display_list[i] = filename_list[i]+': '+$
					strtrim(string(ev_list[i] , format = '(f10.2)'), 2)+' eV, '+$
					strtrim(string(ev_list[i]/12398.52, format = '(f10.3)'), 2)+' A'
ENDFOR

	dat_file_oops :
	close, lun & free_lun, lun
; get dimensions of array if not specified in call or if not provided from E_file
	IF e_read NE 1 THEN BEGIN
			n_cols = get_num(Prompt = '#_x-pixels', Val=n_cols, group=axis_id)
			n_rows = get_num(Prompt = '#_y-pixels', Val=n_rows, group=axis_id)
			x_start = get_num(Prompt = 'x_start', Val= x_start, group=axis_id)
			x_stop = get_num(Prompt = 'x_stop', Val=x_stop, group=axis_id)
			y_start = get_num(Prompt = 'y_start', Val= y_start, group=axis_id)
			y_stop = get_num(Prompt = 'y_step', Val=y_stop, group=axis_id)
			n_energies = get_num(Prompt = '# of E', Val=n_energies, group=axis_id)
	ENDIF

	big_array = intarr(n_cols, n_rows, n_files)

	on_ioerror, binary_file_oops
	widget_control, /Hourglass
	openu, lun, filename, /get_lun
	readu, lun, big_array
	close, lun
	free_lun, lun
	image_stack = float(big_array)/scale
	IF scale NE 1 THEN print, string(format='("Stack read: data values rescaled by ",g13.6)', 1./scale)
	return

binary_file_oops :
	Print, 'STACK_RB: Size information provided disagrees with dimension of data in file '
	close, lun
	free_lun, lun
	return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_event, event

;print,'zstack_buildlist_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

case event.id of
    zstack_build_list_par.browse_directory_label : BEGIN
        on_ioerror, browse_directory_label_oops
        zstack_buildlist_desensitive

        cd,current = current_directory
		dummy = dialog_pickfile( /read, /must_exist, $
			path=data_directory, get_path=data_directory, $	;/directory, $
			title='Select file within desired directory :')
        		; /directory option will display only directories, not individual files
        widget_control, zstack_build_list_par.directory_label, $
          set_value = ' '+data_directory
        IF (dummy EQ '') THEN data_directory = current_directory
			; sets data_directory to initial directory if CANCEL is chosen during dialog
			; without this, data_directory becomes null string

        browse_directory_label_oops :
        cd,data_directory	; change directory to data_directory, CGZ
        last_char = strmid(data_directory,strlen(data_directory)-1,1)

		CASE strupcase(!version.os_family) OF
			'VMS' : BEGIN
				IF (last_char NE ']') THEN BEGIN
					data_directory = data_directory+']'
				ENDIF
			END
			'WINDOWS' : BEGIN
				IF (last_char NE '\') THEN BEGIN
					data_directory = data_directory+'\'
				ENDIF
			END
			'MACOS' : BEGIN
				IF (last_char NE ':') THEN BEGIN
					data_directory = data_directory+':'
				ENDIF
			END
			'UNIX' : BEGIN
				IF (last_char NE '/') THEN BEGIN
					data_directory = data_directory+'/'
				ENDIF
			END
			ELSE : BEGIN
				print,'Unrecognized operating system'
			END
		ENDCASE

        extension = (['.nc','.sxm','.sm','.dat','poly'])[data_source-1]

        filelist = findfile(data_directory+'*'+extension)
        svec = size(filelist)
        IF (svec(0) EQ 0) THEN BEGIN
            data_filelist = ['No files']
        ENDIF ELSE BEGIN
            zstack_buildlist_stripdir, filelist, data_filelist, data_directory
        ENDELSE

        widget_control, zstack_build_list_par.directory_label, $
          set_value = ' '+data_directory
        widget_control, zstack_build_list_par.filelist_label, $
;          set_value = data_filelist
          set_value=['Select from directory',data_filelist]
        zstack_buildlist_sensitive

    END

    zstack_build_list_par.directory_label : BEGIN
        on_ioerror, directory_label_oops
        zstack_buildlist_desensitive

        temp_string = ''
        widget_control, zstack_build_list_par.directory_label, $
          get_value = temp_string
        data_directory = temp_string(0)
        directory_label_oops :
        last_char = strmid(data_directory,strlen(data_directory)-1,1)

		CASE strupcase(!version.os_family) OF
			'VMS' : BEGIN
				IF (last_char NE ']') THEN BEGIN
					data_directory = data_directory+']'
				ENDIF
			END
			'WINDOWS' : BEGIN
				IF (last_char NE '\') THEN BEGIN
					data_directory = data_directory+'\'
				ENDIF
			END
			'MACOS' : BEGIN
				IF (last_char NE ':') THEN BEGIN
					data_directory = data_directory+':'
				ENDIF
			END
			'UNIX' : BEGIN
				IF (last_char NE '/') THEN BEGIN
					data_directory = data_directory+'/'
				ENDIF
			END
			ELSE : BEGIN
				print,'Unrecognized operating system'
			END
		ENDCASE

        extension = (['.nc','.sxm','.sm','.dat','poly'])[data_source-1]

        filelist = findfile(data_directory+'*'+extension)
        svec = size(filelist)
        IF (svec(0) EQ 0) THEN BEGIN
            data_filelist = ['No files']
        ENDIF ELSE BEGIN
            zstack_buildlist_stripdir, filelist, data_filelist, data_directory
        ENDELSE

        widget_control, zstack_build_list_par.directory_label, $
          set_value = ' '+data_directory
        widget_control, zstack_build_list_par.filelist_label, $
;          set_value = data_filelist
          set_value=['Select from directory',data_filelist]

		cd,data_directory	; change directory to data_directory, CGZ
		zstack_buildlist_sensitive
    END

	zstack_build_list_par.filelist_label : BEGIN
		IF (event.index GT 0) THEN BEGIN
			zstack_buildlist_desensitive
			this_filename = data_filelist(event.index-1)
			dummy = findfile(this_filename,count=count)
			IF (count NE 0) THEN BEGIN
				;zstack_buildlist_stripdir,this_filename
				zstack_buildlist_readfile
				zstack_buildlist_colorbar
				widget_control, zstack_build_list_par.display_parameters_label, sensitive = 1
			ENDIF
			widget_control, zstack_build_list_par.filelist_label, set_droplist_select = 0
			zstack_buildlist_sensitive
		ENDIF
	END

    zstack_build_list_par.first_label : BEGIN
        IF (got_a_file NE 0) THEN BEGIN
            first_ev = this_ev
            got_first = 1
            first_filename = this_filename
            widget_control, zstack_build_list_par.first_name_label,$
              set_value = ' '+this_filename
            widget_control, zstack_build_list_par.first_ev_label, $
              set_value = ' '+strtrim(string(first_ev,$
                                   format='(f10.2)'),2)+' eV'
            widget_control, zstack_build_list_par.first_wavelength_label, $
              set_value = ' '+strtrim(string(12398.52/first_ev,$
                                   format='(f10.3)'),2)+' A'
            zstack_buildlist_sensitive
        ENDIF ELSE BEGIN
            got_first = 0
            first_filename = ''
            widget_control, zstack_build_list_par.first_name_label,$
              set_value=''
            widget_control, zstack_build_list_par.first_ev_label, $
              set_value=''
            widget_control, zstack_build_list_par.first_wavelength_label, $
              set_value=''
        ENDELSE
    END

    zstack_build_list_par.last_label : BEGIN
        IF (got_a_file NE 0) THEN BEGIN
            last_ev = this_ev
            got_last = 1
            last_filename = this_filename
            widget_control, zstack_build_list_par.last_name_label,$
              set_value = ' '+this_filename
            widget_control, zstack_build_list_par.last_ev_label, $
              set_value = ' '+strtrim(string(last_ev,$
                                   format='(f10.2)'),2)+' eV'
            widget_control, zstack_build_list_par.last_wavelength_label, $
              set_value = ' '+strtrim(string(12398.52/last_ev,$
                                   format='(f10.3)'),2)+' A'
           zstack_buildlist_sensitive
        ENDIF ELSE BEGIN
            got_last = 0
            last_filename = ''
            widget_control, zstack_build_list_par.last_name_label,$
              set_value=''
            widget_control, zstack_build_list_par.last_ev_label, $
              set_value=''
            widget_control, zstack_build_list_par.last_wavelength_label, $
              set_value=''
        ENDELSE
    END

	zstack_build_list_par.save_list_filename_label : BEGIN
		temp_string = ''
		widget_control, zstack_build_list_par.save_list_filename_label, get_value = temp_string
		on_ioerror, save_list_filename_label_oops
		list_filename = strtrim(temp_string(0),2)
		IF (strlen(list_filename) NE 0) THEN BEGIN
			dotpos = strpos(list_filename,'.')
			IF (dotpos EQ -1) THEN BEGIN
				list_filename = list_filename+'.sl'
			ENDIF ELSE BEGIN	; this forces extension to be '.sl'
				IF (strpos(strlowcase(list_filename),'.sl') EQ -1) THEN BEGIN
					list_filename = str_sep(list_filename,'.')
					list_filename = list_filename(0)+'.sl'
				ENDIF
			ENDELSE
		ENDIF

		save_list_filename_label_oops :
		widget_control, zstack_build_list_par.save_list_filename_label, $
				set_value = ' '+list_filename
		zstack_buildlist_sensitive
    END

    zstack_build_list_par.save_list_label : BEGIN
		zstack_buildlist_desensitive
		zstack_buildlist_savelist
		zstack_buildlist_sensitive

    END

    zstack_build_list_par.read_list_label : BEGIN
		; Check validity of list_filename
		dummy = findfile(list_filename, count=count)
		IF (count EQ 0) THEN BEGIN	; if list_filename is not valid
			print,string(7B),'List file, '+list_filename+', not found',string(7B)
;			list_filename = ''
		ENDIF ELSE BEGIN	; if list_filename is valid
			widget_control, hourglass=1
			zstack_buildlist_desensitive
			zstack_readlist,list_filename

			got_first = 0
			first_filename = ''
			widget_control, zstack_build_list_par.first_name_label, set_value=''
			widget_control, zstack_build_list_par.first_ev_label, set_value=''
			widget_control, zstack_build_list_par.first_wavelength_label, set_value=''

			got_last = 0
			last_filename = ''
			widget_control, zstack_build_list_par.last_name_label, set_value=''
			widget_control, zstack_build_list_par.last_ev_label, set_value=''
			widget_control, zstack_build_list_par.last_wavelength_label, set_value=''
			widget_control,zstack_build_list_par.stack_filelist_label, $
						set_value = filename_display_list

			displayed_file_index = 0
			this_filename = filename_list[displayed_file_index]
			widget_control,zstack_build_list_par.stack_filelist_label, $
						set_list_select = displayed_file_index
			widget_control, zstack_build_list_par.n_files_label,$
						set_value = strtrim(string(n_files,format='(i4)'),2)
			;zstack_buildlist_stripdir,this_filename
			zstack_buildlist_readfile
			zstack_buildlist_colorbar
			widget_control, hourglass=0
			zstack_buildlist_sensitive
		ENDELSE

;	    	IF (max([n_cols,n_rows]) GT 100) THEN BEGIN
;			image_zoom = 1./round(max([n_cols,n_rows])/150.)
;			print,'buildlist : image_zoom :',image_zoom
;			print,'buildlist : image_zoom :',image_zoom
;		ENDIF ;ELSE BEGIN
;;			inv_zoom = 1
;;		ENDELSE

		Device, get_screen_size=screen_size
		CASE 1 OF
			screen_size[0] LE 900 : BEGIN
				print,'max image = 100'
				image_zoom = 1./(max([n_cols,n_rows])/100.)
			END

			(screen_size[0] LT 1100) : BEGIN
				print,'max image = 150'
				image_zoom = 1./(max([n_cols,n_rows])/150.)
			END

			(screen_size[0] LT 1200) : BEGIN
				print,'max image = 200'
				image_zoom = 1./(max([n_cols,n_rows])/200.)
			END

			(screen_size[0] LT 1300) : BEGIN
				print,'max image = 250'
				image_zoom = 1./(max([n_cols,n_rows])/250.)
			END

			screen_size[0] LT 1700 : BEGIN
				print,'max image = 350'
				image_zoom = 1./(max([n_cols,n_rows])/350.)
			END

			screen_size[0] GE 1700 : BEGIN
				print,'max image = 400'
				image_zoom = 1./(max([n_cols,n_rows])/400.)
			END

		ENDCASE
		IF (image_zoom GT 1.0) THEN BEGIN
			image_zoom = floor(image_zoom)
		ENDIF ELSE BEGIN
			image_zoom = 1./round(1./image_zoom)
		ENDELSE
		print,'buildlist read : image_zoom :',image_zoom
    END

    zstack_build_list_par.browse_list_label : BEGIN
		on_ioerror, browse_list_label_oops
		zstack_buildlist_desensitive

		cd,current=current_directory
		dummy = dialog_pickfile(filter='*.sl', /read, /fix_filter, /must_exist, $
				path=data_directory, get_path=data_directory, $
				title='Select STACK image list file')
		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_list_label_oops
				; trap if CANCEL is chosen in dialog
		ENDIF

		widget_control, hourglass=1

		; strip the directory from dummy to get list_filename
		CASE strupcase(!version.os_family) OF
			'VMS' : BEGIN
				firstpos = strpos(dummy, ']')+1
			END
			'WINDOWS' : BEGIN
				firstpos = rstrpos(dummy, '\')+1
			END
			'MACOS' : BEGIN
				firstpos = rstrpos(dummy, ':')+1
			END
			'UNIX' : BEGIN
				firstpos = rstrpos(dummy, '/')+1
			END
			ELSE : BEGIN
				print,'Unrecognized operating system'
			END
		ENDCASE

		IF (firstpos EQ -1) THEN BEGIN
			list_filename = dummy
			stripped_directory = ''
		ENDIF ELSE BEGIN
			list_filename = strmid(dummy, firstpos, (strlen(dummy)-firstpos))
			stripped_directory = strmid(dummy,0,firstpos)
		ENDELSE

		IF (strupcase(!version.os_family) EQ 'VMS') THEN BEGIN
			semipos = rstrpos(list_filename, ';')
			IF (semipos GT 1) THEN BEGIN
				list_filename = strmid(list_filename,0,semipos)
			ENDIF
		ENDIF

		widget_control, zstack_build_list_par.save_list_filename_label, $
				set_value = ' '+list_filename
		widget_control, zstack_build_list_par.directory_label, $
				set_value = ' '+stripped_directory
		cd,stripped_directory

		zstack_readlist,list_filename

		got_first = 0
		first_filename = ''
		widget_control, zstack_build_list_par.first_name_label,set_value=''
		widget_control, zstack_build_list_par.first_ev_label, set_value=''
		widget_control, zstack_build_list_par.first_wavelength_label, set_value=''

		got_last = 0
		last_filename = ''
		widget_control, zstack_build_list_par.last_name_label, set_value=''
		widget_control, zstack_build_list_par.last_ev_label, set_value=''
		widget_control, zstack_build_list_par.last_wavelength_label, set_value=''
		widget_control,zstack_build_list_par.stack_filelist_label,$
				set_value = filename_display_list

		displayed_file_index = 0
		this_filename = filename_list[displayed_file_index]
		widget_control,zstack_build_list_par.stack_filelist_label, $
				set_list_select = displayed_file_index
		widget_control, zstack_build_list_par.n_files_label,$
				set_value = strtrim(string(n_files,format='(i4)'),2)
		zstack_buildlist_readfile
		zstack_buildlist_colorbar

		widget_control, hourglass=0

		browse_list_label_oops :

        extension = (['.nc','.sxm','.sm','.dat','poly'])[data_source-1]

        filelist = findfile(data_directory+'*'+extension)
        svec = size(filelist)
        IF (svec(0) EQ 0) THEN BEGIN
            data_filelist = ['No files']
        ENDIF ELSE BEGIN
            zstack_buildlist_stripdir, filelist, data_filelist, data_directory
        ENDELSE

        widget_control, zstack_build_list_par.directory_label, $
          set_value = ' '+data_directory
        widget_control, zstack_build_list_par.filelist_label, $
;          set_value = data_filelist
          set_value=['Select from directory',data_filelist]

;	    	IF (max([n_cols,n_rows]) GT 150) THEN BEGIN
;			image_zoom = 1./round(max([n_cols,n_rows])/150.)
;			print,'buildlist : image_zoom :',image_zoom
;		ENDIF ;ELSE BEGIN
;;			inv_zoom = 1
;;		ENDELSE
		Device, get_screen_size=screen_size
		CASE 1 OF
			screen_size[0] LE 900 : BEGIN
				print,'max image = 100'
				image_zoom = 1./(max([n_cols,n_rows])/100.)
			END

			(screen_size[0] LT 1100) : BEGIN
				print,'max image = 150'
				image_zoom = 1./(max([n_cols,n_rows])/150.)
			END

			(screen_size[0] LT 1200) : BEGIN
				print,'max image = 200'
				image_zoom = 1./(max([n_cols,n_rows])/200.)
			END

			(screen_size[0] LT 1300) : BEGIN
				print,'max image = 250'
				image_zoom = 1./(max([n_cols,n_rows])/250.)
			END

			screen_size[0] LT 1700 : BEGIN
				print,'max image = 350'
				image_zoom = 1./(max([n_cols,n_rows])/350.)
			END

			screen_size[0] GE 1700 : BEGIN
				print,'max image = 400'
				image_zoom = 1./(max([n_cols,n_rows])/400.)
			END

		ENDCASE
		IF (image_zoom GT 1.0) THEN BEGIN
			image_zoom = float(floor(image_zoom))
			image_zoom = 1.0
		ENDIF ELSE BEGIN
			image_zoom = 1./float(round(1./image_zoom))
		ENDELSE
		print,'buildlist browse : image_zoom :',image_zoom
		zstack_buildlist_sensitive
	END

	zstack_build_list_par.binary_filename_label : BEGIN
		temp_string = ''
		widget_control, zstack_build_list_par.binary_filename_label, get_value = temp_string
		on_ioerror, binary_filename_label_oops
		binary_filename = strtrim(temp_string(0),2)
		IF (strlen(binary_filename) NE 0) THEN BEGIN
			dotpos = strpos(binary_filename,'.')
			IF (dotpos EQ -1) THEN BEGIN
				binary_filename = binary_filename+'.ncb'
			ENDIF ELSE BEGIN	; this forces extension to be '.sl'
				IF (strpos(strlowcase(binary_filename),'.ncb') EQ -1) THEN BEGIN
					binary_filename = str_sep(binary_filename,'.')
					binary_filename = binary_filename(0)+'.ncb'
				ENDIF
			ENDELSE
		ENDIF

		binary_filename_label_oops :
		widget_control, zstack_build_list_par.binary_filename_label, $
				set_value = ' '+binary_filename
		zstack_buildlist_sensitive
	END

;;;;;;;;;;
    zstack_build_list_par.read_binary_label : BEGIN
		; Check validity of binary_filename
		dummy = findfile(binary_filename, count=count)
		IF (count EQ 0) THEN BEGIN	; if binary_filename is not valid
			print,string(7B),'Binary file, '+binary_filename+', not found',string(7B)
;			binary_filename = ''
		ENDIF ELSE BEGIN	; if binary_filename is valid
			widget_control, hourglass=1
			zstack_buildlist_desensitive

; have to read in both binary data file and *.dat file
; recreate filename_list, ev_list, n_files, filename_display_list, n_cols, n_rows, etc
	;	zstack_readlist,binary_filename
;	help, list_filename
			zstack_buildlist_read_binary, binary_filename
			got_first = 0
			first_filename = ''
			widget_control, zstack_build_list_par.first_name_label, set_value=''
			widget_control, zstack_build_list_par.first_ev_label, set_value=''
			widget_control, zstack_build_list_par.first_wavelength_label, set_value=''

			got_last = 0
			last_filename = ''
			widget_control, zstack_build_list_par.last_name_label, set_value=''
			widget_control, zstack_build_list_par.last_ev_label, set_value=''
			widget_control, zstack_build_list_par.last_wavelength_label, set_value=''
			widget_control,zstack_build_list_par.stack_filelist_label, $
						set_value = filename_display_list

			displayed_file_index = 0
			this_filename = filename_list[displayed_file_index]
			widget_control,zstack_build_list_par.stack_filelist_label, $
						set_list_select = displayed_file_index
			widget_control, zstack_build_list_par.n_files_label,$
						set_value = strtrim(string(n_files,format='(i4)'),2)
			;zstack_buildlist_stripdir,this_filename
;			zstack_buildlist_readfile
			zstack_buildlist_imgdisp, displayed_file_index
			zstack_buildlist_colorbar
			widget_control, hourglass=0
			zstack_buildlist_sensitive

		ENDELSE

		Device, get_screen_size=screen_size
		CASE 1 OF
			screen_size[0] LE 900 : BEGIN
				print,'max image = 100'
				image_zoom = 1./(max([n_cols,n_rows])/100.)
			END

			(screen_size[0] LT 1100) : BEGIN
				print,'max image = 150'
				image_zoom = 1./(max([n_cols,n_rows])/150.)
			END

			(screen_size[0] LT 1200) : BEGIN
				print,'max image = 200'
				image_zoom = 1./(max([n_cols,n_rows])/200.)
			END

			(screen_size[0] LT 1300) : BEGIN
				print,'max image = 250'
				image_zoom = 1./(max([n_cols,n_rows])/250.)
			END

			screen_size[0] LT 1700 : BEGIN
				print,'max image = 350'
				image_zoom = 1./(max([n_cols,n_rows])/350.)
			END

			screen_size[0] GE 1700 : BEGIN
				print,'max image = 400'
				image_zoom = 1./(max([n_cols,n_rows])/400.)
			END

		ENDCASE
		IF (image_zoom GT 1.0) THEN BEGIN
			image_zoom = floor(image_zoom)
		ENDIF ELSE BEGIN
			image_zoom = 1./round(1./image_zoom)
		ENDELSE
		print,'buildlist binary read : image_zoom :',image_zoom

    END

    zstack_build_list_par.browse_binary_label : BEGIN
		on_ioerror, browse_binary_label_oops
		zstack_buildlist_desensitive

		cd,current=current_directory
		dummy = dialog_pickfile(filter='*.ncb', /read, /fix_filter, /must_exist, $
				path=data_directory, get_path=data_directory, $
				title='Select binary STACK image file')
		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_binary_label_oops
				; trap if CANCEL is chosen in dialog
		ENDIF

		widget_control, hourglass=1

		; strip the directory from dummy to get binary_filename
		CASE strupcase(!version.os_family) OF
			'VMS' : BEGIN
				firstpos = strpos(dummy, ']')+1
			END
			'WINDOWS' : BEGIN
				firstpos = rstrpos(dummy, '\')+1
			END
			'MACOS' : BEGIN
				firstpos = rstrpos(dummy, ':')+1
			END
			'UNIX' : BEGIN
				firstpos = rstrpos(dummy, '/')+1
			END
			ELSE : BEGIN
				print,'Unrecognized operating system'
			END
		ENDCASE

		IF (firstpos EQ -1) THEN BEGIN
			binary_filename = dummy
			stripped_directory = ''
		ENDIF ELSE BEGIN
			binary_filename = strmid(dummy, firstpos, (strlen(dummy)-firstpos))
			stripped_directory = strmid(dummy,0,firstpos)
		ENDELSE

		IF (strupcase(!version.os_family) EQ 'VMS') THEN BEGIN
			semipos = rstrpos(binary_filename, ';')
			IF (semipos GT 1) THEN BEGIN
				binary_filename = strmid(binary_filename,0,semipos)
			ENDIF
		ENDIF

		widget_control, zstack_build_list_par.binary_filename_label, $
				set_value = ' '+binary_filename
		widget_control, zstack_build_list_par.directory_label, $
				set_value = ' '+stripped_directory
		cd,stripped_directory

; have to read in both binary data file and *.dat file
; recreate filename_list, ev_list, n_files, filename_display_list, n_cols, n_rows, etc
	;	zstack_readlist,binary_filename
	zstack_buildlist_read_binary, binary_filename

		got_first = 0
		first_filename = ''
		widget_control, zstack_build_list_par.first_name_label,set_value=''
		widget_control, zstack_build_list_par.first_ev_label, set_value=''
		widget_control, zstack_build_list_par.first_wavelength_label, set_value=''

		got_last = 0
		last_filename = ''
		widget_control, zstack_build_list_par.last_name_label, set_value=''
		widget_control, zstack_build_list_par.last_ev_label, set_value=''
		widget_control, zstack_build_list_par.last_wavelength_label, set_value=''
		widget_control,zstack_build_list_par.stack_filelist_label,$
				set_value = filename_display_list

		displayed_file_index = 0
		this_filename = filename_list[displayed_file_index]
		widget_control,zstack_build_list_par.stack_filelist_label, $
				set_value = filename_display_list
		widget_control,zstack_build_list_par.stack_filelist_label, $
				set_list_select = displayed_file_index
		widget_control, zstack_build_list_par.n_files_label,$
				set_value = strtrim(string(n_files,format='(i4)'),2)
;		zstack_buildlist_readfile
		zstack_buildlist_colorbar

		widget_control, hourglass=0

		browse_binary_label_oops :

        extension = (['.nc','.sxm','.sm','.dat','poly'])[data_source-1]

        filelist = findfile(data_directory+'*'+extension)
        svec = size(filelist)
        IF (svec(0) EQ 0) THEN BEGIN
            data_filelist = ['No files']
        ENDIF ELSE BEGIN
            zstack_buildlist_stripdir, filelist, data_filelist, data_directory
        ENDELSE

        widget_control, zstack_build_list_par.directory_label, $
          set_value = ' '+data_directory
        widget_control, zstack_build_list_par.filelist_label, $
          set_value=['Select from directory',data_filelist]

		Device, get_screen_size=screen_size
		CASE 1 OF
			screen_size[0] LE 900 : BEGIN
				print,'max image = 100'
				image_zoom = 1./(max([n_cols,n_rows])/100.)
			END

			(screen_size[0] LT 1100) : BEGIN
				print,'max image = 150'
				image_zoom = 1./(max([n_cols,n_rows])/150.)
			END

			(screen_size[0] LT 1200) : BEGIN
				print,'max image = 200'
				image_zoom = 1./(max([n_cols,n_rows])/200.)
			END

			(screen_size[0] LT 1300) : BEGIN
				print,'max image = 250'
				image_zoom = 1./(max([n_cols,n_rows])/250.)
			END

			screen_size[0] LT 1700 : BEGIN
				print,'max image = 350'
				image_zoom = 1./(max([n_cols,n_rows])/350.)
			END

			screen_size[0] GE 1700 : BEGIN
				print,'max image = 400'
				image_zoom = 1./(max([n_cols,n_rows])/400.)
			END

		ENDCASE
		IF (image_zoom GT 1.0) THEN BEGIN
			image_zoom = floor(image_zoom)
		ENDIF ELSE BEGIN
			image_zoom = 1./round(1./image_zoom)
		ENDELSE
		print,'buildlist browse : image_zoom :',image_zoom

		zstack_buildlist_imgdisp, displayed_file_index
		zstack_buildlist_sensitive
	END

;;;;;;;;;;

    zstack_build_list_par.add_label : BEGIN
        on_ioerror, add_label_oops
		zstack_buildlist_desensitive
        widget_control, hourglass=1
        zstack_buildlist_doit

        widget_control, zstack_build_list_par.n_files_label,$
            set_value = strtrim(string(n_files,format='(i4)'),2)
        got_a_file = 0
        got_first = 0
        first_filename = ''
        widget_control, zstack_build_list_par.first_name_label,$
            set_value=''
        widget_control, zstack_build_list_par.first_ev_label, $
            set_value=''
        widget_control, zstack_build_list_par.first_wavelength_label, $
            set_value=''
        got_last = 0
        last_filename = ''
        widget_control, zstack_build_list_par.last_name_label,$
            set_value=''
        widget_control, zstack_build_list_par.last_ev_label, $
            set_value=''
        widget_control, zstack_build_list_par.last_wavelength_label, $
            set_value=''

		; reset value of shift_filename if list_filename exists and shift_filename is not already defined
		; ASSUMES NSLS NAMING FORMAT
;		IF (strlen(list_filename) EQ 0) THEN BEGIN
			num = strmid(filename_list(0),0,strpos(filename_list(0),'.'))
			list_filename = strmid(num,0,strlen(num)-3)
			list_filename = temporary(list_filename) + strmid(num,strlen(num)-3,strlen(num))
			num = strmid(filename_list(n_files-1),0,strpos(filename_list(n_files-1),'.'))
			list_filename = temporary(list_filename) + '_' + strmid(num,strlen(num)-3,strlen(num))
			list_filename = temporary(list_filename) + '.sl'
			widget_control, zstack_build_list_par.save_list_filename_label, $
					set_value = ' '+list_filename
;		ENDIF

        add_label_oops :
        displayed_file_index = 0
        zstack_buildlist_imgdisp,displayed_file_index
        widget_control, hourglass=0

;	    	IF (max([n_cols,n_rows]) GT 150) THEN BEGIN
;			image_zoom = 1./round(max([n_cols,n_rows])/150.)
;			print,'buildlist : image_zoom :',image_zoom
;		ENDIF ;ELSE BEGIN
;;			inv_zoom = 1
;;		ENDELSE
		Device, get_screen_size=screen_size
		CASE 1 OF
			screen_size[0] LE 900 : BEGIN
				print,'max image = 100'
				image_zoom = 1./(max([n_cols,n_rows])/100.)
			END

			(screen_size[0] LT 1100) : BEGIN
				print,'max image = 150'
				image_zoom = 1./(max([n_cols,n_rows])/150.)
			END

			(screen_size[0] LT 1200) : BEGIN
				print,'max image = 200'
				image_zoom = 1./(max([n_cols,n_rows])/200.)
			END

			(screen_size[0] LT 1300) : BEGIN
				print,'max image = 250'
				image_zoom = 1./(max([n_cols,n_rows])/250.)
			END

			screen_size[0] LT 1700 : BEGIN
				print,'max image = 350'
				image_zoom = 1./(max([n_cols,n_rows])/350.)
			END

			screen_size[0] GE 1700 : BEGIN
				print,'max image = 400'
				image_zoom = 1./(max([n_cols,n_rows])/400.)
			END

		ENDCASE
		IF (image_zoom GT 1.0) THEN BEGIN
			image_zoom = floor(image_zoom)
		ENDIF ELSE BEGIN
			image_zoom = 1./round(1./image_zoom)
		ENDELSE

		print,'buildlist add : image_zoom :',image_zoom
        zstack_buildlist_sensitive
    END

    zstack_build_list_par.reset_list_label : BEGIN
        zstack_buildlist_desensitive
	n_files = 0
	filename_list = ''
	ev_list = ''
	msec_list = ''
	filename_display_list = ''
	got_first = 0L
	got_last = 0L
	got_a_file = 0L
	this_filename = ''
	first_filename = ''
	last_filename = ''
	n_cols = 0
	n_rows = 0
	image_zoom = 1.0
	list_filename = ''
        widget_control, zstack_build_list_par.n_files_label,$
            set_value = strtrim(string(n_files,format='(i4)'),2)
        widget_control, zstack_build_list_par.first_name_label,$
            set_value=''
        widget_control, zstack_build_list_par.first_ev_label, $
            set_value=''
        widget_control, zstack_build_list_par.first_wavelength_label, $
            set_value=''
        widget_control, zstack_build_list_par.last_name_label,$
            set_value=''
        widget_control, zstack_build_list_par.last_ev_label, $
            set_value=''
        widget_control, zstack_build_list_par.last_wavelength_label, $
            set_value=''
        widget_control,zstack_build_list_par.stack_filelist_label,$
          set_value = ['']

		widget_control, zstack_build_list_par.save_list_filename_label, $
				set_value = ' '+list_filename
	widget_control,zstack_build_list_par.this_file_label, set_value=''
	widget_control,zstack_build_list_par.this_row_col_label, set_value=''
	widget_control,zstack_build_list_par.this_ev_label, set_value=''
	widget_control,zstack_build_list_par.this_wavelength_label, set_value=''
	widget_control,zstack_build_list_par.this_dwell_label, set_value=''
	wset,zstack_build_list_par.this_image_win
	erase

        zstack_buildlist_sensitive
    END

	zstack_build_list_par.list_complete_label : BEGIN
;		IF (max([n_cols,n_rows]) GT 150) THEN BEGIN
;			image_zoom = 1./round(max([n_cols,n_rows])/150.)
;			print,'buildlist : image_zoom :',image_zoom
;		ENDIF ;ELSE BEGIN
;;			inv_zoom = 1
;;		ENDELSE

		return_filename_list = filename_list
		widget_control,zstack_build_list_par.main_base,/destroy

		n_files = n_elements(filename_list)
		IF n_elements(axis_call) NE 0 THEN BEGIN	; make sure axis_call is defined
			IF ((axis_call EQ 1) AND (n_files NE 0)) THEN BEGIN
				zstack_analyze_align
			ENDIF
		ENDIF
;        return
    END

    zstack_build_list_par.stack_filelist_label : BEGIN
        zstack_buildlist_desensitive
        displayed_file_index = event.index
        this_filename = filename_list[displayed_file_index]
;        zstack_buildlist_readfile
        zstack_buildlist_imgdisp, displayed_file_index
        zstack_buildlist_colorbar
        zstack_buildlist_sensitive
    END

    zstack_build_list_par.delete_label : BEGIN
        zstack_buildlist_desensitive
        widget_control, hourglass=1
		; need to reset n_files, ev_list, msec_list, filename_list, filename_display_list and image_stack
		print,'Deleting ' + filename_display_list(displayed_file_index)

		CASE displayed_file_index OF
			0 : BEGIN
				ev_list = ev_list[1:n_files-1]
				msec_list = msec_list[1:n_files-1]
				filename_list = filename_list[1:n_files-1]
				filename_display_list = filename_display_list[1:n_files-1]
				image_stack = [[temporary(image_stack[*,*,1:n_files-1])]]
			END
			n_files-1 : BEGIN
				ev_list = [ev_list[0:n_files-2]]
				msec_list = [msec_list[0:n_files-2]]
				filename_list = [filename_list[0:n_files-2]]
				filename_display_list = [filename_display_list[0:n_files-2]]
				image_stack = [ [[temporary(image_stack[*,*,0:n_files-2])]] ]
			END
			ELSE : BEGIN
				ev_list = [ev_list[0:displayed_file_index-1],ev_list[displayed_file_index+1:n_files-1]]
				msec_list = [msec_list[0:displayed_file_index-1],msec_list[displayed_file_index+1:n_files-1]]
				filename_list = [filename_list[0:displayed_file_index-1],filename_list[displayed_file_index+1:n_files-1]]
				filename_display_list = [filename_display_list[0:displayed_file_index-1],filename_display_list[displayed_file_index+1:n_files-1]]
				image_stack = [ [[temporary(image_stack[*,*,0:displayed_file_index-1])]], $
							[[temporary(image_stack[*,*,displayed_file_index+1:n_files-1])]] ]
			END
		ENDCASE

		n_files = n_files - 1

		widget_control,zstack_build_list_par.stack_filelist_label,$
			set_value = filename_display_list
		widget_control, zstack_build_list_par.n_files_label,$
			set_value = strtrim(string(n_files,format='(i4)'),2)

        displayed_file_index = (( displayed_file_index >0.) <(n_files-1) )

        zstack_buildlist_imgdisp,displayed_file_index

		; reset value of shift_filename if list_filename exists and shift_filename is not already defined
		; ASSUMES NSLS NAMING FORMAT
;		IF (strlen(list_filename) EQ 0) THEN BEGIN
			num = strmid(filename_list(0),0,strpos(filename_list(0),'.'))
			list_filename = strmid(num,0,strlen(num)-3)
			list_filename = temporary(list_filename) + strmid(num,strlen(num)-3,strlen(num))
			num = strmid(filename_list(n_files-1),0,strpos(filename_list(n_files-1),'.'))
			list_filename = temporary(list_filename) + '_' + strmid(num,strlen(num)-3,strlen(num))
			list_filename = temporary(list_filename) + '.sl'
			widget_control, zstack_build_list_par.save_list_filename_label, $
					set_value = ' '+list_filename
;		ENDIF

        widget_control, hourglass=0
        zstack_buildlist_sensitive
    END

	zstack_build_list_par.next_image_label : BEGIN
		IF (displayed_file_index LT (n_files-1)) THEN BEGIN
			displayed_file_index = displayed_file_index+1
		ENDIF ELSE BEGIN
			displayed_file_index = 0
		ENDELSE
		zstack_buildlist_imgdisp,displayed_file_index
	END

	zstack_build_list_par.prev_image_label : BEGIN
		IF (displayed_file_index GT 0) THEN BEGIN
			displayed_file_index = displayed_file_index-1
		ENDIF ELSE BEGIN
			displayed_file_index = n_files-1
		ENDELSE
		zstack_buildlist_imgdisp,displayed_file_index
	END

	zstack_build_list_par.play_movie_label : BEGIN
		movie_active = 1
		zstack_buildlist_desensitive
		FOR i=0,(n_files-1) DO BEGIN
			IF (displayed_file_index LT (n_files-1)) THEN BEGIN
				displayed_file_index = displayed_file_index+1
			ENDIF ELSE BEGIN
				displayed_file_index = 0
			ENDELSE
			zstack_buildlist_imgdisp, displayed_file_index
			wait,movie_delay
		ENDFOR
		movie_active = 0
		zstack_buildlist_sensitive
	END

	zstack_build_list_par.display_parameters_label : BEGIN
		svec = size(filename_list)
		IF (svec(0) EQ 0) THEN BEGIN
			image_stack = float(image_data(*,*,0))
		ENDIF
		zstack_buildlist_desensitive
		wshow,zstack_build_list_par.main_base_win,0
		zstack_display,'buildlist'
	END

ENDCASE
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist_dialog, Group_Leader_ID=groupLeader

;print,'zstack_buildlist_dialog'

@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=scr_dims

IF (n_tags(zstack_build_list_par) EQ 0) THEN BEGIN
    	zstack_build_list_par = $
    	{	zstack_build_list_par			    , $
		main_base					: 0L, $
		directory_label				: 0L, $
		browse_directory_label		: 0L, $
		filelist_label				: 0L, $
		this_file_label				: 0L, $
		this_ev_label				: 0L, $
		this_wavelength_label			: 0L, $
		this_row_col_label			: 0L, $
		this_dwell_label			: 0L, $
		this_image_label			: 0L, $
		colorbar_label				: 0L, $
		prev_image_label			: 0L, $
		next_image_label			: 0L, $
		play_movie_label			: 0L, $
		display_parameters_label		: 0L, $
		first_label				: 0L, $
		first_name_label			: 0L, $
		first_ev_label				: 0L, $
		first_wavelength_label		: 0L, $
		last_label					: 0L, $
		last_name_label				: 0L, $
		last_ev_label				: 0L, $
		last_wavelength_label			: 0L, $
		save_list_filename_label		: 0L, $
		save_list_label				: 0L, $
		read_list_label				: 0L, $
		browse_list_label			: 0L, $
		stack_filelist_label			: 0L, $
		binary_filename_label			: 0L, $
		read_binary_label			: 0L, $
		browse_binary_label			: 0L, $
		add_label					: 0L, $
		delete_label				: 0L, $
		reset_list_label			: 0L, $
		list_complete_label			: 0L, $
		n_files_label				: 0L, $
		this_image_win				: 0L, $
		colorbar_win				: 0L, $
		main_base_win				: 0L  $
	}
ENDIF
comp_screen_res=GET_SCREEN_SIZE()

IF N_Elements(groupLeader) EQ 0 THEN BEGIN
	IF !version.os_family EQ 'Windows' then begin
		zstack_build_list_par.main_base = widget_base(title='ZSTACK Buildlist', /col, /scroll)
	ENDIF else begin
		zstack_build_list_par.main_base = widget_base(title='ZSTACK Buildlist', /col, $
                       X_SCROLL_SIZE=comp_screen_res(0)*.65,Y_SCROLL_SIZE=comp_screen_res(1)*.90)
	ENDELSE
ENDIF ELSE BEGIN
	zstack_build_list_par.main_base = widget_base(title='ZSTACK Buildlist', /col, $
			/Modal, Group_Leader=groupLeader )
ENDELSE

;zstack_build_list_par.main_base = widget_base(title='ZSTACK Buildlist', /col, /scroll )
row1 = widget_base(zstack_build_list_par.main_base,/row,/frame)
row2 = widget_base(zstack_build_list_par.main_base,/row)
row3 = widget_base(zstack_build_list_par.main_base,/row)	;,/align_center)

zstack_build_list_par.browse_directory_label = widget_button(row1,value='Directory:')
;zlabel = widget_label(row1,value='Current directory:')
zstack_build_list_par.directory_label = widget_text(row1,value='', xsize=100, /editable)
;zstack_build_list_par.browse_directory_label = widget_button(row1,value='Browse')

col1 = widget_base(row2,/col)
col2 = widget_base(row2,/col)
col3 = widget_base(row2,/col)

base = widget_base(col2,/row,/frame,/align_center)
col2a = widget_base(base,/col,space=0)
row = widget_base(col2a,/row,/align_center)
;zlabel = widget_label(col2a,value='File Parameters: ')
zstack_build_list_par.filelist_label = widget_droplist(row,value='Select from directory', scr_xsize=160, scr_ysize=20)
row = widget_base(col2a,/row,/align_center)
zstack_build_list_par.this_file_label = widget_text(row,value='',xsize=25)
row = widget_base(col2a,/row,/align_center)
zstack_build_list_par.this_ev_label = widget_text(row,value='',xsize=25)
row = widget_base(col2a,/row,/align_center)
zstack_build_list_par.this_wavelength_label = widget_text(row,value='',xsize=25)
row = widget_base(col2a,/row,/align_center)
zstack_build_list_par.this_row_col_label = widget_text(row,value='',xsize=25)
row = widget_base(col2a,/row,/align_center)
zstack_build_list_par.this_dwell_label = widget_text(row,value='',xsize=25)
col2b = widget_base(base,/col,space=0)
row = widget_base(col2b,/row,/align_center)
zstack_build_list_par.this_image_label = widget_draw(row,xsize=150,ysize=150)
row = widget_base(col2b,/row,/align_center)
zstack_build_list_par.colorbar_label = widget_draw(row,xsize=150,ysize=10,sensitive=0)

;zstack_build_list_par.filename_display_list_label = widget_droplist( col2, value = 'Select File')
;zstack_build_list_par.filelist_label = widget_droplist(col2,value='Select File', scr_xsize=160, scr_ysize=20)
row = widget_base(col2, /row)
zstack_build_list_par.prev_image_label = widget_button(col2, value='Display Previous Image')
zstack_build_list_par.next_image_label = widget_button(col2, value='Display Next Image')
zstack_build_list_par.play_movie_label = widget_button(col2,value='Play movie')
row = widget_base(col2, /row,/align_center)
zstack_build_list_par.display_parameters_label = widget_button(row,value='Display Parameters')


base = widget_base(col2,/row,/align_center)
first_base = widget_base(base,/col,/frame,space=0)
row = widget_base(first_base,/row)
zstack_build_list_par.first_label = widget_button(row,value='Set as first')
row = widget_base(first_base,/row)
zstack_build_list_par.first_name_label = widget_text(row,value='',xsize=15)
row = widget_base(first_base,/row)
zstack_build_list_par.first_eV_label = widget_text(row,value='',xsize=15)
row = widget_base(first_base,/row)
zstack_build_list_par.first_wavelength_label = widget_text(row,value='',xsize=15)

last_base = widget_base(base,/col,/frame,space=0)
row = widget_base(last_base,/row)
zstack_build_list_par.last_label = widget_button(row,value='Set as last ')
row = widget_base(last_base,/row)
zstack_build_list_par.last_name_label = widget_text(row,value='',xsize=15)
row = widget_base(last_base,/row)
zstack_build_list_par.last_eV_label = widget_text(row,value='',xsize=15)
row = widget_base(last_base,/row)
zstack_build_list_par.last_wavelength_label = widget_text(row,value='',xsize=15)

save_base = widget_base( base, /col,/frame,space=0 )
row = widget_base(save_base,/col,/align_center)
zlabel = widget_label( row, value='Filename (*.sl):' )
row = widget_base(save_base,/col,/align_center)
zstack_build_list_par.save_list_filename_label = widget_text(row,value='',xsize=20,/editable)
row = widget_base(save_base,/col,/align_center)
zstack_build_list_par.save_list_label = widget_button(row,value='  Save list  ')
row = widget_base(save_base,/col,/align_center)
zstack_build_list_par.read_list_label = widget_button(row,value='  Read list  ')
row = widget_base(save_base,/col,/align_center)
zstack_build_list_par.browse_list_label = widget_button(row,value='Browse *.sl')

CASE strupcase(!version.os_family) OF
	'VMS' : BEGIN
		zstack_build_list_par.stack_filelist_label = widget_list( col3, $
					value = '',xsize = 35,ysize=34)
	END
	'WINDOWS' : BEGIN
		zstack_build_list_par.stack_filelist_label = widget_list( col3, $
				value = '',xsize = 35,ysize=25)
	END
	'MACOS' : BEGIN
		zstack_build_list_par.stack_filelist_label = widget_list( col3, $
				value = '',xsize = 35,ysize=34)
	END
	'UNIX' : BEGIN
		zstack_build_list_par.stack_filelist_label = widget_list( col3, $
				value = '',xsize = 35,ysize=34)
	END
	ELSE : BEGIN
		print,'Unrecognized operating system'
	END
ENDCASE

;zstack_build_list_par.stack_filelist_label = widget_list( col3,value = '',xsize = 40,ysize=45)
;zstack_build_list_par.stack_filelist_label = widget_list( col3,value = '',xsize = 35,ysize=34)

frame = widget_base(col3,/frame,/align_center)
base = widget_base(frame,/col,space=0)
row = widget_base(base,/row)
zlabel = widget_label( row, value='Binary Filename (*.ncb) :' )
zstack_build_list_par.binary_filename_label = widget_text( row, value='', xsize=20, /editable)
row = widget_base(base,/row,/align_center)
zstack_build_list_par.read_binary_label = widget_button( row, value='  Read *.ncb  ')
zstack_build_list_par.browse_binary_label = widget_button( row, value='Browse *.ncb')


zstack_build_list_par.add_label = widget_button( row3,value='Add first -> last to list')
zstack_build_list_par.delete_label = widget_button( row3, value = 'Delete from list' )
zstack_build_list_par.reset_list_label = widget_button( row3, value = 'Reset list' )
zstack_build_list_par.list_complete_label = widget_button( row3, value = 'List is complete' )
zlabel = widget_label(row3, value='Number of Files =')
zstack_build_list_par.n_files_label = widget_label(row3, $
			value='0')
;			value = strtrim(string(n_files,format='(i4)'),2))

;;;;;;;;;;

Device, get_screen_size=screen_size
screen_center = [ screen_size(0) / 2 , screen_size(1) / 2 ]
geom = Widget_Info(zstack_build_list_par.main_base, /Geometry)
base_size = [geom.scr_xsize,geom.scr_ysize]
x_base_size = (fix(0.90*screen_size[0]) < base_size[0])
y_base_size = (fix(0.95*screen_size[1]) < base_size[1])
halfsize = [ x_base_size / 2 , y_base_size / 2 ]
widget_control, zstack_build_list_par.main_base, $
	XOffset = screen_center[0] - halfsize[0], $
	YOffset = screen_center[1] - halfsize[1], $
	scr_xsize = x_base_size, $
	scr_ysize = y_base_size

widget_control, zstack_build_list_par.main_base, /realize

zstack_build_list_par.main_base_win = !d.window
widget_control,zstack_build_list_par.this_image_label, get_value = window
zstack_build_list_par.this_image_win = window
widget_control,zstack_build_list_par.colorbar_label, get_value = window
zstack_build_list_par.colorbar_win = window

; make uneditable text widgets inactive
widget_control, zstack_build_list_par.this_file_label, sensitive = 0
widget_control, zstack_build_list_par.this_ev_label, sensitive = 0
widget_control, zstack_build_list_par.this_wavelength_label, sensitive = 0
widget_control, zstack_build_list_par.this_row_col_label, sensitive = 0
widget_control, zstack_build_list_par.this_dwell_label, sensitive = 0
widget_control, zstack_build_list_par.this_image_label, sensitive = 0
widget_control, zstack_build_list_par.first_name_label, sensitive = 0
widget_control, zstack_build_list_par.first_eV_label, sensitive = 0
widget_control, zstack_build_list_par.first_wavelength_label, sensitive = 0
widget_control, zstack_build_list_par.last_name_label, sensitive = 0
widget_control, zstack_build_list_par.last_eV_label, sensitive = 0
widget_control, zstack_build_list_par.last_wavelength_label, sensitive = 0
widget_control, zstack_build_list_par.stack_filelist_label, sensitive = 0


return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO zstack_buildlist, return_filename_list, $
		stxm=stxm, sxm=sxm, sm=sm, als=als, poly=poly, Group_Leader_ID=groupLeader

;print,'zstack_buildlist'

@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

on_error,2

key_vec = [keyword_set(stxm),keyword_set(sxm),keyword_set(sm),keyword_set(als)]
dummy = where(key_vec EQ 1,count)
IF (count EQ 0) THEN BEGIN
	IF (n_elements(data_source) EQ 0) THEN BEGIN
		print,'Assuming files are /stxm type'
		data_source = 1
	ENDIF
ENDIF ELSE BEGIN
	IF (count NE 1) THEN BEGIN
		print,'Can not specify multiple data types - halting execution'
		return
	ENDIF
	data_source = dummy +1
ENDELSE

cd,current=current_dir
data_directory = current_dir

last_char = strmid(data_directory,strlen(data_directory)-1,1)

CASE strupcase(!version.os_family) OF
	'VMS' : BEGIN
		IF (last_char NE ']') THEN BEGIN
			data_directory = data_directory+']'
		ENDIF
	END
	'WINDOWS' : BEGIN
		IF (last_char NE '\') THEN BEGIN
			data_directory = data_directory+'\'
		ENDIF
	END
	'MACOS' : BEGIN
		IF (last_char NE ':') THEN BEGIN
			data_directory = data_directory+':'
		ENDIF
	END
	'UNIX' : BEGIN
		IF (last_char NE '/') THEN BEGIN
			data_directory = data_directory+'/'
		ENDIF
	END
	ELSE : BEGIN
		print,'Unrecognized operating system'
	END
ENDCASE

extension = (['.nc','.sxm','.sm','.dat','.poly'])[data_source-1]

filelist = findfile(data_directory+'*'+extension)
svec = size(filelist)
IF (svec(0) EQ 0) THEN BEGIN
    data_filelist = ['No files']
ENDIF ELSE BEGIN
    zstack_buildlist_stripdir, filelist, data_filelist, data_directory
ENDELSE

n_files = 0
filename_list = ''
ev_list = ''
msec_list = ''
filename_display_list = ''
got_first = 0L
got_last = 0L
got_a_file = 0L
this_filename = ''
first_filename = ''
last_filename = ''
list_filename = ''
n_cols = 0
n_rows = 0
movie_active = 0
image_range = 0
IF (n_elements(disp_min) EQ 0) THEN zstack_buildlist_prep

zstack_buildlist_dialog, Group_Leader_ID=groupLeader

widget_control, zstack_build_list_par.directory_label, set_value=' '+data_directory
widget_control, zstack_build_list_par.filelist_label, set_value=['Select from directory',data_filelist]

zstack_buildlist_sensitive

xmanager, 'zstack_buildlist', zstack_build_list_par.main_base, $
  group_leader = zstack_build_list_par.main_base

return
END
