# Copyright (C) 1999 - Martin Strauss - under terms of GPL
##################################################################
# Undo function
proc proc_undo {E} {
global UndoArray
 event generate $E <<proc_undo>>
 if {[llength $UndoArray($E)] != 0} then {
 set liste [lindex $UndoArray($E) end]
 set UndoArray($E) [lrange $UndoArray($E) 0 [expr [llength $UndoArray($E)] - 2]]
 switch [lindex $liste 0] insert {
  set ksp [$E index "insert linestart"]
  $E insert [lindex $liste 1] "[lindex $liste 2]"
  Syntax $E $ksp "insert lineend"
 } delete {
  $E delete [lindex $liste 1] [lindex $liste 2]
 } UndoMul {
  proc_undo $E
  proc_undo $E
 }
}
}
##########################
# gliedert tag ein
proc undo_tag E {
global UndoArray

set sel_flag 0
if {[$E tag nextrange undo 1.0 end] != ""} then {
 set flag 0
 foreach {A O} [$E tag ranges undo] {
  if $flag {
   if {[$E index $KO+1c] != $A} {
    lappend UndoArray($E) "delete $KA $KO"
    set KA $A
   }
  } {
   set flag 1
   set KA $A
  }
  set KO $O
 }
 lappend UndoArray($E) "delete $KA $KO"
 $E tag remove undo 1.0 end
}
}
#########################
# max laenge des undo Speichers
proc undo_maxlength E {
global UndoArray max_undo
while {[string length $UndoArray($E)] > $max_undo} {
 if {[llength $UndoArray($E)] != 0} then {
  set UndoArray($E) [lrange $UndoArray($E) 1 end]
 } else break
}
}
##########################
#
proc undo_switch {E L} {
global UndoArray undo_switch_sel_flag
foreach i $L {
 switch $i UndoMax {
   undo_maxlength $E

  } Save {
  # Text sammeln und sichern
  undo_tag $E

 } Delete {
  # Delete speichern
  lappend UndoArray($E) "insert [$E index [lindex $LIST 0]] [backslash [$E get [lindex $LIST 0] [lindex $LIST 1]]]"
  $E delete [lindex $LIST 0] [lindex $LIST 1]

 } UndoBegin {
  # Textmarke setzen
  $E mark set UndoBegin insert
  $E mark gravity UndoBegin left

 } UndoEnd {
  # Texttag setzen
  $E tag add undo UndoBegin insert

 } SelSave {
  if {[$E tag nextrange sel 1.0 end] != ""} then {
   undo_tag $E
   lappend UndoArray($E) "insert [$E index sel.first] [backslash [$E get sel.first sel.last]]"
   set undo_switch_sel_flag 1
  } {set undo_switch_sel_flag 0}
 } SelMul {
  if $undo_switch_sel_flag {
   undo_tag $E
   lappend UndoArray($E) UndoMul
   $E mark set UndoBegin insert
   $E mark gravity UndoBegin left
  }
 } BeginMark {
  $E tag add undo BeginMark-1c BeginMark
 } UndoMul {
  lappend UndoArray($E) UndoMul
 } DeleteKey {
  if {$undo_switch_sel_flag == 0} then {
   set ksp ""
   if {[lindex $UndoArray($E) end] != ""} then {
    if {[lindex [lindex $UndoArray($E) end] 0] == "insert"} then {
     if {[lindex [lindex $UndoArray($E) end] 1] == [$E index insert]} then {
      set ksp [lindex [lindex $UndoArray($E) end] 2]
      set UndoArray($E) [lrange $UndoArray($E) 0 [expr [llength $UndoArray($E)] - 2]]
     }
    }
   }
   lappend UndoArray($E) "insert [$E index insert] [backslash $ksp][backslash [$E get insert]]"
  }
 } BackSpaceKey {
  if {$undo_switch_sel_flag == 0} then {
   set ksp ""
   if {[lindex $UndoArray($E) end] != ""} then {
    if {[lindex [lindex $UndoArray($E) end] 0] == "insert"} then {
     if {[lindex [lindex $UndoArray($E) end] 1] == [$E index insert]} then {
      set ksp [lindex [lindex $UndoArray($E) end] 2]
      set UndoArray($E) [lrange $UndoArray($E) 0 [expr [llength $UndoArray($E)] - 2]]
     }
    }
   }
   lappend UndoArray($E) "insert [$E index insert-1c] [backslash [$E get insert-1c]][backslash $ksp]"
  }
 } default {
  set LIST $i
 }
}
}