#----------------------------------------------------------------------------
#
# PADT---------------------------------------------------- Phoenix Analysis &
#                                                         Design Technologies
#
#----------------------------------------------------------------------------
#
#       Package: AI-Environment GUI Management
#
#
#          File: text_editor.tcl
#
#
#	  Developer: Matt Sutton
#
#
#   Description: This file contains the implementation of an text widget window
#                that is configurable to be either editable or readonly. 
#        
#
#      03/25/02: Demo release 1. No implementation. Just a popup window.
#
#			
#
#-----------------------------------------------------------------------------
# For support: 1-480-813-4884 ext. 125 -or- matt.sutton@padtinc.com
#-----------------------------------------------------------------------------

package require Tktable
package require BWidget 1.4.0

namespace eval ::AIEnv {
	namespace export TableEditor
}
namespace eval ::AIEnv::GUIManagement {
	namespace export TableEditor
}
namespace eval ::AIEnv::GUIManagement::Widgets {
	namespace export TableEditor
} 
namespace eval ::AIEnv::GUIManagement::Widgets::TableEditor {
	variable TableEditors
	variable Counter
	variable Commands
	variable MinNumRows
	set MinNumRows 5
	set Commands [list "create" "destroy" "getdata"]
	set Counter 0
	namespace export TableEditor
}

proc ::AIEnv::GUIManagement::Widgets::TableEditor::TableEditor {{Name ""}} {
	variable TableEditors
	variable Counter
	
	if {[llength [info level 0]] == 1 } {
		incr Counter
		set Name "tableEditor${Counter}"
	}
	
	if {![string equal [info commands ::$Name] ""] } {
		::AIEnv::GUIManagement::Error "Command: \"$Name\" already exists, unable to create the TableEditor"
	}
	
	interp alias {} ::$Name {} ::AIEnv::GUIManagement::Widgets::TableEditor::TableEditorProc $Name
	
	return $Name
}

proc ::AIEnv::GUIManagement::Widgets::TableEditor::TableEditorProc {name {cmd ""} args } {
	
	if { [llength [info level 0]] == 2 } {
		::AIEnv::GUIManagement::Error "Wrong # args: should be \"$name option ?arg arg ...?\""
	}
	
	if { [string equal [info commands ::AIEnv::GUIManagement::Widgets::TableEditor::_$cmd] ""] } {
		set OptList [join $Commands ", "]
		set OptList [linsert $OptList "end-1" "or"]
		::AIEnv::GUIManagement::Error "Bad option \"$cmd\": must be $OptList"
	}
	
	return [eval [list ::AIEnv::GUIManagement::Widgets::TableEditor::_$cmd $name] $args]
}

#-----------------------------------------------------------------------------------------
# Create Command:
#	This function is responsible for creating a new table editor and initializing the 
#	data structure TableEditors with an entry for this table editor
#-----------------------------------------------------------------------------------------
proc ::AIEnv::GUIManagement::Widgets::TableEditor::_create {Name args} {
	variable TableEditors
	variable MinNumRows
	
	if {[llength $args] < 3} {
		::AIEnv::GUIManagement::Error "Wrong # args: should be \"$name numCol colHeadingList tableVariable\""
	}
	
	set TableEditors("$Name-NumCols")   [lindex $args 0]
	set TableEditors("$Name-Headings") [lindex $args 1]
	set TableEditors("$Name-TableVariable") [lindex $args 2]
	
	upvar #0 $TableEditors("$Name-TableVariable") TableArray
	if {[array exists TableArray]} {
		# Peel off the number of rows by grabbing the last index name from a list of 
		# index names. The last index name is a string of the form Row,Col so split 
		# the string using a comma as a delimiter and grab the first element of the 
		# resulting two element list
		set NumRows [expr [lindex [split [lindex [lsort [array names TableArray]] end] ","] 0] * 2]
		if { $NumRows > $MinNumRows } {
			set TableEditors("$Name-NumRows") $NumRows
		} else {
			set TableEditors("$Name-NumRows") $MinNumRows
		}
		
		# Create the Table array if it doesn't exists
		set TableArray(0,0) ""
	} else {
		# Default value
		set TableEditors("$Name-NumRows") $MinNumRows
	}
	set TableEditors("$Name-FirstRow") 1
	set TableEditors("$Name-FirstCol") 1
	
	if {[info exists TableEditors("$Name-Window")]} {
		wm deiconify $TableEditors("$Name-Window")
		raise $TableEditors("$Name-Window")
		return
	}
	
	destroy .$Name-table
	set Win [toplevel .$Name-table]
	
	set TableEditors("$Name-Window") $Win
	
	::AIEnv::GUIManagement::Widgets::TableEditor::CreateTableEditor $Win $Name
	
	bind $Win <Destroy> "::AIEnv::GUIManagement::Widgets::TableEditor::UnMapEditorDataStructure $Name"
}

#------------------------------------------------------------------------------------------
# UnMapEditorDataStructure
#	This function is responsible for deleting the table editor "name" from the list of
# 	current table editors
#------------------------------------------------------------------------------------------
proc ::AIEnv::GUIManagement::Widgets::TableEditor::UnMapEditorDataStructure {Name} {
	variable TableEditors
	if { [info exists TableEditors("$Name-Window")] } {
		unset TableEditors("$Name-Window")
		interp alias {} ::$Name {}
	}
}

#------------------------------------------------------------------------------------------
# Destroy Command:
#	This command will invoke the UnMapEditorDataStructure command due to the binding 
#	established in the Create Command. 
#------------------------------------------------------------------------------------------
proc ::AIEnv::GUIManagement::Widgets::TableEditor::_destroy {Name} {
	variable TableEditors
	if { [info exists TableEditors("$Name-Window")] } {
		destroy $TableEditors("$Name-Window")
	}
}


#------------------------------------------------------------------------------------------
# CreateTableEditor
#	This function actually creates all of the widgets associated with a table editor and
#	sets up the default bindings
#------------------------------------------------------------------------------------------
proc ::AIEnv::GUIManagement::Widgets::TableEditor::CreateTableEditor {Win Name} {
	variable TableEditors
	
	
	# Create the menu structure
	
	set MainMenu [menu $Win.mainMenu -tearoff 0]
	set FileMenu [menu $MainMenu.file -tearoff 0]
	set EditMenu [menu $MainMenu.edit -tearoff 0]
	
	$Win config -menu $MainMenu
	
	$MainMenu add cascade -label "File" -menu $FileMenu
	$MainMenu add cascade -label "Edit" -menu $EditMenu
	
	$FileMenu add command -label "Open..." -command "::AIEnv::GUIManagement::Widgets::TableEditor::ReadFile $Name"
	$FileMenu add separator
	$FileMenu add command -label "Close" -command "::AIEnv::GUIManagement::Widgets::TableEditor::_destroy $Name"
	
	$EditMenu add command -label "Cut" -command "::AIEnv::GUIManagement::Widgets::TableEditor::Cut $Name"
	$EditMenu add command -label "Copy" -command "::AIEnv::GUIManagement::Widgets::TableEditor::Copy $Name"
	$EditMenu add command -label "Paste" -command "::AIEnv::GUIManagement::Widgets::TableEditor::Paste $Name"
	
	# Create the toolbar and separator
	set TopSep [frame $Win.topsep -height 2 -borderwidth 1 -relief sunken]
	set BotSep [frame $Win.botsep -height 2 -borderwidth 1 -relief sunken]

	set Tbf [frame $Win.f]
	set FileBar [ButtonBox $Tbf.bbox1 -spacing 2 -padx 1 -pady 1]
	set EditBar [ButtonBox $Tbf.bbox2 -spacing 2 -padx 1 -pady 1]
	set CloseBar [ButtonBox $Tbf.bbox3 -spacing 0 -padx 1 -pady 1]
	set sep1 [Separator $Tbf.sep1 -orient vertical]
	set sep2 [Separator $Tbf.sep2 -orient vertical]
	
	$FileBar add -image [Bitmap::get open] \
				 -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
				 -helptext "Open" -command "::AIEnv::GUIManagement::Widgets::TableEditor::ReadFile $Name"

	$EditBar add -image [Bitmap::get cut] \
				 -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
				 -helptext "Cut" -command "::AIEnv::GUIManagement::Widgets::TableEditor::Cut $Name"
	
	$EditBar add -image [Bitmap::get copy] \
					 -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
				 -helptext "Copy" -command "::AIEnv::GUIManagement::Widgets::TableEditor::Copy $Name"
	
	$EditBar add -image [Bitmap::get paste] \
					 -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
				 -helptext "Paste" -command "::AIEnv::GUIManagement::Widgets::TableEditor::Paste $Name"

		
	$CloseBar add -text "Close" -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
					-helptext "Close" -command "::AIEnv::GUIManagement::Widgets::TableEditor::_destroy $Name"
	
	pack $FileBar -side left -anchor w -padx 4
	pack $sep1 -side left -fill y -anchor w
 	pack $EditBar -side left -anchor w -padx 4
 	pack $sep2 -side left -fill y -anchor w
	pack $CloseBar -side left -anchor w -padx 4

	
	grid columnconfigure $Win 0 -weight 0
	grid columnconfigure $Win 1 -weight 1
	
	grid configure $TopSep -row 0 -column 0 -columnspan 2 -sticky ew
	grid configure $Tbf -row 1 -column 0 -sticky w
	grid configure $BotSep -row 2 -column 0 -columnspan 2 -sticky ew
	
	# Create the table
	set tF [frame $Win.tf]
	
	set Cols [expr $TableEditors("$Name-NumCols") + 1]
	set Rows [expr $TableEditors("$Name-NumRows") + 1]
	
	set TableEditors("$Name-Table") [table $tF.tab -selectmode extended -background white -highlightbackground blue \
                                                   -colseparator "\t" -rowseparator "\n" -foreground black \
                                                   -bd {1 2 1 2} -titlerows 1 -titlecols 1 \
                                                   -variable  $TableEditors("$Name-TableVariable")\
                                                   -resizeborders both -rows $Rows -cols $Cols \
                                                   -yscrollcommand "$tF.sy set" \
					                               -xscrollcommand "$tF.sx set" \
					                               -colstretchmode all \
					                               -rowstretchmode all]
					  
	scrollbar $tF.sy -orient vertical -command "$tF.tab yview"
	scrollbar $tF.sx -orient horizontal -command "$tF.tab xview"
	
	grid $tF.tab -row 0 -col 0 -sticky nsew
	grid $tF.sy -row 0 -col 1 -sticky ns
	grid $tF.sx -row 1 -col 0 -sticky ew
	grid rowconfigure $tF 0 -weight 1
	grid columnconfigure $tF 0 -weight 1
	grid rowconfigure $tF 1 -weight 0
	grid columnconfigure $tF 1 -weight 0
	
	grid configure $tF -row 3 -column 0 -columnspan 2 -sticky nsew -padx 2 -pady 2
	
	grid rowconfigure $Win 0 -weight 0
	grid rowconfigure $Win 1 -weight 0
	grid rowconfigure $Win 2 -weight 0
	grid rowconfigure $Win 3 -weight 1
	
	CreateTableHeadings $Name
}

proc ::AIEnv::GUIManagement::Widgets::TableEditor::CreateTableHeadings {Name} {
	variable TableEditors
	
	upvar #0 $TableEditors("$Name-TableVariable") TableArray
	set ColHeadings $TableEditors("$Name-Headings")
	set NumCols $TableEditors("$Name-NumCols")
	if {[llength $ColHeadings] > $NumCols} {
		
	} else {
		set Col $TableEditors("$Name-FirstCol")
		foreach Heading $ColHeadings {
			set TableArray(0,$Col) $Heading
			incr Col
		}
	}
}

proc ::AIEnv::GUIManagement::Widgets::TableEditor::ReadFile {Name} {
	variable TableEditors
		
	upvar #0 $TableEditors("$Name-TableVariable") TableArray
	
	set FileName [tk_getOpenFile]
	if {$FileName != ""} {
		set ChannelID [open $FileName]
		gets $ChannelID FirstLine
		# Rewind back to the beginning
		seek $ChannelID 0 start
		if { [string first "/t" $FirstLine] != -1 } {
			set Delimiter "/t"
		} else {
			set Delimiter ","
		}
		
		# Load in the file
		set Row $TableEditors("$Name-FirstRow")
		set Col $TableEditors("$Name-FirstCol")
		while {![eof $ChannelID] } {
			gets $ChannelID CurrentLine
			set Items [split $CurrentLine $Delimiter]
			foreach i $Items {
				set TableArray($Row,$Col) $i
				incr Col
			}
			set Col $TableEditors("$Name-FirstCol")
			incr Row
		}
	}
}

proc ::AIEnv::GUIManagement::Widgets::TableEditor::Cut {Name} {
	variable TableEditors
	
	tk_tableCut $TableEditors("$Name-Table")
}

proc ::AIEnv::GUIManagement::Widgets::TableEditor::Copy {Name} {
	variable TableEditors
	
	tk_tableCopy $TableEditors("$Name-Table")
}

proc ::AIEnv::GUIManagement::Widgets::TableEditor::Paste {Name} {
	variable TableEditors
	
	tk_tablePaste $TableEditors("$Name-Table")
}
	
