##############################################################################
#    ASED Tcl/Tk IDE
#
#    Copyright (C) 1999  Andreas Sievers andreas.sievers@t-online.de
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
##############################################################################

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


global rootDir
global search_var_string search_option_icase search_option_area search_option_match search_option_blink 
global EditorData 
global clock_var
global textChanged
global conWindow

if { [file type $argv0] == "link" } {
    set rootDir [file dirname [file readlink $argv0]]
} else {
    set rootDir [file dirname $argv0]
}

################################################################################
# If BWidget and/or Tcl/Tk is not included in your environment PATH
# please set the following path_* variables appropriate and uncomment the block
################################################################################
#
 set path_to_BWidget "\./BWidget-1.2.1"
# set path_to_TclLib "Your Path to Tcl Lib-Directory"
# set path_to_TkLib "Your Path to Tk Lib-Directory"
# set auto_path [linsert auto_path 0 $path_to_BWidget]
# set auto_path [linsert auto_path 0 $path_to_TclLib]
# set auto_path [linsert auto_path 0 $path_to_TkLib]
################################################################################
lappend auto_path $path_to_BWidget

package require BWidget 1.2
Bitmap::get cut
# this used for loading Bitmap namespace into the interpetator
namespace eval Bitmap {
    lappend path [file join $rootDir images]
}

source [file join $rootDir bindings.tcl]
source [file join $rootDir find.tcl]
source [file join $rootDir repl.tcl]
source [file join $rootDir undo.tcl]
source [file join $rootDir asedcon.tcl]
source [file join $rootDir manager.tcl]

################################################################################
#proc delete_id
#called when a editorwindow is closed to delete the correspondend undo_id
################################################################################
proc delete_id {} {
    global undo_id
    delete textUndoer $Editor::current(undo_id)
    return
}

namespace eval Editor {
    variable _wfont
    variable notebook
    variable list_notebook
    variable con_notebook
    variable pw1
    variable pw2
    variable procWindow
    variable markWindow
    variable mainframe
    variable status
    variable prgtext
    variable prgindic
    variable font
    variable font_name
    variable Font_var
    variable FontSize_var
    variable toolbar1  1
    variable toolbar2  0
    variable showConsoleWindow 1
    variable showProcWindow 1
    variable search_var
    variable search_combo
    variable current
    variable last
    variable text_win
    variable index_counter 0
    variable index    
    variable workingDir $rootDir
    variable slaves 
    variable startTime [clock seconds]
    variable defaultProjectFile "none"
    variable defaultFile "defaults.prj"
    variable options
    variable lineNo
    variable lineEntryCombo
}

proc Editor::tick {} {
    global clock_var
    variable mainframe
    variable startTime
    set seconds [expr [clock seconds]  - $startTime]
    set clock_var [clock format $seconds -format %H:%M:%S -gmt 1]
    after 1000 Editor::tick
}

proc Editor::aboutBox {} {\
    tk_messageBox -message \
"      ASED Tcl/Tk-IDE 0.9.1.4
(c) Andreas Sievers, 1999\n\n\
     Parts of this Editor are based upon the\n\
BWidget Toolkit Demo from UNIFIX and
   Tcldev from Alexey Kakunin\n\
email:andreas.sievers@t-online.de" \
                                    -type ok \
                                    -title About \
                                    -icon info
}

proc Editor::getWindowPositions {} {
    global EditorData
    variable pw1
    variable pw2
    variable notebook
    variable list_notebook
    variable con_notebook
    variable current
    
    update idletasks
    
   
    set EditorData(options,notebookWidth) [winfo width $notebook]
    set EditorData(options,notebookHeight) [winfo height $notebook]
    set EditorData(options,list_notebookWidth) [winfo width $list_notebook]
    set EditorData(options,list_notebookHeight) [winfo height $list_notebook]
    set EditorData(options,con_notebookWidth) [winfo width $con_notebook]
    set EditorData(options,con_notebookHeight) [winfo height $con_notebook]
#    get position of mainWindow
    set EditorData(options,mainWinSize) [wm geom .]
}

proc Editor::restoreWindowPositions {} {
    global EditorData
    variable pw1
    variable pw2
    variable notebook
    variable list_notebook
    variable con_notebook
    
    
    
    $notebook configure -width $EditorData(options,notebookWidth)
    $notebook configure -height $EditorData(options,notebookHeight)
    $list_notebook configure -width $EditorData(options,list_notebookWidth)
    $list_notebook configure -height $EditorData(options,list_notebookHeight)
    $con_notebook configure -width $EditorData(options,con_notebookWidth)
    $con_notebook configure -height $EditorData(options,con_notebookHeight)
    showConsole $EditorData(options,showConsole)
    showProcWin $EditorData(options,showProcs)
}



################################################################################
#proc Editor::saveOptions
#called when ASED exits
#saves only "EditorData(options,...)"
#but might be easily enhanced with other options
################################################################################
proc Editor::saveOptions {} {
    global EditorData
    global rootDir
    
    Editor::getWindowPositions
    
    set configData "#ASED Configuration File\n\n"
    set configFile [file join $rootDir ased.cfg]
    set optionlist [array names EditorData]
    foreach option $optionlist {        
        set optiontext EditorData($option)
        if {![string match "*(options*" $optiontext]} {
            continue
        }
        set value \"[subst \$[subst {$optiontext}]]\"
        append configData "set EditorData($option) $value\n"
        
    }
    set result [Editor::_saveFile $configFile $configData]
}

proc Editor::CreateFonts {} {
        global EditorData
    
        variable configError
        variable Font_var
        variable FontSize_var    
       
        # set editor font
        if {$configError} {
            
            set font [list -family Courier -size 10 -weight normal -slant roman -underline 0 -overstrike 0]
            
            set EditorData(options,fonts,editorFont) $font
        }
        eval font create editorFont $EditorData(options,fonts,editorFont)
        # set comment font
        if {$configError} {
            
            set font [list -family Courier -size 10 -weight normal -slant italic -underline 0 -overstrike 0]
            
            set EditorData(options,fonts,commentFont) $font
        }
        eval font create commentFont $EditorData(options,fonts,commentFont)

        # set keyword font
        if {$configError} {
            
            set font [list -family Courier -size 10 -weight bold -slant roman -underline 0 -overstrike 0]
            set EditorData(options,fonts,keywordFont) $font
        }
        eval font create keywordFont $EditorData(options,fonts,keywordFont)
        set Font_var [font configure editorFont -family]
        return
    }

proc Editor::setDefault {} {
        global tcl_platform
        global EditorData
        variable current
        variable defaultFile
        variable defaultProjectFile        
        variable configError
        variable toolbar1
        variable toolbar2
        variable showConsoleWindow
        variable showProcWindow
        variable options
    		variable lineNo
    
        
        set current(is_procline) 0; #is needed for checkProcs
        set current(procListHistoryPos) 0
        set current(procListHistory) [list "mark1"]
        set current(procList_hist_maxLength) 20
        set current(lastPos) "1.0"
        
        set filename [file join  [pwd] $defaultFile]
        if {[file exists $filename]} {
            set fd [open $filename r]
            set defaultProjectFile [read $fd]
            set current(project) $defaultProjectFile
            close $fd
        }
    
        
         # set keywords
         set EditorData(keywords) [info commands]
 
         set EditorData(files) {}
         set EditorData(curFile) ""
         set EditorData(find) {}
         set EditorData(find,lastOptions) ""
         set EditorData(replace) {}
         set EditorData(projectFile) ""  
         set EditorData(cursor,line) 1
         set EditorData(cursor,pos) 0
         set EditorData(cursorPos) "Line: 1   Pos: 0"
    		 set Editor::lineNo $EditorData(cursor,line)
    
    if $configError {   
        if {$tcl_platform(platform) == "windows"} {
            set EditorData(options,fontSize) 15
            set EditorData(options,fontEncoding) ""
        } else {
            set EditorData(options,fontSize) 12
            set EditorData(options,fontEncoding) "koi8-r"
        }
        
        font create nbFrameFont -size 8
        
        set EditorData(options,useIndent) 1
        set options(useIndent) 1
        set EditorData(options,useSintaxIndent) 1
        set options(useSI) 1
        set EditorData(options,indentSize) 4        
        set EditorData(options,changeTabs) 0
        set options(changeTabs) 0
        set EditorData(options,tabSize) 4        
        set EditorData(options,useHL) 1
        set options(useHL) 1        
        set EditorData(options,useTemplates) 1
        set options(useTemplates) 1
        set EditorData(options,useTemplatesForKeywords) 1
        set options(useKeywordTemplates) 1
        set EditorData(options,useTemplatesForBrace) 1
        set options(useBracesTemplates) 1
        set EditorData(options,useTemplatesForParen) 1
        set options(useParenTemplates) 1
        set EditorData(options,useTemplatesForBracket) 1
        set options(useBracketTemplates) 1
        set EditorData(options,useTemplatesForQuoteDbl) 1
        set options(useQuotesTemplates) 1
        set EditorData(options,showToolbar1) $toolbar1
        set EditorData(options,showToolbar2) $toolbar2
        set options(showConsole) 1
        set EditorData(options,showConsole) $showConsoleWindow
        set options(showProcs) 1
        set EditorData(options,showProcs) $showProcWindow
    } else  {
        set toolbar1 $EditorData(options,showToolbar1)
        set toolbar2 $EditorData(options,showToolbar2)
        set options(useIndent) $EditorData(options,useIndent)
        set options(useSI) $EditorData(options,useSintaxIndent)
        set options(useHL) $EditorData(options,useHL)
        set options(useTemplates) $EditorData(options,useTemplates)
        set options(useKeywordTemplates) $EditorData(options,useTemplatesForKeywords)
        set options(useBracesTemplates) $EditorData(options,useTemplatesForBrace)
        set options(useParenTemplates) $EditorData(options,useTemplatesForParen)
        set options(useBracketTemplates) $EditorData(options,useTemplatesForBracket)
        set options(useQuotesTemplates) $EditorData(options,useTemplatesForQuoteDbl)
        set options(showConsole) $EditorData(options,showConsole)
        set options(showProcs) $EditorData(options,showProcs)
    }
    Editor::CreateFonts
    return
}

proc Editor::newFile {{force 0}} {
    variable notebook
    variable current
    global EditorData
    set pages [NoteBook::pages $notebook]
    if {([llength $pages] > 0) && ($force == 0)} {\
        if {[info exists current(text)]} {\
            set f0 [NoteBook::raise $notebook]
            set text [NoteBook::itemcget $notebook $f0 -text]
            set data [$current(text) get 1.0 end-1c]
            if {($data == "") && ($text == "Untitled")} {return}
        }
    }
    set temp $current(hasChanged)
    set f0 [EditManager::create_text $notebook "Untitled"]
    set Editor::text_win($Editor::index_counter,undo_id) [new textUndoer [lindex $f0 2]]
    set current(hasChanged) $temp
    NoteBook::raise $notebook [lindex $f0 1]
    set current(hasChanged) 0
}

################################################################################
#proc Editor::checkProcs
#updates highlight position in the Procs Window, 
#dependent on current cursor position
################################################################################

proc Editor::checkProcs {{add_history {1}}} {
    variable current
    variable procWindow
    global EditorData
    
    set procLine ""
    set procLength ""
         
    update idletasks
       
    if {![info exists current(procName)]} {
        set current(procName) ""
    } 
    #is current line a proc-line?
    set result [$current(text) search "proc " "insert linestart" "insert lineend"]
    if {$result == ""} {
        #this is not a proc-line
        #was it a proc-line?
        if $current(is_procline) {
            updateProcs
            set current(is_procline) 0
            set current(procSelectionChanged) 1
        }
        set result [$current(text) index insert]
         
        # look for previous proc-line
        while {$result != ""} {
            set result [$current(text) search -backwards "proc " $result 1.0]
            # no prev. proc-line found              
            if {$result == ""} {
                $procWindow selection clear 0 end
                if {($current(procName) != "") && $add_history} {
                    Editor::procList_history_add $Editor::current(lastPos)
                }
                set current(procName) ""
                return
            } else  {
                set line [$current(text) get "$result linestart" "$result lineend"]
                set temp [string trim $line \ \t\;]
                set proc ""
                set procName ""
                #is it really a proc-line?
                if {[scan $temp %\[proc\]%s proc procName] != 2} {
                    continue
                } elseif {$proc != "proc"} {
                    continue
                }
                #it is a proc-line!                
                break 
            }
        }    
    } else  {
        #is current line really a proc-line?
        set line [$current(text) get "$result linestart" "$result lineend"]
        set temp [string trim $line \ \t\;]
        set proc ""
        set procName ""
        #is it really a proc-line?
        if {[scan $temp %\[proc\]%s proc procName] != 2} {
            set result ""
        } elseif {$proc != "proc"} {
            set result ""
        }
        
        if {$result != ""} {
            set current(is_procline) 1
        } else  {
            set current(is_procline) 0
            set result [$current(text) index insert]
            # look for previous proc-line
            while {$result != ""} {
                set result [$current(text) search -backwards "proc " $result 1.0]
                # no prev. proc-line found              
                if {$result == ""} {
                    $procWindow selection clear 0 end
                    if {($current(procName) != "") && $add_history} {
                        Editor::procList_history_add $Editor::current(lastPos)
                    }
                    set current(procName) ""
                    return
                } else  {
                    set line [$current(text) get "$result linestart" "$result lineend"]
                    set temp [string trim $line \ \t\;]
                    set proc ""
                    set procName ""
                    #is it really a proc-line?
                    if {[scan $temp %\[proc\]%s proc procName] != 2} {
                        continue
                    } elseif {$proc != "proc"} {
                        continue
                    }
                    #it is a proc-line!                
                    break 
                }
            }    
        }
    }
    # if we have not found a proc-line then return
    if {$result == ""} {
        $procWindow selection clear 0 end
        #if we left a proc
        if {$current(procName) != "" && $add_history} {
            Editor::procList_history_add $Editor::current(lastPos)
        } elseif $add_history {
            #we assume we are in the same region
            set current(lastPos) [$current(text) index insert]
        }
        set current(procName) ""
        return
    }    
    
    #look for procname in list     
    set found [lsearch $EditorData(files,$current(file),marks) $procName]
    #if proc didnīt exist before
    if {$found == -1} {                 
        updateProcs            
        set found [lsearch $EditorData(files,$current(file),marks) $procName]
    }    
    $procWindow selection clear 0 end
    $procWindow selection set [expr $found + 2]
    $procWindow see [$procWindow curselection]
    if {$current(procName) != $procName} {
         #procName has changed, so store new position in history
        if $add_history {Editor::procList_history_add $Editor::current(lastPos)}
        set current(procName) $procName
    } elseif $add_history {
        #we assume we are in the same region
        set current(lastPos) [$current(text) index insert]
    }    
}


################################################################################
#proc Editor::updateProcs
#read proc-names from Editor-window, (re-)insert them in the proc-window and sort them
################################################################################
proc Editor::updateProcs {} {
    variable current
    variable procWindow    
    global EditorData
    
    $procWindow delete 0 end
    $procWindow insert 0 "<End of File>"
    $procWindow insert 0 "<Top of File>"
    set EditorData(files,$Editor::current(file),text) [$current(text) get 1.0 end-1c]
    editorWindows::ReadMarks $current(file)
    set EditorData(files,$current(file),marks)  [lsort -dictionary $EditorData(files,$current(file),marks) ]
    
    foreach procName $EditorData(files,$current(file),marks) {
        set name $EditorData(files,$current(file),marks,$procName,name)
        $procWindow insert end $name
    }
}

################################################################################
#proc Editor::evalMain
#will be called from within a slave-interpreter to do something within the main-interpreter
################################################################################
proc Editor::evalMain {args} {
        
    uplevel #0 eval $args
}    

################################################################################
#proc Editor::execFile
#runs current editor-data without saving to file, 
#or associated or default projectfile with data of the current window
################################################################################
proc Editor::execFile {} {
    global tk_library
    global tcl_platform
    global auto_path
    global conWindow
    global code
    variable current 
    
    Editor::argument_history_add              
#aleady running ?    
    if {[interp exists $current(slave)]} {
        switch [tk_messageBox -message "$current(file) is already running!\nRestart ?" -type yesnocancel -icon question -title "Question"] {
            yes {Editor::exitSlave $current(slave); after idle Editor::execFile; return}
            no {}
            cancel {}
        }    
        return
    }
    set cursor [. cget -cursor]
    . configure -cursor watch
    update
    set hasChanged $current(hasChanged)
    if {$current(file) != "Untitled"} {Editor::saveFile}
    set current(slave) [interp create]    
    set Editor::slaves($current(slave)) $Editor::current(pagename)
    interp eval $current(slave) set page $current(pagename)
    $current(slave) alias _exitSlave Editor::exitSlave
    if {"$tcl_platform(platform)" == "windows"} {
        $current(slave) alias consolePuts consolePuts
        interp eval $current(slave) {
            rename puts Puts
            proc puts {args} {
                switch [llength $args] {
                    0 {return}
                    1 {eval consolePuts $args}
                    2 {if {[lindex $args 0] == "-nonewline"} {
                        eval consolePuts $args
                      } else  {
                          eval Puts $args
                      }}
                    default {eval Puts $args}
                }
            }
        }
    }
    $current(slave) alias evalMain Editor::evalMain    
    
        
    if {($current(project) == "none") || ($current(file) == "Untitled" || $current(file) == $current(project))} {
        set current(data) [$current(text) get 1.0 end-1c]
        interp eval $current(slave) set data [list $current(data)]
    } else  {
        if {[file exists $current(project)]} {
            set fd [open $current(project) r]
            interp eval $current(slave) set data [list [read $fd]]
            close $fd
        } else  {
            tk_messageBox -message "ProjectFile <$current(project)> not found !" -title Error -icon error
            after idle Editor::exitSlave $current(slave)
            return
        }
    }
    # ToDo:
    # setup for interpreter environment via dialog
    interp eval $current(slave) set slave $current(slave)    
    interp eval $current(slave) set conWindow $conWindow
    interp eval $current(slave) set argv [list $Editor::argument_var]
    interp eval $current(slave) set argc [llength [list $Editor::argument_var]]    
    interp eval $current(slave) set argv0 $current(file)
    interp eval $current(slave) set tk_library [list $tk_library]
    interp eval $current(slave) set auto_path [list $auto_path]
    interp eval $current(slave) {
        proc _exitProc {{exitcode 0}} {
            global slave
            catch {_exitSlave $slave}
        }
        load {} Tk 
        interp alias {} exit {} _exitProc
        wm protocol . WM_DELETE_WINDOW {_exitProc}
        set code [catch {eval $data} info]
        catch {
            if {$code} {            
                tk_messageBox -message $errorInfo -title Error -icon error
                after idle _exitProc
            }
        }  
    }
    if {$current(file) != "Untitled"} {
        set bakFile "[file rootname $current(file)].bak"
        Editor::file_copy $bakFile $current(file)
    }
    set current(hasChanged) $hasChanged
    update idletasks
    . configure -cursor $cursor   
    catch {
        interp eval $current(slave) {
            if {[wm title .] != ""} {
                wm title . "ASED is running: >>[wm title .]<<"
            } else  {
                if {$current(project) != "none" && $current(project) != $current(file)} {
                    wm title . "ASED is running \"$current(project)\" testing >>$current(file)<<"
                } else  {
                    wm title . "ASED is running: >>$current(file)<<"
                }                
            }
        }
    }
       
}

################################################################################
#proc Editor::terminate
#terminates execution of current editor-file or associated projectfile
################################################################################
proc Editor::terminate {} {
    variable current
    Editor::exitSlave $current(slave)    
}

proc Editor::exitSlave {slave} {                
       
        if {[interp exists $slave]} {
            interp eval $slave {
                set taskList [after info]
                foreach id $taskList {
                    after cancel $id
                }
            }
            $Editor::notebook raise $Editor::slaves($slave)
            if {[winfo exists .]} {catch {$Editor::current(slave) eval destroy .}}
            interp delete $Editor::current(slave)
        }
        . configure -cursor {}
        return
}


proc Editor::file_copy {in out} {\

    if {[file exists $in]} {        
        file copy -force $in $out
    } else {
#        tk_messageBox -message "File $in doesnīt exist!" -type ok -icon warning -title "Warning"
    }
}
################################################################################
#proc Editor::getFile
#openfile dialog
#returns filename and content of the file
################################################################################
proc Editor::getFile {{filename {}}} {
    variable procWindow
    
    # workaround to avoid button1 events to the procWindow while
    # double clicking a file
    bind $procWindow <Button-1> {}
    
    if {$filename == {}} {    
        set filePatternList [list "Tcl-Files {*.tcl *.tk}" "All-Files {*.*}"]
        set defaultExt .tcl
        set initialFile ""
        set filename [tk_getOpenFile -filetypes $filePatternList -initialdir $Editor::workingDir -title "Open File"]
    }
    after 1000 {
        bind $Editor::procWindow <Button-1> {
            Editor::procList_history_add
            $Editor::procWindow selection clear 0 end
            $Editor::procWindow selection set @%x,%y          
            if { [$Editor::procWindow curselection] == 0} {
                $Editor::current(text) mark set insert 1.0
                $Editor::current(text) see insert
                focus $Editor::current(text)
                editorWindows::ReadCursor 0
                set Editor::current(lastPos) [$Editor::current(text) index insert]
            } elseif { [$Editor::procWindow curselection] == 1} {
                $Editor::current(text) mark set insert end-1c
                $Editor::current(text) see insert
                focus $Editor::current(text)
                editorWindows::ReadCursor 0
                set Editor::current(lastPos) [$Editor::current(text) index insert]
            } else  {
                editorWindows::gotoProc [$Editor::procWindow get [$Editor::procWindow curselection]]
                set Editor::current(lastPos) [$Editor::current(text) index insert]
            }
        }
    }
    if {[file exists $filename]} {
        set cursor [. cget -cursor]
       . configure -cursor watch
       update
      set fd [open $filename r+]
      set data [read $fd]
      close $fd
        . configure -cursor $cursor
      set Editor::workingDir [file dirname $filename]
      return [list $filename $data]
    }
}


proc Editor::openNewPage {{file {}}} {\
    variable notebook
    variable current
    variable workingDir
    
    set temp [Editor::getFile $file];#returns filename and textdata
    set filename [lindex $temp 0]
    if {$filename == ""} {return 1}
    set workingDir [file dirname $filename]
    set f0 [EditManager::create_text $notebook $filename]
    set data [lindex $temp 1]
    
#the new textwindow is actually not the current
#insertion will cause the undoer to set the current(hasChanged)
#therefor save and restore current(hasChanged)

#08.10.99: Since the undoer is now initialized after initialisation 
#of the new TextWindow, this should have no effect anymore!
    
    set temp $current(hasChanged)
    set editorWindows::TxtWidget [lindex $f0 2]
    $editorWindows::TxtWidget insert 1.0 $data
    $editorWindows::TxtWidget mark set insert 1.0 
    set current(hasChanged) $temp
    editorWindows::colorize; #needs TxtWidget !
    set Editor::text_win($Editor::index_counter,undo_id) [new textUndoer $editorWindows::TxtWidget]
    NoteBook::raise $notebook [lindex $f0 1]
    updateProcs
#Now the new textwindow is the current

    set current(hasChanged) 0
	set current(lastPos) [$current(text) index insert]
	procList_history_add    
    return 0
}

################################################################################
#proc Editor::setDefaultProject
#if default project file is set then this will be run from any window by 
#pressing the Test button instead of the current file, except for the current 
#file is associated to another projectfile
################################################################################
proc Editor::setDefaultProject {{filename {}}} {
    variable current
    variable defaultProjectFile
    variable defaultFile
    
    if {$filename == "none"} {
        switch [tk_messageBox -message "Do you want to unset current default project ?" \
                                                 -type yesnocancel -icon question -title Question] {
              yes {set defaultProjectFile "none"
                      set result [Editor::_saveFile $defaultFile $defaultProjectFile]
                      set prjFile [file rootname $current(file)].prj
                      if { ! [file exists $prjFile]} {
                          set current(project) "none"
                      } 
              }
              default {}
        }
        return
    }
    
    if {$filename == {}} {
        set filePatternList [list "Tcl-Files {*.tcl *.tk}" "All-Files {*.*}"]
        set defaultExt .tcl
        set initialFile ""
        set filename [tk_getOpenFile -filetypes $filePatternList -initialdir $Editor::workingDir -title "Select Default Project File"]
    }
    if {$filename != ""} {
        set defaultProjectFile $filename
        set result [Editor::_saveFile $defaultFile $defaultProjectFile]
        if {$current(project) == "none"} {
            set current(project) $defaultProjectFile
        }
    } 
}

################################################################################
#proc Editor::associateProject
#if there is a projectfile associated to the current file,
#this file will be started by pressing the test button.
#This overrides the option for the default project file    
################################################################################
proc Editor::associateProject {} {
    variable current
    variable defaultProjectFile
    
    set filePatternList [list "Tcl-Files {*.tcl *.tk}" "All-Files {*.*}"]
    set defaultExt .tcl
    set initialFile ""
    set filename [tk_getOpenFile -filetypes $filePatternList -initialdir $Editor::workingDir -title "Select Project File"]
    if {$filename != ""} {
        set current(project) $filename
        set prjFile [file rootname $current(file)].prj
        set result [Editor::_saveFile $prjFile $current(project)]
    }
}

proc Editor::unsetProjectAssociation {} {
    variable current
    variable defaultProjectFile
    
    set prjFile [file rootname $current(file)].prj
    if {[file exists $prjFile]} {
        file delete $prjFile
    }
    set current(project) $defaultProjectFile
}

proc Editor::openFile {{file {}}} {
    
    variable notebook
    variable current
    variable index
    variable last
   
    set deleted 0
# test if there is a page opened
    set pages [NoteBook::pages $notebook]
    if {[llength $pages] == 0} { \
        Editor::openNewPage
        return
    } else {
# test if current page is empty
        if {[info exists current(text)]} {\
            set f0 $current(pagename)
            set text [NoteBook::itemcget $notebook $f0 -text]
        
            set data [$current(text) get 1.0 end-1c]
            if {($data == "") && ($text == "Untitled")} {\
# page is empty 
                delete_id
                NoteBook::delete $notebook $current(pagename)
                unset index($current(text))
                set deleted 1
            }
        }
        set result [Editor::openNewPage $file]
        if {$deleted && $result} {            
             set force 1
            Editor::newFile force
        }
    }    
}

proc Editor::_saveFile {filename data} {

    if {$filename == "Untitled"} {
        Editor::_saveFileas $filename $data
        return
    }
    set cursor [. cget -cursor]
        . configure -cursor watch
    update
    set fd [open $filename w+]
    puts -nonewline $fd $data
    close $fd
      . configure -cursor $cursor
    return
}

proc Editor::saveFile {} {
    variable notebook
    variable current
    variable index
    
    set filename $current(file)
    if {$filename == "Untitled"} {
        Editor::saveFileas
        return
    }    
    set data [$current(text) get 1.0 end-1c]
    Editor::file_copy $filename "[file rootname $filename].bak"
    set result [Editor::_saveFile $current(file) $data]
    set current(hasChanged) 0
    set idx $index($current(text))
    set Editor::text_win($idx,hasChanged) $current(hasChanged)  
    if {$current(project) != "none"} {
        set prjFile [file rootname $current(file)].prj
        set result [Editor::_saveFile $prjFile $current(project)]
    }
}

proc Editor::_saveFileas {filename data} {
  
    set filePatternList [list "Tcl-Files {*.tcl *.tk}" "Alle {*.*}"]
    set defaultExt .tcl
    set initialFile $filename
    set file [tk_getSaveFile -filetypes $filePatternList -initialdir $Editor::workingDir \
                           -initialfile $filename -defaultextension $defaultExt -title "Save File"]
    if {$file != ""} {
        set cursor [. cget -cursor]
        . configure -cursor watch
        update
        set fd [open $file w+]
        puts -nonewline $fd $data
        close $fd
        . configure -cursor $cursor
    }
    set Editor::workingDir [file dirname $file]
    return $file
}


proc Editor::saveFileas {} {
    variable notebook
    variable current

    set filename $current(file)
    set data [$current(text) get 1.0 end-1c]
    set result [Editor::_saveFileas $current(file) $data]
    if {$result == ""} {return 1}
    set current(hasChanged) 0
    Editor::closeFile
    Editor::openNewPage $result
    #if there was already a .prj-File then copy to new name too
    if {[file exists [file rootname $filename].prj]} {
        set prjFile [file rootname $current(file)].prj
        set result [Editor::_saveFile $prjFile $current(project)]
    }
    Editor::file_copy $current(file) "[file rootname $current(file)].bak"
}

proc Editor::showConsole {show} {
    variable con_notebook
        
    set win [winfo parent $con_notebook]
    set win [winfo parent $win]
    set panedWin [winfo parent $win]
    update idletasks
    
    if {$show} {
        grid configure $panedWin.f0 -rowspan 1
        grid $panedWin.sash1
        grid $win
        grid rowconfigure $panedWin 2 -minsize 100
    } else  {
        grid remove $win
        grid remove $panedWin.sash1
        grid configure $panedWin.f0 -rowspan 3
    }
}

proc Editor::showProcWin {show} {
    variable list_notebook
        
    set win [winfo parent $list_notebook]
    set win [winfo parent $win]
    set panedWin [winfo parent $win]
    update idletasks
    
    if {$show} {
        grid configure $panedWin.f1 -column 2 -columnspan 1
        grid $panedWin.sash1
        grid $win
        grid columnconfigure $panedWin 0 -minsize 200
    } else  {
        grid remove $win
        grid remove $panedWin.sash1
        grid configure $panedWin.f1 -column 0 -columnspan 3
    }
}


################################################################################
#proc Editor::close_dialog
#called whenever the user wants to exit ASED and there are files
#that have changed and are still not saved yet
################################################################################
proc Editor::close_dialog {} {\
    variable notebook
    variable current
    variable index
    variable text_win
    
    set result [tk_messageBox -message "File <$current(file)> has changed!\n Save it ?" -type yesnocancel -icon warning -title "Question"]
    switch $result {
        yes {Editor::saveFile ; set result 0; return $result}
        no  {set result 0 ; return $result}
        cancel {set result 1 ; return $result}
    }
}


proc Editor::closeFile {} {

    variable notebook
    variable current
    variable index
    variable last
    variable text_win
    variable procWindow

    # Is there an open window
    if {[$notebook pages] == {}} {
        return
    }        
    if {$current(hasChanged)} {\
        set result [Editor::close_dialog]
        if {$result} {return $result}
    }
    if {[info exists current(undo_id)]} {delete_id}
    # if current file is running terminate execution
    Editor::terminate
    NoteBook::delete $notebook $current(pagename)
    unset index($current(text))
    set indexList [NoteBook::pages $notebook]
    if {[llength $indexList] != 0} {
        NoteBook::raise $notebook [lindex $indexList end] 
    } else {
        $procWindow delete 2 end
    }
    return 0
}
    

proc Editor::exit_app {} {

    variable notebook
    variable current
    variable index
    variable text_win

    set taskList [after info]
    foreach id $taskList {
        after cancel $id
    }
    if {$current(hasChanged)} {\
        set idx $index($current(text)) 
        set text_win($idx,hasChanged) $current(hasChanged)
    }
    set newlist ""
    set index_list [array names index]
    foreach idx $index_list {\
        set newlist [concat $newlist  $index($idx)]
    } 
#    if no window is open, we can exit at once

    if {[llength $newlist] == ""} {
        exit
    }
    
    Editor::getWindowPositions
    Editor::saveOptions
    
    foreach idx $newlist {\
        set current(text) $text_win($idx,path)
        set current(page) $text_win($idx,page)
        set current(pagename) $text_win($idx,pagename)
        set current(hasChanged) $text_win($idx,hasChanged)
        set current(undo_id) $text_win($idx,undo_id)
        set current(file) $text_win($idx,file)
        set current(slave) $text_win($idx,slave)
        set result [Editor::closeFile]
        if {$result} {\
            NoteBook::raise $notebook $current(pagename)
            return
        }
    }
    exit
}

proc Editor::gotoLineDlg {} {
    variable current
    
    set gotoLineDlg [toplevel .dlg]
    set entryLabel [label .dlg.label -text "Please enter line number"]
    set lineEntry [entry .dlg.entry -textvariable lineNo]
    set buttonFrame [frame .dlg.frame]
    set okButton [button $buttonFrame.ok -width 8 -text Ok -command {catch {destroy .dlg};Editor::gotoLine $lineNo}]
    set cancelButton [button $buttonFrame.cancel -width 8 -text Cancel -command {catch {destroy .dlg}}]
	wm title .dlg "Goto Line"
    bind $lineEntry <KeyRelease-Return> {.dlg.frame.ok invoke}
    pack $entryLabel
    pack $lineEntry
    pack $okButton $cancelButton -padx 10 -pady 10 -side left -fill both -expand yes
    pack $buttonFrame
    BWidget::place $gotoLineDlg 0 0 center
    focus $lineEntry
}
proc Editor::gotoLine {lineNo} {
	variable current
    if {[catch {$current(text) mark set insert $lineNo.0}]} {
        tk_messageBox -message "Line number out of range!" -icon warning -title "Warning"
    }
    $current(text) see insert
    editorWindows::flashLine
    checkProcs
    focus $current(text)
}

proc Editor::cut {} {
    variable current
    
    editorWindows::cut 
    Editor::updateProcs
    Editor::checkProcs
    set current(lastPos) [$current(text) index insert]
}

proc Editor::copy {} {
    variable current
    editorWindows::copy 
}

proc Editor::paste {} {
    
    variable current
    editorWindows::paste 
    Editor::updateProcs
    Editor::checkProcs
    set current(lastPos) [$current(text) index insert]
}

proc Editor::delete {} {
   variable current
   editorWindows::delete 
   Editor::updateProcs
   Editor::checkProcs
   set current(lastPos) [$current(text) index insert]
}

proc Editor::SelectAll {} {
    variable current
    
    $current(text) tag remove sel 1.0 end
    $current(text) tag add sel 1.0 end
}

proc Editor::getFirstChar { index } {
    
    set w $Editor::current(text)
    set curLine [lindex [split [$w index $index] "."] 0]
    set pos $curLine.0
    set char [$w get $pos]
    for {set i 0} { $char ==" "} {incr i} {
        set pos $curLine.$i
        set char [$w get $pos]
    }
    return [list $char $pos]
}

proc Editor::make_comment_block {} {
    variable current
    
    set commentLineString \
    "################################################################################\n"
    
    if {[$current(text) tag ranges sel] == ""} {
        #no selection
        set curPos [$current(text) index insert]
        set curLine [lindex [split [$current(text) index $curPos] "."] 0]
        $current(text) insert $curLine.0 $commentLineString
        editorWindows::ColorizeLine $curLine
    } else {
        set firstLine [lindex [split [$current(text) index sel.first] "."] 0]
        set lastLine [lindex [split [$current(text) index sel.last] "."] 0]
        for {set line $firstLine} {$line <= $lastLine} {incr line} {
            $current(text) insert $line.0 "# "           
        }
        $current(text) insert $firstLine.0 $commentLineString
        set lastLine [expr $lastLine+2]
        $current(text) insert $lastLine.0 $commentLineString
        for {set line $firstLine} {$line <= $lastLine} {incr line} {
            editorWindows::ColorizeLine $line
        }
        $current(text) tag remove sel sel.first sel.last
        $current(text) mark set insert "insert+2l linestart"
    }
    checkProcs
}

################################################################################
# proc Editor::toggle_comment
# toggles the comment status of the current line or selection
################################################################################
proc Editor::toggle_comment {} {
    variable current
   
    if {[$current(text) tag ranges sel] == ""} {
        #no selection
        set curPos [$current(text) index insert]
        set result [Editor::getFirstChar $curPos]
        if {[lindex $result 0]  == "#"} {
            $current(text) delete [lindex $result 1]
            set curLine [lindex [split [$current(text) index $curPos] "."] 0]
            editorWindows::ColorizeLine $curLine
        } else  {
            set curLine [lindex [split [$current(text) index $curPos] "."] 0]
            $current(text) insert $curLine.0 #            
            editorWindows::ColorizeLine $curLine
        }   
    } else {
        set firstLine [lindex [split [$current(text) index sel.first] "."] 0]
        set lastLine [lindex [split [$current(text) index sel.last] "."] 0]
        set result [Editor::getFirstChar $firstLine.0]
        set char [lindex $result 0]  
        if {$char == "#"} {
            #if first char of first line is # then uncomment selection complete
            for {set line $firstLine} {$line <= $lastLine} {incr line} {
                set result [Editor::getFirstChar $line.0]
                if {[lindex $result 0] == "#"} {
                    $current(text) delete [lindex $result 1]
                    after idle editorWindows::ColorizeLine $line
                }
            }                
        } else  {
            #if first char of first line is not # then comment selection complete
            for {set line $firstLine} {$line <= $lastLine} {incr line} {
                $current(text) insert $line.0 #           
                after idle editorWindows::ColorizeLine $line
            }
        }
        $current(text) tag remove sel sel.first sel.last        
    }
    checkProcs
}

proc Editor::procList_history_get_prev {} {
    variable current

    if  {$current(procListHistoryPos) == 0} {
        set index [$Editor::current(text) index insert]
        set Editor::current(lastPos) $index
        Editor::procList_history_add $index
    } elseif {$current(procListHistoryPos) == -1} {
        incr current(procListHistoryPos)
        set index [$Editor::current(text) index insert]
        set Editor::current(lastPos) $index
        Editor::procList_history_add $index
    }
    if {$current(procListHistoryPos) < [expr [llength $current(procListHistory)]-1]} {
        incr current(procListHistoryPos)
    } else  {
        return
    }
   
    $current(text) mark set insert [lindex $current(procListHistory) $current(procListHistoryPos)]
    $current(text) see insert
    focus $current(text)
    editorWindows::ReadCursor 0
    editorWindows::flashLine      
    checkProcs 0    
}
    
proc Editor::procList_history_get_next {} {
    variable current
    
    if {$current(procListHistoryPos) > 0} {
        incr current(procListHistoryPos) -1
    } else  {
        set current(procListHistoryPos) "-1"
        return
    }
    catch {$current(text) mark set insert [lindex $current(procListHistory) $current(procListHistoryPos)]}
    if {$current(procListHistoryPos) == 0} {
        set current(procListHistoryPos) "-1"        
    }
    
    $current(text) see insert
    focus $current(text)
    editorWindows::ReadCursor 0
    editorWindows::flashLine
    
    checkProcs 0
}


proc Editor::procList_history_add {{pos {}}} {
    variable current
    
    if {$pos == {}} {
        set index [$Editor::current(text) index insert]
        
    } else  {
        set index [$Editor::current(text) index $pos]
    }
    set lineNum [lindex [split $index "."] 0]
    set mark "mark$lineNum"
   
     if {![info exists Editor::current(procListHistory)]} {
         set Editor::current(procListHistory) [list "mark1"]
     } elseif {[lsearch $Editor::current(procListHistory) "$mark"] == 0} {
         $Editor::current(text) mark set $mark $index
         set Editor::current(procListHistoryPos) 0
         return
     }
    
    catch [$Editor::current(text) mark set $mark $index]
    
    set Editor::current(procListHistory) [linsert $Editor::current(procListHistory) 0 $mark]
    if {[llength $Editor::current(procListHistory)] > $Editor::current(procList_hist_maxLength)} {
        $Editor::current(text) mark unset [lindex $Editor::current(procListHistory) end]  
        set Editor::current(procListHistory) [lreplace $Editor::current(procListHistory) end end]
    }
    set Editor::current(procListHistoryPos) 0
}

proc Editor::lineNo_history_add {} {\
    variable lineEntryCombo
    variable lineNo
    set newlist [ComboBox::cget $lineEntryCombo -values]
    if {[lsearch -exact $newlist $lineNo] != -1} {return}
    set newlist [linsert $newlist 0 $lineNo]
    ComboBox::configure $lineEntryCombo -values $newlist
}

proc Editor::argument_history_add {} {\
    variable argument_combo
    variable argument_var
    set newlist [ComboBox::cget $argument_combo -values]
    if {[lsearch -exact $newlist $argument_var] != -1} {return}
    set newlist [linsert $newlist 0 $argument_var]
    ComboBox::configure $argument_combo -values $newlist
}

proc Editor::search_history_add {} {\
    variable search_combo
    variable search_var
    set newlist [ComboBox::cget $search_combo -values]
    if {[lsearch -exact $newlist $search_var] != -1} {return}
    set newlist [linsert $newlist 0 $search_var]
    ComboBox::configure $search_combo -values $newlist
}

proc Editor::search_forward {} {\
    global search_option_icase search_option_match search_option_blink
    variable search_combo
    variable current
    Editor::search_history_add    
    set search_string $Editor::search_var
    set result [Editor::search $current(text) $search_string search $search_option_icase\
                forwards $search_option_match $search_option_blink]
    focus -force $current(text)
    Editor::checkProcs
}


proc Editor::search_backward {{searchText {}}} {\
    global search_option_icase search_option_match search_option_blink
    variable search_combo
    variable current

    if {$searchText == {}} {
        Editor::search_history_add   
        set search_string $Editor::search_var
        set result [Editor::search $current(text) $search_string search $search_option_icase\
                    backwards $search_option_match $search_option_blink]
        
    } else  {
        set result [Editor::search $current(text) $searchText search 0\
                    backwards $search_option_match 0]
    }
    
    if {$result != ""} {$current(text) mark set insert [lindex $result 0]}
    focus -force $current(text)
    Editor::checkProcs
}

proc Editor::load_search_defaults {} {\
    search_default_options 
}

proc Editor::search {textWindow search_string tagname icase where match blink} {\
 	variable current   
	set result [search_proc $textWindow $search_string $tagname $icase $where $match $blink]
	editorWindows::ReadCursor 0
	set current(lastPos) [$current(text) index insert]        
	return $result
}

proc Editor::search_dialog {} {\
   
    variable current
   
   search_dbox $current(text)
   Editor::search_history_add
   focus -force $current(text)
}

proc Editor::replace_dialog {} {\
   variable current
   
   replace_dbox $current(text)
   focus -force $current(text)
}

proc Editor::undo {} {\
    variable notebook
    variable current

    set cursor [. cget -cursor]
    . configure -cursor watch
    update
    set range [textUndoer:undo $Editor::current(undo_id)]
    . configure -cursor $cursor
    if {$range != {}} {
       set startLine [lindex [split [$current(text) index [lindex $range 0]] "."] 0]
       set endLine [lindex [split [$current(text) index [lindex $range 1]] "."] 0]
       after idle editorWindows::ColorizeLines $startLine $endLine 
     }
    Editor::updateProcs
    Editor::checkProcs
    set current(lastPos) [$current(text) index insert]
    focus -force $current(text)
}

proc Editor::redo {} {\
   variable notebook
   variable current
   
    set cursor [. cget -cursor]
    . configure -cursor watch
    update
    set range [textRedoer:redo $Editor::current(undo_id)]
    . configure -cursor $cursor

    if {$range != {}} {
       set startLine [lindex [split [$current(text) index [lindex $range 0]] "."] 0]
       set endLine [lindex [split [$current(text) index [lindex $range 1]] "."] 0]
       after idle editorWindows::ColorizeLines $startLine $endLine 
    }
    Editor::updateProcs
    Editor::checkProcs
    set current(lastPos) [$current(text) index insert]
    focus -force $current(text)   
}


proc Editor::create { } {
    global tcl_platform 
    global clock_var
    global EditorData
    global rootDir
        
    variable _wfont
    variable notebook
    variable list_notebook
    
    variable pw2
    variable pw1
    variable procWindow
    variable markWindow
    variable mainframe
    variable font
    variable prgtext
    variable prgindic
    variable search_combo
    variable argument_combo
    variable current
    variable clock_label
    variable defaultFile
    variable defaultProjectFile
    variable Font_var
    variable FontSize_var
    variable options
    variable con_notebook
    

    set result [catch {source [file join $rootDir ased.cfg]} info]
    variable configError $result
    
    _create_intro
    update

    Editor::setDefault
    Editor::load_search_defaults
    Editor::tick

    # Menu description
    set descmenu {
        "&File" {} {} 0 {
            {command "&New" {} "New Text" {} -command Editor::newFile}
            {command "&Open" {}  "Open File" {} -command Editor::openFile}
            {command "&Save" {}  "Save active File" {} -command Editor::saveFile}
            {command "Save &as ..." {}  "Save active File as .." {} -command Editor::saveFileas}
            {command "&Close" {} "Close active File" {} -command Editor::closeFile }
            {separator}
            {command "E&xit" {}  "Exit ASED" {} -command Editor::exit_app}
        }
        "&Project" {} {} 0 {
            {command "Set &Default Project..." {} "Set Default Project" {} -command Editor::setDefaultProject }
            {command "&Unset Default Project" {} "Unset current Default ProjectFile" {} -command {Editor::setDefaultProject "none"} }
            {separator}
            {command "Set Project &Association..." {} "Associate current File to a Project" {} -command Editor::associateProject }
            {command "Unset Project Association..." {} "Clear current Project Association" {} -command Editor::unsetProjectAssociation }
            {separator}
            {command "&Execute " {} "Test current File" {} -command Editor::execFile }
            {command "&Terminate Execution " {} "Terminate Execution of current File" {} -command Editor::terminate  }            
        }
        "&Edit" {} {} 0 {
            {command "Copy" {} "Copy to Clipboard" {} -command Editor::copy }
            {command "Cut" {} "Cut to Clipboard" {} -command Editor::cut }
            {command "Paste" {} "Paste from Clipboard" {} -command Editor::paste }
            {command "Delete" {} "Delete Selection" {} -command Editor::delete }
            {separator}
            {command "Select all" {} "Select All" {} -command Editor::SelectAll }
            {separator}
            {command "Goto Line ..." {} "Goto Line" {} -command Editor::gotoLineDlg }
            {separator}
            {command "Search ..." {} "Search dialog" {} -command Editor::search_dialog }
            {command "Replace ..." {} "Replace dialog" {} -command Editor::replace_dialog }
            {separator}    
            {command "Undo" {} "Undo" {} -command Editor::undo }
            {command "Redo" {} "Redo" {} -command Editor::redo }
        }
        "&Options" all options 0 {
            {checkbutton "Main Toolbar" {all option} "Show/hide Main Toolbar" {}
                -variable Editor::toolbar1
                -command  {$Editor::mainframe showtoolbar 0 $Editor::toolbar1
                           set EditorData(options,showToolbar1) $Editor::toolbar1}
            }    
            {checkbutton "&Font Toolbar" {all option} "Show/hide Font Toolbar" {}
                -variable Editor::toolbar2
                -command  {$Editor::mainframe showtoolbar 1 $Editor::toolbar2
                          set EditorData(options,showToolbar2) $Editor::toolbar2}
            }
            {separator}
            {command "Increase Fontsize" {} "Increase Fontsize" {} -command {Editor::increaseFontSize up} }
            {command "Decrease Fontsize" {} "Decrease Fontsize" {} -command {Editor::increaseFontSize down} }
            {separator}
            {checkbutton "&Highlighting" {all option} "Use Keyword Highlighting" {}
                -variable Editor::options(useHL)
                -command  {set EditorData(options,useHL) $Editor::options(useHL)
                           editorWindows::colorize}
            }
            {checkbutton "&Indent" {all option} "Use Indent" {}
                -variable Editor::options(useIndent)
                -command  {set EditorData(options,useIndent) $Editor::options(useIndent)
                          }
            }
            {checkbutton "&SyntaxIndent" {all option} "Use Syntax Indent" {}
                -variable Editor::options(useSI)
                -command  {set EditorData(options,useSintaxIndent) $Editor::options(useSI)
                          }
            }
            
            {checkbutton "Templates for Keywords" {all option} "Use Templates for Keywords" {}
                -variable Editor::options(useKeywordTemplates)
                -command  {set EditorData(options,useTemplatesForKeywords) $Editor::options(useKeywordTemplates)
                          }
            }
            {checkbutton "Templates for \{" {all option} "Use Templates for Braces" {}
                -variable Editor::options(useBracesTemplates)
                -command  {set EditorData(options,useTemplatesForBrace) $Editor::options(useBracesTemplates)
                          }
            }
            {checkbutton "Templates for \(" {all option} "Use Templates for Paren" {}
                -variable Editor::options(useParenTemplates)
                -command  {set EditorData(options,useTemplatesForParen) $Editor::options(useParenTemplates)
                          }
            }
            {checkbutton "Templates for \[" {all option} "Use Templates for Bracket" {}
                -variable Editor::options(useBracketTemplates)
                -command  {set EditorData(options,useTemplatesForBracket) $Editor::options(useBracketTemplates)
                          }
            }
            {checkbutton "Templates for \"" {all option} "Use Templates for DblQuotes" {}
                -variable Editor::options(useQuotesTemplates)
                -command  {set EditorData(options,useTemplatesForQuoteDbl) $Editor::options(useQuotesTemplates)
                          }
            }
            {separator}
            {checkbutton "Change tabs into spaces" {all option} "Change tabs into spaces" {}
                -variable Editor::options(changeTabs)
                -command  {set EditorData(options,changeTabs) $Editor::options(changeTabs)
                          }
            }
            {separator}
            {checkbutton "Show Console" {all option} "Show Console Window" {}
                -variable Editor::options(showConsole)
                -command  {set EditorData(options,showConsole) $Editor::options(showConsole)
                            Editor::showConsole $EditorData(options,showConsole)
                          }
            }
            {checkbutton "Show Procs" {all option} "Show ProcList" {}
                -variable Editor::options(showProcs)
                -command  {set EditorData(options,showProcs) $Editor::options(showProcs)
                            Editor::showProcWin $EditorData(options,showProcs)
                          }
            }
        }
        "&Help" {} {} 0 {
            {command "About" {} "About" {} -command Editor::aboutBox }
        }    
    }

    set prgtext   "Creating MainFrame..."
    set prgindic  0
    set delta     [expr 100.0 / 10]
    set mainframe [MainFrame::create .mainframe -menu $descmenu \
                       -textvariable Editor::status \
                       -progressvar    Editor::prgindic ]
    set prgindic [expr $prgindic + $delta]

    # toolbar 1 creation
    set tb1  [MainFrame::addtoolbar $mainframe]
    set bbox [ButtonBox::create $tb1.bbox1 -spacing 0 -padx 1 -pady 1]
    ButtonBox::add $bbox -image [Bitmap::get new] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Create a new file" -command Editor::newFile
    ButtonBox::add $bbox -image [Bitmap::get open] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Open an existing file" -command Editor::openFile
    ButtonBox::add $bbox -image [Bitmap::get save] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Save file" -command Editor::saveFile
    ButtonBox::add $bbox -image [Bitmap::get delete] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Close File" -command Editor::closeFile
    
    pack $bbox -side left -anchor w
        
    set sep0 [Separator::create $tb1.sep0 -orient vertical]
    pack $sep0 -side left -fill y -padx 4 -anchor w
    set prgindic [expr $prgindic + $delta]

    set bbox [ButtonBox::create $tb1.bbox2 -spacing 0 -padx 1 -pady 1]
    ButtonBox::add $bbox -image [Bitmap::get cut] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Cut selection" -command Editor::cut
    ButtonBox::add $bbox -image [Bitmap::get copy] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Copy selection" -command Editor::copy
    ButtonBox::add $bbox -image [Bitmap::get paste] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Paste selection" -command Editor::paste
    
    pack $bbox -side left -anchor w
    set sep2 [Separator::create $tb1.sep2 -orient vertical]
    pack $sep2 -side left -fill y -padx 4 -anchor w
    set prgindic [expr $prgindic + $delta]
    
    set bbox [ButtonBox::create $tb1.bbox2b -spacing 0 -padx 1 -pady 1]
    ButtonBox::add $bbox -image [Bitmap::get toglcom] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Toggle Comment" -command Editor::toggle_comment
    ButtonBox::add $bbox -image [Bitmap::get comblock] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Make Comment Block" -command Editor::make_comment_block
    ButtonBox::add $bbox -image [Bitmap::get unindent] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Unindent Selection" -command editorWindows::unindentSelection
    ButtonBox::add $bbox -image [Bitmap::get indent] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Indent Selection" -command editorWindows::indentSelection
    pack $bbox -side left -anchor w

    set sep1c [Separator::create $tb1.sep1c -orient vertical]
    pack $sep1c -side left -fill y -padx 4 -anchor w

    set bbox [ButtonBox::create $tb1.bbox3 -spacing 0 -padx 1 -pady 1]
 
    ButtonBox::add $bbox -image [Bitmap::get undo] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Undo" -command Editor::undo 
    pack $bbox -side left -anchor w   

    ButtonBox::add $bbox -image [Bitmap::get redo] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Redo" -command Editor::redo 
    pack $bbox -side left -anchor w

    set sep3 [Separator::create $tb1.sep3 -orient vertical]
    pack $sep3 -side left -fill y -padx 4 -anchor w
    set prgindic [expr $prgindic + $delta]

    set bbox [ButtonBox::create $tb1.bbox4 -spacing 0 -padx 1 -pady 1]

    ButtonBox::add $bbox -image [Bitmap::get find] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Find Dialog" -command Editor::search_dialog 
    
    ButtonBox::add $bbox -image [Bitmap::get replace] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Replace Dialog" -command Editor::replace_dialog 
    
    pack $bbox -side left -anchor w
    
    set search_combo [ComboBox::create $tb1.combo -label "" -labelwidth 0 -labelanchor w \
                   -textvariable Editor::search_var\
                   -values {""} \
                   -helptext "Enter Searchtext" \
                   -entrybg white\
                   -width 15]
    pack $search_combo -side left

    set bbox [ButtonBox::create $tb1.bbox5 -spacing 1 -padx 1 -pady 1]
    
 
    set down_arrow [ArrowButton::create $bbox.da -dir bottom \
                                                 -height 21\
                                                 -width 21\
                                                 -helptype balloon\
                                                 -helptext "Search forwards"\
                                                 -command Editor::search_forward]
    set up_arrow [ArrowButton::create $bbox.ua -dir top\
                                               -height 21\
                                               -width 21\
                                               -helptype balloon\
                                               -helptext "Search backwards"\
                                               -command Editor::search_backward]
    
    
    pack $down_arrow $up_arrow -side left
    pack $bbox -side left -anchor w
    

    set sep [Separator::create $tb1.sep -orient vertical]
    pack $sep -side left -fill y -padx 4 -anchor w
    
    set bbox [ButtonBox::create $tb1.bbox1b -spacing 0 -padx 1 -pady 1]
    ButtonBox::add $bbox -image [Bitmap::get stop] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Terminate Execution" -command Editor::terminate
    

    pack $bbox -side left -anchor w -padx 2
    
    set bbox [ButtonBox::create $tb1.bbox1c -spacing 1 -padx 1 -pady 1]
    
    set right_arrow [ArrowButton::create $bbox.ua -dir right\
                                               -height 21\
                                               -width 21\
                                               -helptype balloon\
                                               -helptext "Test Application"\
                                               -command {
                                                    set code [catch Editor::execFile cmd]
                                                    if $code {
                                                        tk_messageBox -message $errorInfo -title Error -icon error
                                                    }
                                                }]    
    
    pack $right_arrow -side left -padx 4
    pack $bbox -side left -anchor w
    
    set argument_combo [ComboBox::create $tb1.combo2 -label "" -labelwidth 0 -labelanchor w \
                   -textvariable Editor::argument_var\
                   -values {""} \
                   -helptext "Enter optional argument" \
                   -entrybg white\
                   -width 15]
    pack $argument_combo -side left
    
    set sep4 [Separator::create $tb1.sep4 -orient vertical]
        pack $sep4 -side left -fill y -padx 4 -anchor w
        set prgindic [expr $prgindic + $delta]
    
    set bbox [ButtonBox::create $tb1.bbox6 -spacing 1 -padx 1 -pady 1]
    ButtonBox::add $bbox -image [Bitmap::get exitdoor] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Exit Ased" -command Editor::exit_app
    pack $bbox -side right -anchor w 
    
    #get Entry path out of Combo Widget
    set childList [winfo children $search_combo]
    foreach w $childList {if {[winfo class $w] == "Entry"} { set entry $w ; break}}
    bind $entry <KeyRelease-Return> {Editor::search_forward ; break}
    set childList [winfo children $argument_combo]
    foreach w $childList {if {[winfo class $w] == "Entry"} { set entry2 $w ; break}}
    bind $entry2 <KeyRelease-Return> {
                        set code [catch Editor::execFile cmd]
                        if $code {
                            tk_messageBox -message $errorInfo -title Error -icon error
                        }
                        break
    }

    # toolbar 2 creation
    set tb2  [MainFrame::addtoolbar $mainframe]
    
    set bbox [ButtonBox::create $tb2.bbox2 -spacing 0 -padx 1 -pady 1]
 
    ButtonBox::add $bbox -image [Bitmap::get incfont] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Increase Fontsize" -command {Editor::increaseFontSize up}
    pack $bbox -side left -anchor w   

    ButtonBox::add $bbox -image [Bitmap::get decrfont] \
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
        -helptext "Decrease Fontsize" -command {Editor::increaseFontSize down} 
    pack $bbox -side left -anchor w
    set sep3 [Separator::create $tb2.sep3 -orient vertical]
    pack $sep3 -side left -fill y -padx 4 -anchor w
    set Editor::Font_var [font configure editorFont -family]
    set Font_combo [ComboBox::create $tb2.combo -label "" -labelwidth 0 -labelanchor w \
                   -textvariable Editor::Font_var\
                   -values [font families] \
                   -helptext "Choose Font" \
                   -entrybg white\
                   -modifycmd {Editor::changeFont}\
                   ]
    pack $Font_combo -side left
    set Editor::FontSize_var [font configure editorFont -size]
    set FontSize_combo [ComboBox::create $tb2.combo2 -width 2 -label "" -labelwidth 0 -labelanchor w \
                   -textvariable Editor::FontSize_var\
                   -values {8 9 10 11 12 14 16 20 24 30} \
                   -helptext "Choose Fontsize" \
                   -entrybg white\
                   -modifycmd {Editor::changeFont}\
                   ]
    pack $FontSize_combo -side left
    
    $Editor::mainframe showtoolbar 0 $Editor::toolbar1
    $Editor::mainframe showtoolbar 1 $Editor::toolbar2
    
    set prgindic [expr $prgindic + $delta]
# set statusbar indicator for file-directory clock and Line/Pos 
    set temp [MainFrame::addindicator $mainframe -text "Current Project: " ]
    set temp [MainFrame::addindicator $mainframe -textvariable Editor::current(project) ]
    set temp [MainFrame::addindicator $mainframe -text " File: " ]
    set temp [MainFrame::addindicator $mainframe -textvariable Editor::current(file) ]
    set temp [MainFrame::addindicator $mainframe -textvariable EditorData(cursorPos)]
    set temp [MainFrame::addindicator $mainframe -textvariable clock_var]
#    set temp [MainFrame::addindicator $mainframe -textvariable Editor::current(hasChanged)]
    
# NoteBook creation

    set frame    [$mainframe getframe]
    
    set pw1 [PanedWindow::create $frame.pw -side left]
    set pane [PanedWindow::add $pw1];# -minsize 100]    
    set pw2 [PanedWindow::create $pane.pw -side top]  
    
    
    set pane1 [PanedWindow::add $pw2 -minsize 100]
    set pane2 [PanedWindow::add $pw2 -minsize 100]
    set pane3 [PanedWindow::add $pw1 -minsize 100]

    set list_notebook [NoteBook::create $pane1.nb]
    set notebook [NoteBook::create $pane2.nb]  
    set con_notebook [NoteBook::create $pane3.nb] 

    set pf0 [EditManager::create_procWindow $list_notebook ]

    set procWindow $pf0.sw.proc
    
    bind $procWindow <Button-1> {
        catch {
            Editor::procList_history_add
            $Editor::procWindow selection clear 0 end
            $Editor::procWindow selection set @%x,%y          
            if { [$Editor::procWindow curselection] == 0} {
                $Editor::current(text) mark set insert 1.0
                $Editor::current(text) see insert
                focus $Editor::current(text)
                editorWindows::ReadCursor 0
                set Editor::current(lastPos) [$Editor::current(text) index insert]
                return
            }
            if { [$Editor::procWindow curselection] == 1} {
                $Editor::current(text) mark set insert end-1c
                $Editor::current(text) see insert
                focus $Editor::current(text)
                editorWindows::ReadCursor 0
                set Editor::current(lastPos) [$Editor::current(text) index insert]
                return
            }
            editorWindows::gotoProc [$Editor::procWindow get [$Editor::procWindow curselection]]
            set Editor::current(lastPos) [$Editor::current(text) index insert]

        }
    }

    set f0 [EditManager::create_text $notebook "Untitled"]
    set Editor::text_win($Editor::index_counter,undo_id) [new textUndoer [lindex $f0 2]]
    set prgindic [expr $prgindic + $delta]

    NoteBook::compute_size $list_notebook
    pack $list_notebook -side left -fill both -expand yes -padx 4 -pady 4
    
    NoteBook::compute_size $notebook 
    pack $notebook -side left -fill both -expand yes -padx 4 -pady 4    
    
    pack $pw2 -fill both -expand yes
    
    set cf0 [EditManager::create_conWindow $con_notebook]
    NoteBook::compute_size $con_notebook
    pack $con_notebook -side bottom -fill both -expand yes -padx 4 -pady 4
      
    pack $pw1 -fill both -expand yes    
    
    $list_notebook raise Proclist
    $con_notebook raise asedCon
    $notebook raise [lindex $f0 1]
    set prgindic [expr $prgindic + $delta]
    set prgtext   "Done"
    
    pack $mainframe -fill both -expand yes
    
    update idletasks
    destroy .intro
    wm protocol . WM_DELETE_WINDOW Editor::exit_app
    
    if {!$configError} {catch Editor::restoreWindowPositions}
}

proc Editor::changeFont {} {
    global EditorData
    variable index
    variable text_win
    variable Font_var
    variable FontSize_var
    
    
    font configure editorFont -family $Font_var \
                              -size $FontSize_var
    set EditorData(options,fonts,editorFont) [font configure editorFont]
    
    font configure commentFont -family $Font_var \
                              -size $FontSize_var
    set EditorData(options,fonts,commentFont) [font configure commentFont]
    
    font configure keywordFont -family $Font_var \
                              -size $FontSize_var
    set EditorData(options,fonts,keywordFont) [font configure keywordFont]
    
    set newlist ""
    set index_list [array names index]
    foreach idx $index_list {\
        set newlist [concat $newlist  $index($idx)]
    } 
    
    foreach idx $newlist {\
        editorWindows::onChangeFontSize $text_win($idx,path)
    }
    
}
proc Editor::increaseFontSize {direction} {
    global EditorData
    
    variable notebook
    variable current
    variable index
    variable text_win
    variable list_notebook
    variable pw2
    variable con_notebook
    variable pw1
    variable mainframe
    variable FontSize_var
    
    
    set minSize 8
    set maxSize 30
    
    set newlist ""
    set index_list [array names index]
    foreach idx $index_list {\
        set newlist [concat $newlist  $index($idx)]
    } 
    
    if {$direction == "up"} {
        if {[font configure editorFont -size] == $maxSize} {
            return
        }
        font configure editorFont -size [expr [font configure editorFont -size]+1]                
        set EditorData(options,fonts,editorFont) [font configure editorFont]
        font configure commentFont -size [expr [font configure commentFont -size]+1]                
        set EditorData(options,fonts,commentFont) [font configure commentFont]
        font configure keywordFont -size [expr [font configure keywordFont -size]+1]                
        set EditorData(options,fonts,keywordFont) [font configure keywordFont]
    } else  {
        if {[font configure editorFont -size] == $minSize} {
            return
        }
        font configure editorFont -size [expr [font configure editorFont -size]-1]                
        set EditorData(options,fonts,editorFont) [font configure editorFont]
        font configure commentFont -size [expr [font configure commentFont -size]-1]                
        set EditorData(options,fonts,commentFont) [font configure commentFont]
        font configure keywordFont -size [expr [font configure keywordFont -size]-1]                
        set EditorData(options,fonts,keywordFont) [font configure keywordFont]
    }
    
    
    foreach idx $newlist {\
        editorWindows::onChangeFontSize $text_win($idx,path)
    }
    set FontSize_var [font configure editorFont -size]
}

proc Editor::update_font { newfont } {
    variable _wfont
    variable notebook
    variable font
    variable font_name
    variable current

    . configure -cursor watch
    if { $font != $newfont } {
        SelectFont::configure $_wfont -font $newfont
        set raised [NoteBook::raise $notebook]
        $current(text) configure -font $newfont
        set font $newfont
    }
    . configure -cursor ""
}


proc Editor::_create_intro { } {
    global tcl_platform
    global rootDir

    set top [toplevel .intro -relief raised -borderwidth 2]

    wm withdraw $top
    wm overrideredirect $top 1

    set image [image create photo -file [file join $rootDir images/ased.gif]]
    set splashscreen  [label $top.x -image $image]
    pack $splashscreen
    BWidget::place $top 0 0 center
    wm deiconify $top
}


proc main {argc argv} {
    global tcl_platform
    global auto_path
    global EditorData

    lappend auto_path ..

    package require Tk 8.0

    

    option add *TitleFrame.font {helvetica 11 bold italic}

    wm withdraw .
    wm title . "ASED Tcl/Tk-IDE"
    
    Editor::create
    BWidget::place . 0 0 center
    if {$argc >= 1} {
        foreach filename $argv {
            if {[file exists $filename]} {
                Editor::openFile $filename
            } elseif {[file exists [file join [pwd] $filename]]} {
                Editor::openFile [file join [pwd] $filename]
            }
        }
    }
    
    update idletasks
    if {[info exists EditorData(options,mainWinSize)]} {
        wm geom . $EditorData(options,mainWinSize)
        update idletasks
    } 
    after idle {
        wm deiconify .
        raise .
        focus -force .
    }
}

main $argc $argv
