FORWARD_FUNCTION dicw_fnfinder, dicw_fnfinder_event, dicw_fnfinder_setval, $
	dicw_fnfinder_getval, filedialog_opts__define

;;-----------------------------------------------------------------------------
;; PURPOSE:
;;	Creates a compound widget that contains a text box and a browse button
;;	to identify a filename
;;
;; CALLING SEQUENCE:
;;	ID = dicw_fnfinder(parent, UNAME=uname, UVALUE=uvalue, VALUE=value, $
;;		/SENSITIVE, FILTER=filter, /READ, /WRITE, TITLE=title, $
;;		/ALIGN_BOTTOM, /ALIGN_CENTER, /ALIGN_TOP, /ALIGN_RIGHT, $
;;		/ALIGN_LEFT, LABEL=label, XSIZE=xsize)
;;
;; REQUIRED INPUTS:
;;	parent - the parent of this widget
;;
;; OUTPUTS:
;;	The widget ID of the compound widget
;;
;; OPTIONAL INPUT KEYWORDS:
;;	UNAME - User name
;;	UVALUE - User value
;;	VALUE - Initial value of the widget
;;	SENSITIVE - If the widget is sensitive to user input
;;	FILTER - scalar or array of strings for the types of files to display
;;		in the file seclection dialog
;;	READ - causes the file selection dialog to have the title 
;;		'Select File to Read'
;;	WRITE - causes the file selction dialog to have the title
;;		'Select File to Write'. This must be set in order to specify
;;		a file that does not exist on a Mac
;;	TITLE - the title of the file selection dialog
;;	ALIGN_* - Align the widget in the appropriate way with respect to its 
;;		parent
;;	LABEL - A label to display above the file choose dialog
;;	XSIZE - The size in characters of the text box
;;
;; EVENTS PRODUCED:
;;	Whenever the chosen filename changes, the following event is created
;;	{DICW_FNFINDER, ID:0, TOP:0, HANDLER:0, VALUE:''}
;;
;; EXAMPLE:
;;      IDL> dicw_fnfinder, base, 'This is a test'
;;
;; PROCEDURES USED (i.e. called directly!):
;;
;; MODIFICATION HISTORY:
;;   2004-07-29  M. Desnoyer    Created
;;
;;-----------------------------------------------------------------------------

;;-----------------------------------
;; Structure specifying options for the file selection dialog
;;-----------------------------------
PRO filedialog_opts__define

tmp = {filedialog_opts, filter:'', read:0B, write:0B, title:''}

END

;;-----------------------------------
;; Event handler for compound widget
;;-----------------------------------
FUNCTION dicw_fnfinder_event, ev
IF tag_names(ev, /structure_name) EQ 'WIDGET_BUTTON' THEN BEGIN
	;; Get the options for the file dialog
	widget_control, ev.ID, get_uvalue=opts

	;; Get the path of the currently chosen file
	widget_control, widget_info(ev.HANDLER, find_by_uname='fnbox'), $
		get_value=fn
	fn=fn[0]
	IF fn NE '' THEN BEGIN
		pos = strpos(fn, path_sep(), /reverse_search)
		IF pos NE -1 THEN path = strmid(fn, 0, pos)
	ENDIF

	;; Query the user for the filename
	fn = dialog_pickfile(filter=opts.filter, read=opts.read, $
		write=opts.write, title=opts.title, file=fn, path=path, $
		dialog_parent=ev.TOP)

	;; Update the text box
	IF fn NE '' THEN BEGIN
		txt = widget_info(ev.handler, find_by_uname='fnbox')
		widget_control, txt, set_value=fn
	ENDIF ELSE RETURN, 0
ENDIF ELSE IF strcmp(tag_names(ev, /structure_name),'WIDGET_TEXT',11) THEN BEGIN
	;; Don't report a selection changet
	IF ev.type EQ 3 THEN RETURN, 0 $
	ELSE widget_control, ev.ID, get_value=fn
ENDIF ELSE message, 'Invalid event'
	
;; Put together the event to send on
RETURN, {DICW_FNFINDER, ID:ev.handler, TOP:ev.top, HANDLER:ev.handler, $
	VALUE:fn[0]}
END

;;-----------------------------------
;; Set value handler
;;-----------------------------------
PRO dicw_fnfinder_setval, id, value
ON_ERROR, 2

txt = widget_info(id, find_by_uname='fnbox')
IF txt EQ 0 THEN message, 'Widget is broken'
widget_control, txt, set_value=value

END

;;-----------------------------------
;; Get value handler
;;-----------------------------------
FUNCTION dicw_fnfinder_getval, id
ON_ERROR, 2

txt = widget_info(id, find_by_uname='fnbox')
IF txt EQ 0 THEN message, 'Widget is broken'
widget_control, txt, get_value=value
RETURN, value

END

;;-----------------------------------
;; Widget creation function
;;-----------------------------------
FUNCTION DIcw_fnfinder, parent, UNAME=uname, UVALUE=uvalue, VALUE=value, $
	SENSITIVE=sensitive, FILTER=filter, READ=read, WRITE=write, $
	TITLE=title, ALIGN_BOTTOM=align_bottom, ALIGN_CENTER=align_center, $
	ALIGN_TOP=align_top, ALIGN_LEFT=align_left, ALIGN_RIGHT=align_right, $
	LABEL=label, XSIZE=xsize

ON_ERROR, 2

;; Default the keywords
IF NOT keyword_set(uname) THEN uname = 'DICW_FNFINDER'
IF NOT keyword_set(uvalue) THEN uvalue = 0
IF NOT keyword_set(value) THEN value = ''
IF NOT keyword_set(filter) THEN filter='*'
IF NOT keyword_set(read) THEN read = 0
IF NOT keyword_set(write) THEN write = 0
IF NOT keyword_set(title) THEN title = ''

;; Check to make sure the value is a string
tmp = size(value, /type)
IF tmp NE 7 THEN message, 'String expression required for VALUE'

;; Create the container
base = widget_base(parent, /column, uname=uname, uvalue=uvalue, $
	pro_set_value='dicw_fnfinder_setval', $
	func_get_val='dicw_fnfinder_getval', $
	event_func='dicw_fnfinder_event', sensitive=sensitive, $
	align_top=align_top, align_bottom=align_bottom, $
	align_center=align_center, align_left=align_left, $
	align_right=align_right)

;; Insert the label
IF keyword_set(label) THEN $
	lbl = widget_label(base, /align_left, value=label)

fnBase = widget_base(base, /row)

;; Create the structure containing the options for the file dialog
fOpts = {filedialog_opts}
fOpts.filter = filter
fOpts.read = read
fOpts.write = write
fOpts.title = title

;; Add the text box and browse buttons
fnBox = widget_text(fnbase, /editable, /all_events, value=value, $
	uname='fnbox', xsize=xsize)
browse = widget_button(fnbase, value='Browse', uvalue=fOpts)

RETURN, base

END