#ASED asedCon
global asedCon
global conWindow


proc flashWin {win delay} {
    set color [$win cget -bg]
    $win configure -bg red
    update    
    after $delay
    $win configure -bg $color
    update
}

proc conPuts {var {win {}} {flash 0} {see 1} } {
    global prompt
    global conWindow

    if {$win == {}} {
        set win $conWindow
    }
#    if [winfo exists $win] {
        eval $win insert end "$var" stdin
        $win insert end "\n$prompt % "
        $win mark set insert end
        if $see {$win see insert}
        if $flash {
            flashWin $win $flash
        }
#    } else  {
#        tk_messageBox -message "$var\n\nAPPLICATION CANCELED !" -title Error -icon error
#    }
}

proc consolePuts {args} {
    global prompt
    global conWindow
    global errorInfo
    
    set win $conWindow
    
    set argcounter [llength $args]
    switch $argcounter {
        1 {conPuts $args}
        2 {
            if {[lindex $args 0] == "-nonewline"} {
                conPuts [lindex $args 1]
            } else {
               set code [catch {eval puts $args} info]
               if $code {conPuts $errorInfo {} 1000 0} else {conPuts [lindex $args 1]}
            }
            }
        3 {
                if {[lindex $args 0] == "-nonewline"} {
                    if {[info exists [lindex $args 1]]} {
                        conPuts [lindex $args 2]
                    } else {
                           set code [catch {eval puts $args} info]
                           if $code {conPuts $errorInfo {} 1000 0} else {conPuts [lindex $args 2]}
                    }    
                } else {
                   set code [catch {eval puts $args} info]
                   if $code {conPuts $errorInfo {} 1000 0} else {conPuts [lindex $args 2]}
                }
             }
        default {
            set code [catch {eval puts $args} info]
            if $code {conPuts $errorInfo {} 1000 0}
        }    
    }   
#    history add [list puts $args]
}

proc reset {} {
    global asedCon
    interp eval $asedCon {
        if {[lsearch [package names] Tk] != -1} {
            foreach child [winfo children .] {
                if {[winfo exists $child]} {destroy $child}
            }        
            wm withdraw .
        }
    }
}
    
# proc evalCommand
# executes commands within a seperate interpreter
# runs also windows commands via exec
# ToDo:
# 1. should run also Linux/Unix-commands
proc evalCommand {window Interp command} {
    global errorInfo
    global env
    global code cmd     
    global prompt
    global historyIndex
    global linestart
    global tcl_platform
    
    set historyIndex 0
    set linestart [expr [string length $prompt] +3]
    
    proc SetValues {_code _cmd _errorInfo} {
        global code cmd errorInfo
        set code $_code
        set cmd $_cmd
        set errorInfo $_errorInfo
    }
    
    if {$command != {}} {
        history add $command
        interp eval $Interp set command [list ""]
        set code [catch {interp eval $Interp lappend command $command} cmd]
        if {$code} {
            $window insert end \n$cmd\n stdin
            set prompt [file tail [pwd]]
            set linestart [expr [string length $prompt] +3]
            $window insert end "$prompt % "
            $window mark set insert end
            $window see insert
            return
        }
        if {[info commands [lindex $command 0]] == "puts"} {$window insert end \n }        
        interp eval $Interp {
            set code [catch {eval $command} cmd]
            setValues $code $cmd $errorInfo
        }
        if {!$code} {            
            if {$cmd != {}} {
                $window insert end \n$cmd } 
        } else  {
            if {[info commands [lindex $command 0]] != ""} {
                $window insert end "\n$errorInfo\n"
            } else  {
                if {$tcl_platform(platform) == "windows"} {                
                    set comspec [file split $env(COMSPEC)]
                    set temp ""
                    foreach item $comspec {
                        set temp [file join $temp $item]
                    }
                    set execComspec [concat $temp /c $command]
                } else {
                    set execComspec $command
                }
                set code [catch {eval exec $execComspec} cmd]
                if {!$code} {
                    if {$cmd != {}} {$window insert end \n$cmd\n stdin}
                } else  {
                    $window insert end "\n$errorInfo\n"
                }
            }
        }
    }     
    set prompt [file tail [pwd]]
    set linestart [expr [string length $prompt] +3]
    if {[lindex $command 0] != "puts"} {$window insert end "\n$prompt % "}
    $window mark set insert end
    $window see insert
}


proc getCommand {window} {
    global prompt
    
    set offset [expr [string length $prompt] +3]
    set command [$window get "end-1l linestart+$offset char" "end-1l lineend"]
    return $command
}

proc searchHistory {direction} {
    global historyIndex
    switch $direction {
        backwards {                 
            if {$historyIndex > -20} {
                set command [history event $historyIndex]               
                incr historyIndex -1
                return $command
            } else  {
                return {}
            }
        }
        forwards {               
            if {$historyIndex < -1} {
                incr historyIndex
                set command [history event [expr $historyIndex+1]]
                return $command
            } else  {
                return {}
            }
        }
        default {tk_messageBox -message "Internal Error" -type ok; return}
    }
    
}

proc onKeyPressed {win} {
    global linestart
    if {[lindex [split [$win index insert] .] 1] < $linestart} {
        $win mark set insert end
        $win see insert
    }
}

proc onButtonPressed {win} {
    global linestart
    if {[lindex [split [$win index insert] .] 1] < $linestart} {
        $win mark set insert end
        $win see insert
    }
}

proc onKeyHome {win} {
    global prompt
    $win mark set insert "insert linestart + [expr [string length $prompt] +3] char"
}

proc onKeyUp {win} {
    global prompt
    $win mark set insert end
    $win delete "insert linestart" "insert lineend"
    set command [searchHistory backwards] 
    $win insert "insert linestart" "$prompt % $command"
    $win see insert
}

proc onKeyDown {win} {
    global prompt
    $win mark set insert end
    $win delete "insert linestart" "insert lineend"
    set command [searchHistory forwards]
    $win insert "insert linestart" "$prompt % $command" 
    $win see insert
}

proc onKeyLeft {win} {
    global linestart
    
    set CurPos [lindex [split [$win index insert] "."] 1]
    set temp [$win index insert]
    if {$CurPos <= $linestart} {
        return {}
    } else  {
        $win mark set insert insert-1c
    }
}

proc onKeyBackSpace {win} {
    global linestart
    
    set CurPos [lindex [split [$win index insert] "."] 1]
    if {$CurPos <= $linestart} {
            return {}
    }  else  {
            $win delete insert-1c
    }
}


proc consoleInit {win {width 60} {height 5}} {
    global asedCon
    global prompt
    global window
    global historyIndex
    global linestart
    global EditorData
    
    set historyIndex 0
    set window $win
    set prompt [file tail [pwd]]
    set linestart [expr [string length $prompt] +3]

    if {$window == "."} {
        set window ""
    }
    set asedCon [interp create]


    $asedCon alias setValues SetValues
    $asedCon alias exit reset
    $asedCon alias puts consolePuts
    interp share {} stdout $asedCon
    interp share {} stderr $asedCon    
    text $window.t -font $EditorData(options,fonts,editorFont) -width $width -height $height -bg white    
    $window.t insert end "$prompt % "    
    bind $window.t <Key-Return> {evalCommand $window.t $asedCon [getCommand $window.t];break}
    bind $window.t <Key-Up> {onKeyUp $window.t; break}
    bind $window.t <Key-Down> {onKeyDown $window.t; break}
    bind $window.t <Key-Left> {onKeyLeft $window.t; break}        
    bind $window.t <Key-BackSpace> {onKeyBackSpace $window.t;break}
    bind $window.t <Key-Home> {onKeyHome $window.t ;break}
    bind $window.t <Control-c> {set dummy nothing}
    bind $window.t <Key> {if {([lindex [split [$window.t index insert] .] 1] < $linestart) \
        || ([lindex [split [$window.t index insert] .] 0] < [lindex [split [$window.t index "end-1l"] .] 0])} break}
    pack $window.t 
    return $window.t
}