#!/bin/sh
# \
exec wish "${0}" "${@}"

source misc.tcl

namespace eval setup {
variable page_list {}	;# Textual list of long names for pages
variable pages {}	;# Textual list of code names
variable page_info	;# Array of information about each page
variable cur_page -1	;# Index of currently displayed page

proc main {} {
	variable page_info
	variable pages
	variable cur_page

	# Create the common components
	toplevel .setup
	wm title .setup "OpenVerse Preferences"
	wm geometry .setup "510x380"
	wm resizable .setup 0 0
	listbox .setup.list -yscroll ".setup.scroll set" -relief sunken\
			-background white -foreground black -width 15\
			-listvar "setup::page_list"
	bind .setup.list <ButtonRelease-1> {setup::show_page}
	scrollbar .setup.scroll -command ".setup.list yview"
	frame .setup.content
	frame .setup.buttons
	button .setup.buttons.cancel -text "Cancel" -command {exit}
	button .setup.buttons.saveapply -text "Save & Apply" -command {$setup::page_info($setup::pages($setup::cur_page).save)}
        button .setup.buttons.applyonly -text "Apply Only" -command {$page_info($cur_page.apply)}
	button .setup.buttons.help -text "Help" -command {help}


	# Pack them
	foreach btn {"cancel" "saveapply" "applyonly" "help"} {
		pack .setup.buttons.$btn -side left
	}
	pack .setup.buttons -in .setup.content -side bottom -anchor sw
	pack .setup.list .setup.scroll -side left -fill y
	pack .setup.content -side left -fill both -expand 1

	# Prepare page_list
	foreach page $pages {$page_info($page.create)}

	# Show the first page
	show_page 0
}

proc show_page {args} {
	variable cur_page
	variable pages
	variable page_info

	if {$cur_page != -1} {
		pack forget "$page_info([lindex $pages $cur_page].path)"
	}
	if [llength $args] {
		set cur_page [lindex $args 0]
	} else {
		set cur_page [.setup.list curselection]
	}
	pack $page_info([lindex $pages $cur_page].path) -in .setup.content\
			-anchor nw
	update idletasks
}

# Add a setup page to the list
# name: the long name of the page (appears in the list)
# args:
#	-code-name: the short name used in the database
#	-path: the window path to the setup page
#	-index: suggested place in the list to put the page (0 = beg, end = end)
#	-create: code to create the setup page
#	-destroy: code to delete the setup page
#	-save: code to save settings to disk
#	-apply: code to apply settings to running session
#	-verify: code to verify validity of settings
proc register_page {name args} {
	variable page_info
	variable page_list
	variable pages

	# Defaults
	set code_name [string_map {" " ""} [string tolower $name]]
	set path ".setup.$code_name"
	set index "end"
	set create "create_$code_name"
	set destroy "destroy \$setup::page_info($code_name.path)"
	set save "save_$code_name"
	set apply "apply_$code_name"
	set verify "verify_$code_name"

	# Gather extra options
	while 1 {
		if ![arg_pop arg args] break
		switch -- $arg {
		"-code-name" {arg_pop code_name args}
		"-path" {arg_pop path args}
		"-index" {arg_pop index args}
		"-create" {arg_pop create args}
		"-destroy" {arg_pop destroy args}
		"-save" {arg_pop save args}
		"-apply" {arg_pop apply args}
		"-verify" {arg_pop verify args}
		}
	}

	# Save to database
	set page_info($code_name.long_name) $name
	set page_info($code_name.path) $path
	set page_info($code_name.create) $create
	set page_info($code_name.destroy) $destroy
	set page_info($code_name.save) $save
	set page_info($code_name.apply) $apply
	set page_info($code_name.verify) $verify
	set pages [linsert $pages $index $code_name]
	set page_list [linsert $page_list $index $name]
}
}

#PERSONAL INFORMATION FRAME
#This is a good example of a setup menu
#You need at least one frame to contain everything so we can hide and show the
#whole shebang. Also make sure the rest of the widgets (not the frame) are
#arranged.
proc create_profile {} {
	namespace eval profile {
	#global MV
	#variable sex "$MV(profile.sex)"
	#variable image "$MV(profile.image)"
	#variable realname "$MV(profile.realname)"
	#variable email "$MV(profile.email)"
	#variable homepage "$MV(profile.homepage)"
	#variable info "$MV(profile.info)"
	#variable availability "$MV(profile.availability)"
	}
	set frm $setup::page_info(profile.path)
	frame $frm
	label $frm.lblname -text "Real Name"
	entry $frm.txtname 
	label $frm.lblemail -text "Email Address"
	entry $frm.txtemail
	label $frm.lblhomepage -text "Homepage"
	entry $frm.txthomepage
	text $frm.txtpersonal -height 10 -width 50
	grid $frm.lblname -row 0 -column 0 -sticky "EW"
	grid $frm.txtname -row 0 -column 1 -sticky "EW"
	grid $frm.lblemail -row 1 -column 0 -sticky "EW"
	grid $frm.txtemail -row 1 -column 1 -sticky "EW"
	grid $frm.lblhomepage -row 2 -column 0 -sticky "EW"
	grid $frm.txthomepage -row 2 -column 1 -sticky "EW"
	grid $frm.txtpersonal -row 3 -column 0 -columnspan 2
}

proc destroy_profile {} {destroy $setup::page_info(profile.path)}
proc save_main {} {
return
}
proc apply_main {} {
return
}
#Look and feel
proc create_lookandfeel {} {
	set frm $setup::page_info(lookandfeel.path)
	frame $frm
	label $frm.lbl1 -text "TESTING TESTING 1 2 3"
	pack $frm.lbl1
}
#process all save commands
proc do_saves {} {
save_main
foreach cmd setup::savecmds {}
}
setup::register_page "Profile" -code-name "profile" -path ".setup.profile"\
		-index 0 -create "create_profile" -destroy "destroy_profile"\
		-save "save_main" -apply "apply_main" -verify ""
setup::register_page "Look and Feel" -save "" -apply "" -verify ""

setup::main

