# jentryedt.tcl - support for EDT entry bindings
# 
# Copyright 1994-1995 by Achim Bohnet <ach@rosat.mpe-garching.mpg.de>.
# This file may be freely redistributed in whole or in part.
#
# Modified by Jay Sekora.  Achim's version was more general, sharing a lot
# of procedures between Entry and Text bindings.  That's a direction I want
# to go in, but I didn't have time to integrate it into my sources. ---j.

#	 EDT (emulation of the standard VAX/VMS AXP/VMS editor)

###############################################################################
# to do:   	- all commands repeatable (j:text does it but why j:text:bof??
#		- use private selection for edt-/paste/cut/append/clear
###############################################################################

proc j:eb:edt_init { e } {
  global j_teb
  ::aq::debug "'edt' bound to '$e'"
  
  set j_teb(cutbuffer) {}
  set j_teb(dragscroll,txnd) 0
  set j_teb(dragscroll,delay) 50
  set j_teb(scanpaste_time) 0
  set j_teb(scanpaste_paste) 1
    
  set j_teb(keymap,$e) edt-normal
  
  # not impl. up to now: set j_ed(edt,$t,select,on) 0

  j:eb:key_bind $e
  j:eb:mouse_bind $e
  
  j:ekb:mkmap Entry edt-normal edt-normal {
    {Up				j:eb:beep}
    {Down			j:ekb:down}
    {Left			j:ekb:left}
    {Right			j:ekb:right}
    
    {Find			j:eb:beep}
    {Insert			j:eb:beep}
    {apLineDel			j:eb:beep}
    {Select			j:eb:beep}
    {Prior			j:eb:beep}
    {Next			j:eb:beep}
    
    {KP_F1			j:ekb:edt:gold}
    {KP_F2			::aq::beep}
    {KP_F2_X			j:ekb:edt:help-bindings}
    {KP_F3			::aq::beep}
    {KP_F3_X			j:ekb:find-next}
    {KP_F4			j:ekb:edt:del-line}
    
    {KP_0			j:ekb:edt:line}
    {KP_1			j:ekb:edt:word}
    {KP_2			j:ekb:edt:eol}
    {KP_3			j:ekb:edt:char}
    {KP_4			j:ekb:edt:advance}
    {KP_5			j:ekb:edt:backup}
    {KP_6			::aq::beep}
    {KP_6_X			j:ekb:edt:cut-range}
    {KP_7			j:ekb:edt:page}
    {KP_8			::aq::beep}
    {KP_8_X			j:ekb:edt:append}
    {KP_9			::aq::beep}
    {KP_9_X			j:ekb:edt:replace}
    
    {KP_Subtract		j:ekb:edt:del-word}
    {KP_Separator		j:ekb:edt:del-char}
    {KP_Enter			j:eb:beep}
    {KP_Decimal			j:eb:beep}
    {KP_Decimal_X		j:ekb:edt:sel-range}
    
    {Return			j:eb:no_op}
    {BackSpace			j:ekb:delete_left}
    {Delete			j:ekb:delete_left}
    
    {Control-DEFAULT		j:ekb:self_insert}
    {DEFAULT			j:ekb:self_insert}
    {Shift-DEFAULT		j:ekb:self_insert}
  }
  
  j:ekb:mkmap Entry edt-gold edt-normal {

    {Up				j:eb:beep}
    {Down			j:eb:beep}
    {Left			j:ekb:left}
    {Right			j:ekb:right}

    {Find			j:eb:beep}
    {Insert			j:eb:beep}
    {apLineDel			j:eb:beep}
    {Select			j:eb:beep}
    {Prior			j:eb:beep}
    {Next			j:eb:beep}

    {KP_F1			j:eb:beep}
    {KP_F2			j:ekb:edt:help}
    {KP_F3			j:ekb:find-string}
    {KP_F4_X			j:ekb:edt:restore-line}

    {KP_2_X			j:ekb:edt:open-line}
    {KP_1_X			j:ekb:change-case}
    {KP_2			j:ekb:edt:del-eol}
    {KP_3_X			j:ekb:literal-insert}
    {KP_4			j:ekb:edt:bottom}
    {KP_5			j:ekb:edt:top}
    {KP_6			j:ekb:edt:ins-buffer paste}
    {KP_7_X			j:ekb:edt:command}
    {KP_8_X			j:ekb:edt:fill}
    {KP_9_X			j:ekb:edt:replace}

    {KP_Subtract_X		j:ekb:edt:restore-word}
    {KP_Separator_X		j:ekb:edt:restore-char}
    {KP_Enter_X			j:ekb:g-Enter}
    {KP_Decimal_X		j:ekb:g-Decimal}

    {0				j:ekb:continue_number}
    {1				j:ekb:continue_number}
    {2				j:ekb:continue_number}
    {3				j:ekb:continue_number}
    {4				j:ekb:continue_number}
    {5				j:ekb:continue_number}
    {6				j:ekb:continue_number}
    {7				j:ekb:continue_number}
    {8				j:ekb:continue_number}
    {9				j:ekb:continue_number}

    {Control-DEFAULT		j:eb:beep}
    {DEFAULT			j:eb:beep}
    {Shift-DEFAULT		j:eb:beep}
  }
  
#   j:bind:set_map edt-normal $class
#		{Alt-a			literal-insert ä}
#		{Alt-A			literal-insert ä}
#		{Alt-o			literal-insert ö}
#		{Alt-O			literal-insert Ö}
#		{Alt-u			literal-insert ü}
#		{Alt-U			literal-insert Ü}
#		{Alt-s			literal-insert ß}
}

#####################################################################
# Public routines

#####################################################################

proc j:ekb:edt:gold { w k a } {
  j:ekb:new_mode edt-gold $w $k $a
}

#####################################################################

proc j:ekb:edt:top { w k a } { $w icursor 0 }
proc j:ekb:edt:bottom { w k a } { $w icursor end }

proc j:ekb:edt:char { w k a } { j:eb:edt:move ekb "" $w $k $a }

proc j:ekb:edt:word { w k a } { j:eb:edt:move ekb word_ $w $k $a }

proc j:eb:edt:move { sfx range w k a } {
  if [j:eb:edt:isForw $w] {
    j:$sfx:${range}right $w $k $a
  } else {
    j:$sfx:${range}left $w $k $a
  }
}

proc j:ekb:edt:line { w k a } { j:eb:edt:line ekb bol $w $k $a }

proc j:ekb:edt:eol { w k a } { j:eb:edt:line ekb eol $w $k $a }

proc j:eb:edt:line { sfx to w k a } {
  if [j:eb:edt:isForw $w] {
    if [j:eb:is_$to $w] {
      j:eb:beep $w
      #### j:$sfx:down $w $k $a
    }
  } else {
    if [j:eb:is_$to $w] {
      j:eb:beep $w
      #### j:$sfx:up $w $k $a
    }
  }
  j:$sfx:$to $w $k $a
}

#####################################################################

proc j:ekb:edt:del-char { w k a } { j:eb:edt:delChar ekb $w $k $a }

proc j:eb:edt:delChar { sfx w k a} {
  if [j:eb:edt:isForw $w] {
    ##### SHOULD RECORD CHAR HERE
    j:$sfx:delete_right $w $k $a
  } else {
    ##### SHOULD RECORD CHAR HERE
    j:$sfx:delete_left $w $k $a
  }
}

proc j:ekb:edt:del-word { w k a } { j:eb:edt:delWord ekb $w $k $a }

proc j:eb:edt:delWord { sfx w k a } {
  if [j:eb:edt:isForw $w] {
    ##### SHOULD RECORD WORD HERE
    j:$sfx:delete_right_word $w $k $a
  } else {
    ##### SHOULD RECORD WORD HERE
    j:$sfx:delete_left_word $w $k $a
  }
}

##### SHOULD RECORD LINE:
proc j:ekb:edt:del-eol { w k a } { j:ekb:kill_eol $w }

proc j:ekb:edt:del-line { w k a } {j:ekb:kill_eol $w }

# proc j:tkb:edt:del-eol { w k a } {
#   j:ed:buf:insert $w line insert "insert lineend"
#   $w delete insert "insert lineend"
# }

proc j:ekb:edt:ins-buffer { name w k a } {
  set oldpos [$w index insert]
  j:ed:buf:get $w $name insert
  $w icursor $oldpos 
}

#####################################################################

proc j:ekb:edt:page { w k a } { j:eb:beep $w }

#####################################################################

proc j:ekb:edt:advance { w k a } {
  j:eb:edt:setForw $w
}

proc j:ekb:edt:backup { w k a } {
  j:eb:edt:setBack $w
}

#####################################################################
#####################################################################
# Internally used routines
#####################################################################
#####################################################################


#####################################################################
# Prodecure set for editing direction handling

proc j:eb:edt:isForw { w } {
  global j_ed
  
  if { ! [info exists j_ed(edt,$w,forward)]} {
    set j_ed(edt,$w,forward) 1
  }
  return $j_ed(edt,$w,forward)
}

proc j:eb:edt:setForw { w } { global j_ed; set j_ed(edt,$w,forward) 1 }
proc j:eb:edt:setBack { w } { global j_ed; set j_ed(edt,$w,forward) 0 }

#####################################################################
# Procedures handling select/paste
#
#	* wrong should handle its own selection mark NOT the	**
#	** X11 one. Too many side effects!			**
#
#proc j:ekb:edt:selectOn { w } {
#	global j_ed
#	set start [$w index insert]
#
#	set j_ed(edt,$w,select,on) 1
#	set j_ed(edt,$w,select,start) $start
#	set j_ed(edt,$w,select,final) $start
#	$w select from $start
#}
#proc j:ekb:edt:selectOff { w } {
#	global j_ed
#	set start [$w index insert]
#
#}
#proc j:ebk:edt:selectOff { w } {
#	global j_ed
#	if ![info exists j_ed(edt,$w,select,on)] {return 0}
#	if !$j_ed(edt,$w,select,on) {
#		set $j_ed(edt,$w,select,on) 0
#		$w select from [$w index insert]
#		$w select to [$w index insert]
#		return
#	}
#}
