FORWARD_FUNCTION dialog_strEntry, dialog_strEntry_butEvent, $
	dialog_strEntry_typeEvent

;;-----------------------------------------------------------------------------
;; PURPOSE:
;;	Creates a modal dialog with a user specified number of entry fields.
;;	The window has two buttons (Ok and Cancel) and texboxes for user entry.
;;	When the user finishes entering data into the window, the function
;;	returns. For all arrays of input and output data, the nth element in 
;;	the array corresponds to the nth field from the top of the window.
;;
;; CALLING SEQUENCE:
;;	data = dialog_strEntry(parent, fields, TITLE=title, FLDSIZE=fldsize, 
;;		ISPASSWORD=ispassword, VALUE=value
;;
;; REQUIRED INPUTS:
;;	parent - widget ID of the parent for this dialog
;;	fields - string array of the names of the entry fields
;;
;; OUTPUTS:
;;	A string array where the nth string corresponds to the user's entry
;;	for the nth field. If the user clicks the cancel button, this will
;;	be an array of null strings.
;;
;; OPTIONAL INPUT KEYWORDS:
;;	TITLE - title for the window
;;	FLDSIZE - The display size in characters for every text box
;;	ISPASSWORD - boolean array specifying which fields are password fields
;;		and need to have asterixs displayed on the screen
;;	VALUE - string array specifying the initial values of the fields
;;
;; EVENTS PRODUCED:
;;	No event is returned
;;
;; EXAMPLE:
;;      IDL> data = dialog_strEntry(['User','Password'], ispassword=[0,1])
;;
;; PROCEDURES USED (i.e. called directly!):
;;	password_text
;;
;; MODIFICATION HISTORY:
;;   2004-09-20  M. Desnoyer    Created
;;
;;-----------------------------------------------------------------------------

;;----------------------
;; Button pressed event handling routine
;;----------------------
PRO dialog_strEntry_butEvent, ev

;; If the cancel button was pressed then empty the string array
IF widget_info(ev.ID, /UNAME) EQ 'cancelBut' THEN BEGIN
	widget_control, ev.TOP, get_uvalue=valPtr
	*valPtr = strarr((size(*valPtr,/dimensions))[0])
ENDIF

;; Destroy the window, causing the dialog creation function to return
widget_control, ev.TOP, /destroy

END

;;----------------------
;; Event handler for the text fields
;;----------------------
PRO dialog_strEntry_typeEvent, ev

;; Check to make sure that the event changed the value of the display
IF ev.type EQ 3 THEN RETURN

;; Get the pointer to the stored values
widget_control, ev.TOP, get_uvalue=valPtr

;; Figure out which text field was changed
widget_control, ev.ID, get_uvalue=idx, get_value=newval

;; Change the appropriate stored value
(*valPtr)[idx] = newval

END

;;----------------------
;; Actual dialog creation routine
;;----------------------
FUNCTION dialog_strEntry, parent, fields, TITLE=title, FLDSIZE=fldsize, $
	ISPASSWORD=ispassword, VALUE=value

;; Verify inputs

;; Valid parent
IF NOT widget_info(parent, /valid_id) THEN message, 'Invalid parent'

;; Valid field names 
n = n_elements(fields)
IF n EQ 0 THEN message, 'Must specify some field names'

;; Valid password identities
m = n_elements(ispassword)
ispass = bytarr(n)
IF m GT 0 AND m LE n THEN ispass[0] = ispassword

;; Valid initial values
m = n_elements(value)
vals = strarr(n)
IF m GT 0 AND m LE n THEN vals[0] = value
valsPtr = ptr_new(vals)

;; Create the window
base = widget_base(/modal, group_leader=parent, title=title, /column)
cont = widget_base(base, row=n)

;; Add all the fields 
FOR i=0, n-1 DO BEGIN
	txt = widget_label(cont,/align_center, value=fields[i])
	IF ispass[i] THEN BEGIN
		fld = dicw_pwdField(cont, /sensitive, xsize=fldsize, $
			uvalue=i, value=vals[i])
	ENDIF ELSE BEGIN
		fld = widget_text(cont, /editable, /sensitive,$
			xsize=fldsize, /all_events, uvalue=i, value=vals[i])
	ENDELSE
END

;; Add the Ok and Cancel Buttons
butHold = widget_base(base, /align_center, /row)
okBut = widget_button(butHold, value='Ok', uname='okBut')
cancelBut = widget_button(butHold, value='Cancel', uname='cancelBut')

;; Realize the window
widget_control, base, default_button=okBut, cancel_button=cancelBut, /realize,$
	set_uvalue=valsPtr

;; Register the event handlers
xmanager, 'dialog_strEntry', butHold, event_handler='dialog_strEntry_butEvent',$
	/just_reg
xmanager, 'dialog_strEntry', cont, event_handler='dialog_strEntry_typeEvent'

;; Now that the internal widgets have been destroyed, get the values 
out = *valsPtr
ptr_free, valsPtr
RETURN, out

END