############################################################
# cut an element from an extended entry to the clipboard
############################################################
proc extEntryCut {path prefix name row} {
  global __scrollBar __editInfo __children __widgetArgs __windows

  set function $__editInfo(name)

  ### first of all copy the entry
  extEntryCopy $path $prefix $name $row

  ### move all elements one down and close all windows in this
  ### extentry.
  moveElm -1 $prefix $name $row

  ### Telling the scrollbar that there's one less element
  set firstUnit  [lindex $__scrollBar(${prefix}_$name) 0]
  set total  [expr [lindex $__scrollBar(${prefix}_$name) 1] -1]
  set count $__widgetArgs(${function}__${name}__count)
  if {$firstUnit > $total - $count} {
    set firstUnit [expr $total - $count]
  }
  if {$firstUnit < 0} {
    set firstUnit 0
  }
  set __scrollBar(${prefix}_$name) "$firstUnit $total"

  ### packing the extentry again, so __state and __scrollBar will be updated.
  Pack $path $prefix $name 0 top 0 1
}

############################################################
# copy and element from an extended entry to the clipboard
############################################################
proc extEntryCopy {path prefix name row} {
  global __clipboardName __state __scrollBar __fillList __widgetArgs
  set __clipboardName $name

  ### erasing old variables
  foreach varname [uplevel \#0 "info vars __clipboard_*"] {
    uplevel \#0 "unset $varname"
  }
  foreach varname [array names __state clipboard_*] {
    unset __state($varname)
  }
  foreach varname [array names __scrollBar clipboard_*] {
    unset __scrollBar($varname)
  }
  
  ### copying the ordanary variables
  foreach varname [uplevel \#0 "info vars ${prefix}_$name${row}_*"] {
    upvar \#0 $varname var
    if {![regexp "^${prefix}_$name${row}_(.*)\$" $varname all lastname]} {
      error "Couldn't match $varname with ${prefix}_$name${row}_"
    }
    upvar \#0 __clipboard_$lastname clipboard
    set clipboard $var
  }

  ### copying the variable __state
  foreach varname [array names __state ${prefix}_$name${row}_*] {
    if {![regexp "^${prefix}_$name${row}_(.*)\$" $varname all lastname]} {
      error "Couldn't match $varname with ${prefix}_$name${row}_"
    }
    set __state(clipboard_$lastname) $__state($varname)
  }

  ### copying the variable __scrollBar
  foreach varname [array names __scrollBar ${prefix}_$name${row}_*] {
    if {![regexp "^${prefix}_$name${row}_(.*)\$" $varname all lastname]} {
      error "Couldn't match $varname with ${prefix}_$name${row}_"
    }
    set __scrollBar(clipboard_$lastname) $__scrollBar($varname)
  }
  ### copying the variable __fillList
  foreach varname [array names __fillList ${prefix}_$name${row}_*] {
    if {![regexp "^${prefix}_$name${row}_(.*)\$" $varname all lastname]} {
      error "Couldn't match $varname with ${prefix}_$name${row}_"
    }
    set __fillList(clipboard_$lastname) $__fillList($varname)
  }
}

############################################################
#     insert into an extended entry from the clipboard
############################################################
proc extEntryPaste {path prefix name row} {
  global __scrollBar __state __fillList

  ### move all element one up
  moveElm +1 $prefix $name $row

  ### first ordanary variables
  set count [lindex $__scrollBar(${prefix}_$name) 1]
  foreach varname [uplevel \#0 "info vars __clipboard_*"] {
    upvar \#0 $varname clipboard
    if {![regexp {^__clipboard_(.*)$} $varname all lastname]} {
      error "Couldn't match $varname with __clipboard_"
    }
    upvar \#0 ${prefix}_$name${row}_$lastname var
    set var $clipboard
  }

  ### the __state variable
  foreach varname [array names __state clipboard_*] {
    if {![regexp {^clipboard_(.*)$} $varname all lastname]} {
      error "Couldn't match $varname with clipboard_"
    }
    set __state(${prefix}_$name${row}_$lastname) $__state(clipboard_$lastname)
  }
  ### the __scrollBar variable
  foreach varname [array names __scrollBar clipboard_*] {
    if {![regexp {^clipboard_(.*)$} $varname all lastname]} {
      error "Couldn't match $varname with clipboard_"
    }
    set __scrollBar(${prefix}_$name${row}_$lastname) \
        $__scrollBar(clipboard_$lastname)
  }
  ### the __fillList variable
  foreach varname [array names __fillList clipboard_*] {
    if {![regexp {^clipboard_(.*)$} $varname all lastname]} {
      error "Couldn't match $varname with clipboard_"
    }
    set __fillList(${prefix}_$name${row}_$lastname) $__fillList(clipboard_$lastname)
  }

  ### Telling the scrollbar that there's one more element
  set __scrollBar(${prefix}_$name) \
      "[lindex $__scrollBar(${prefix}_$name) 0] [expr $count+1]"

  ### packing the extentry again, so __state and __scrollBar will be updated.
  Pack $path $prefix $name 0 top 0 1
}

############################################################
#       insert a blank tuple into an extended entry
############################################################
proc extEntryInsert {path prefix name row} {
  global __scrollBar __children __editInfo __initFunc changeElm __activeNivau
  global __widgetArgs
  
  moveElm +1 $prefix $name $row
  
  set count [lindex $__scrollBar(${prefix}_$name) 1]
  set function $__editInfo(name)

  ### Telling the scrollbar that there's one more element
  set __scrollBar(${prefix}_$name) \
      "[lindex $__scrollBar(${prefix}_$name) 0] [expr $count+1]"

  foreach child $__children(${function}__$name) {
    setVariable $function $child ${prefix}_$name$row {} 1
  }

  # calling the init and change function
  set childs $__children(${function}__$name)
  UpdateActive [lindex $childs 0] ${prefix}_$name$row
  set changeElm $name
  uplevel \#0 $__initFunc($function)
  set __activeNivau($name) $row
  foreach child $childs {
    changeAll $child
  }

  ### packing the extentry again, so __state and __scrollBar will be updated.
  Pack $path $prefix $name 0 top 0 1
}

############################################################
# This function move the element in an extentry one up or
# one down, from an element to the end.
############################################################
proc moveElm {direction prefix name row} {
  global __scrollBar __state __fillList __changed __widgetArgs __windows

  set __changed 1; # the configuration page has changed

  ### closing all windows
  foreach elm [array names __windows ${prefix}_$name*] {
    set _path [lindex $__windows($elm) 1]
    set _prefix [lindex $__windows($elm) 2]
    set _name [lindex $__windows($elm) 3]
    set result [closeWindow $_path $_prefix $_name]
    if {$result == "error"} return
  }


  set count [lindex $__scrollBar(${prefix}_$name) 1]

  if {$direction == -1} {
    # copy things downwards (removed an element)
    set actualRow [expr $row+1]
    set test {$actualRow < $count}
  } else {
    # copy things upwards (inserted an element)
    set actualRow [expr $count-1]
    set test {$actualRow >= $row}
  }
  set d $direction
  
  for {} {[expr $test]} {incr actualRow [expr -$direction]} {
    ### ordanary variables
    foreach varname [uplevel \#0 "info vars ${prefix}_$name[expr $actualRow + $d]_*"] {
      uplevel \#0 unset $varname
    }
    foreach varname [uplevel \#0 "info vars ${prefix}_$name${actualRow}_*"] {
      upvar \#0 $varname from
      if {![regexp "^${prefix}_$name${actualRow}_(.*)\$" $varname all lastname]} {
        error "Couldn't match $varname with ${prefix}_$name${actualRow}_"
      }
      upvar \#0 ${prefix}_$name[expr $actualRow+$d]_$lastname to
      set to $from
    }
    ### the __state variable
    foreach varname [array names __state ${prefix}_$name${actualRow}_*] {
      if {![regexp "^${prefix}_$name${actualRow}_(.*)\$" $varname all lastname]} {
        error "Couldn't match $varname with ${prefix}_$name${actualRow}_"
      }
      set __state(${prefix}_$name[expr $actualRow+$d]_$lastname) $__state($varname)
    }
    ### the __scrollBar variable
    foreach varname [array names __scrollBar ${prefix}_$name${actualRow}_*] {
      if {![regexp "^${prefix}_$name${actualRow}_(.*)\$" $varname all lastname]} {
        error "Couldn't match $varname with ${prefix}_$name${actualRow}_"
      }
      set __scrollBar(${prefix}_$name[expr $actualRow+$d]_$lastname) \
          $__scrollBar($varname)
    }
    ### the __fillList variable
    foreach varname [array names __fillList ${prefix}_$name${actualRow}_*] {
      if {![regexp "^${prefix}_$name${actualRow}_(.*)\$" $varname all lastname]} {
        error "Couldn't match $varname with ${prefix}_$name${actualRow}_"
      }
      set __fillList(${prefix}_$name[expr $actualRow+$d]_$lastname) $__fillList($varname)
    }
  }
}
