# $Revision$ on $Date$
# The above revision line needs to be the first line for all techtk files
# Copyright (c) 2006 Ansys Inc

#--------------------------------- Standard Tokenizer -----------------------------------



proc ::AIEnv::GUIManagement::ReadFile {ResFileName} {
    set ResFileID [open_with_encoding $ResFileName r]
    ResourceFileIDStack push $ResFileID
    ResourceFileNameStack push $ResFileName
    ResourceFileLineNumberStack push 0
    ReadLine
}


proc ::AIEnv::GUIManagement::ReadLine {} {
	variable TokenList
	variable CurTokenIndex
	variable CurrLine
	global BuildProgressValue
	# Used for display purposes
	
	while {1} {
		# Check the stack of files to see if we have a valid source
		# file open
		if { [ResourceFileIDStack size] == 0 } {
			set TokenList ""
			lappend TokenList "EOF"
			set CurTokenIndex 0
			return 
		}
		set ResFileID [ResourceFileIDStack peek]
		if { [eof $ResFileID] == 1 } {
			# Close the file since we have reached the end of file
			# marker for this file
			close [ResourceFileIDStack pop]
			# Keep the other three stacks in the same state as the
			# file ID stack
			ResourceFileNameStack pop
			ResourceFileLineNumberStack pop
			continue
		} else {
		    set CurrLine ""
		    set LineNum [ResourceFileLineNumberStack pop]
		    while {[gets $ResFileID line] >= 0} {
			incr LineNum
			set line [string trimright $line \r] ;# ^M's on windows
			if { [string index $line end] == "\\" } {
			    append CurrLine [string trimright $line \\]
                        } else {
			    append CurrLine $line
			    break
			}					
		    }

		    set CurrLine [string trimleft $CurrLine]
		    if {$CurrLine != "" && [string index $CurrLine 0] != "#"} {
			set CurrLine [uplevel #0 subst -nocommands \{$CurrLine\}]
		    }
		    set TokenList ""
		    ResourceFileLineNumberStack push $LineNum
		    SplitLine $CurrLine TokenList
		    lappend TokenList "_EOLToken"
		    set CurTokenIndex 0
		    return
		}
	}
}

proc ::AIEnv::GUIManagement::SplitLine {Line List} {
	upvar $List LocalList
	set LocalList ""
	# Look for unmatched quoting.  This is done by spliting the string
	# using the quotation marks. If the resulting list is not an odd number
	# the quoting is not properly matched.
	if { [CheckQuote $Line] == -1 } {
		ParseError "Unmatched Quote on Line"
	}
	
	# Make sure to separate out the comment symbol
	regsub {#} $Line {#;;} Line
	# Break everything else up by quoting.  Must have properly matched quotes
	# for this regular expression to function properly
	regsub -all {\"[^\"]*\"} $Line {;;\0;;} Line
	
	set MetaList [split $Line ";;"]
	
	foreach Item $MetaList {
		if {[string index $Item 0] == "\""} {
			lappend LocalList [string trimleft [string trimright $Item "\""] "\""]
		} else {
			set TmpList [split [string trimleft [string trimright $Item]] " \t"]
			foreach i $TmpList {
				set i [string trimleft [string trimright $i]]
				if {$i != ""} {
					lappend LocalList $i
				}
			}
		}
	}
}

proc ::AIEnv::GUIManagement::CheckQuote {Str} {
	set First [string first "\"" $Str]
	set Last  [string last "\"" $Str]
	if { $First != -1 } {
		if { $Last != -1 } {
			if { $First >= $Last } {
				# We've crossed over so bail out
				return -1
			} else {
				# Subdivide again looking for matching quotes
				incr First
				incr Last -1
				set Str [string range $Str $First $Last]
				CheckQuote $Str
			}
		} else {
			return -1
		}
	} else {
		return 1
	}
}

#-----------------------------------------------------------------------------
#
# Get the next token from the list
#
proc ::AIEnv::GUIManagement::GetToken {} {
	variable TokenList
	variable CurTokenIndex
	variable ForceEOF
	if {$ForceEOF == 1} {
		set ForceEOF 0
		return "EOF"
	}
	
	set CurItem ""
	# Skip over blank entries in the list.  This loop depends on
	# each line being truncated with an _EOLToken. If this token
	# does not appear at the end of each line, then the loop will
	# become infinte.
	while {1} {
		if { $CurTokenIndex > [llength $TokenList] } {
			ReadLine
		}
		set CurItem [lindex $TokenList $CurTokenIndex]
		incr CurTokenIndex
		if { $CurItem != "" } {
			return $CurItem
		}
	}
}



#-----------------------------------------------------------------------------
#
# Look at the next token without removing it
#

proc ::AIEnv::GUIManagement::PeekToken {} {
    variable TokenList
    variable CurTokenIndex
    set CurItem ""
    # Skip over blank entries in the list
    while {1} {
        if { $CurTokenIndex > [llength $TokenList] } {
			return ""
		} else {
			set CurItem [lindex $TokenList $CurTokenIndex]
			incr CurTokenIndex
			if {$CurItem != ""} {
				# Since we are peeking, move the index back to this token
				incr CurTokenIndex -1
				return $CurItem
			}
		}
    }
}


# --------------------------------------------------

# Stuff to support Japanese language text

proc open_with_encoding {name mode} {
    global env

    set fp [open $name $mode]
    set japanes 0
    if {[info command set_env] != ""} {
	set japanese [expr [info exists env(LANG)] && [string match *JP* [set_env env(LANG)]]]
    } else {
	set japanese [expr [info exists env(LANG)] && [string match *JP* [set env(LANG)]]]
    }
    if $japanese {
	fconfigure $fp -encoding shiftjis
    }
    return $fp
}

