FORWARD_FUNCTION dical_config_closing, dical_config_event, dical_Config

;;-----------------------------------------------------------------------------
;; PURPOSE:
;;	Runs a GUI to help modify the configuration file for the calibration
;;	pipeline. This is the configuration of where to get calibration files,
;;	not actual calibration options.
;;
;; CALLING SEQUENCE:
;;	dical_Config
;;
;; REQUIRED INPUTS:
;;	none
;;
;; OUTPUTS:
;;	none
;;		
;; OPTIONAL INPUT KEYWORDS:
;;
;; EXAMPLE:
;;      IDL> DICal_Config
;;
;; PROCEDURES USED (i.e. called directly!):
;;	freeLinkedList, dialog_strEntry, setDICalConfig, getDICalConfig, 
;;	sqlServerList2HostArr, 
;;
;; MODIFICATION HISTORY:
;;   	2004-08-13  M. Desnoyer - Created
;;
;;-----------------------------------------------------------------------------

;;---------------------
;; Kill Event Handler
;;---------------------
PRO DICal_config_closing, top

;; Find out if the user has modified anything
widget_control, top, get_uvalue=val

IF val.modified THEN BEGIN
	IF dialog_message('Do you want to save before quitting?', /Question, $
		title='Save?', dialog_parent=top) EQ 'Yes' THEN $
			setDicalConfig, val.config
ENDIF

;; Free all of the data
freeLinkedList, val.config.sqlServers

;; Destroy the widget
widget_control, top, /destroy

END


;;---------------------
;; Event Handler
;;---------------------
PRO dical_config_event, ev

;; Get the options
widget_control, ev.TOP, get_uvalue=val

;; Get the list widget
dblist = widget_info(ev.TOP, find_by_uname='dblist')

CASE widget_info(ev.ID, /uname) OF

;; Local directory selction
'locdir': BEGIN
	val.config.calibDir = ev.value
	val.modified = 1
END

;; Enable using local directory
'locdirena': BEGIN
	dirWid = widget_info(ev.TOP, find_by_uname='locdir')
	IF ev.select EQ 1 THEN BEGIN ;; Enable using the local directory
		widget_control, dirWid, get_value=dir
		val.config.calibDir = dir
		widget_control, dirWid, sensitive=1
	ENDIF ELSE BEGIN;; Disable local directory
		val.config.calibDir = ''
		widget_control, dirWid, sensitive=0
	ENDELSE
	val.modified = 1
END

;; Save button
'savebut': BEGIN
	setDicalConfig, val.config
	val.modified = 0
END

;; Close button
'closebut': BEGIN
	widget_control, ev.TOP, /destroy
	RETURN
END

;; Add Servers button
'addbut': BEGIN
	;; Query the user
	usrEntry = dialog_strEntry(ev.TOP, ['Host:', 'User:', 'Password:'], $
		title='Add New Server', isPassword=[0,0,1])
	;; User didn't enter a value so skip
	IF usrEntry[0] EQ '' THEN BREAK

	;; Create the new server object
	newServ = ptr_new({sqlServer, host:usrEntry[0], usr:usrEntry[1], $
			pass:usrEntry[2], next:ptr_new()},/NO_COPY)

	;; Add the new server to the list
	cur = val.config.sqlServers
	IF NOT ptr_valid(cur) THEN val.config.sqlServers = newServ $
	ELSE BEGIN
		WHILE ptr_valid((*cur).next) DO cur=(*cur).next
		(*cur).next = newServ
	ENDELSE
	val.modified=1

	;; Refresh the list
	widget_control, dblist, $
		set_value=sqlServerList2HostArr(val.config.sqlServers)
END

;; Edit Servers button
'editbut': BEGIN
	cur = val.config.sqlServers

	;; Find out which server is selected
	idx = widget_info(dblist, /list_select)
	IF idx[0] EQ -1 OR (NOT ptr_valid(cur)) THEN BREAK

	;; Go to the entry to change in the list
	FOR i=0, idx[0]-1 DO cur = (*cur).next

	;; Query user for changes
	usrEntry = dialog_strEntry(ev.TOP, ['Host:', 'Usr:', 'Password:'], $
		title='Edit Server', isPassword=[0,0,1], $
		value=[(*cur).host,(*cur).usr,(*cur).pass])
	IF usrEntry[0] EQ '' THEN BREAK

	;; Save the changes
	(*cur).host = usrEntry[0]
	(*cur).usr = usrEntry[1]
	(*cur).pass = usrEntry[2]
	val.modified = 1

	;; Refresh the list
	widget_control, dblist, $
		set_value=sqlServerList2HostArr(val.config.sqlServers)
	
END

;; Delete Servers button
'delbut': BEGIN
	cur = val.config.sqlServers

	;; Find out which server is selected
	idx = widget_info(dblist, /list_select)
	IF idx[0] EQ -1 OR (NOT ptr_valid(cur)) THEN BREAK

	;; Remove the server from the list
	IF idx[0] EQ 0 THEN BEGIN ;; Special case for the first item
		val.config.sqlServers = (*cur).next
		ptr_free, cur
	ENDIF ELSE BEGIN
		;; Go to the server right before the one being deleted
		FOR i=0, idx[0]-2 DO cur = (*cur).next
		
		;; Remove the server from the list and delete from memory
		toDie = (*cur).next
		(*cur).next = (*toDie).next
		ptr_free, toDie
	ENDELSE

	;; Refresh the list
	widget_control, dblist, $
		set_value=sqlServerList2HostArr(val.config.sqlServers)

	;; Update the data structure
	val.modified=1
END

ELSE:BREAK

ENDCASE

widget_control, ev.TOP, set_uval=val, /no_copy
END

;;---------------------
;; Main procedure
;;---------------------

PRO dical_Config

;; Open the current configuration
config = getDICalConfig()

;; Build the GUI
base = widget_base(title='DICal Configuration Editor', mbar=menu, $
	uvalue={config:config,modified:0}, /column, uname='main')
filemenu = widget_button(menu, value='File', /Menu)
saveBut = widget_button(filemenu, value='Save', uname='savebut')
closeBut = widget_button(filemenu, value='Close', uname='closebut')

;; Add the local directory chooser
locdirena = cw_bgroup(base, ['Use Local Directory For Calibration Files'], $
	/nonexclusive, set_value=[config.calibdir NE ''], $
	uname='locdirena')
locdir = dicw_fnfinder(base, value=config.calibdir, $
	title='Please Choose a Directory that is the Root of the Calibration Files', $
	sensitive=config.calibdir NE '', uname='locdir', /align_center)

;; Add the list of databases
temp = widget_label(base, value='Hosts to Query for Calibration Files', $
	/align_left)
dbbase = widget_base(base, /row, /align_center)
dblist = widget_list(dbbase, uname='dblist', xsize=15, ysize=5, $
	value=sqlServerList2HostArr(config.sqlServers))

;; Add the buttons to modify the list of databases
butbase = widget_base(dbbase, /column)
addbut = widget_button(butbase, value='Add', uname='addbut')
editbut = widget_button(butbase, value='Edit', uname='editbut')
delbut = widget_button(butbase, value='Delete', uname='delbut')

;; Show the gui
widget_control, base, /realize

;; Register the event handler
widget_control, base, kill_notify='dical_config_closing'
xmanager, 'dical_config', base, event_handler='dical_config_event', /no_block

END