# This code updates the list box in place,
# I.e. a line at a time.
# it works with the old list (glob(inst,filelist))
# and a new list which it gets from glob(inst,pwd)
# it takes "inst" (left or right)as a parameter
# We want to do sane things with the selection but there are issues
# If we insert or delete in the "listvariable" and the current selection 
# is after the delete or insert point, the selection shifts to an
# ajacent element (next if delete, prior if insert), however, if
# we insert or delete using the wiget command, the selection stays
# with the old element.
# On the otherhand, if we update an element using delete and insert
# the selection is lost and, if the last element is being displayed
# and there are more elements than fix in the window, the window is
# scrolled such that the last element is no longer visable.
# So, for update of an existing entry we use the "listvariable" 
# and for deletion and insert we use the wiget command.
#

proc updateInPlace {inst} {
  global glob
  # frputs "Enter updateinplace ************************************* "
  set old $glob($inst,filelist)
  set glob($inst,filelist) [GetDirList $inst]
  set oindx [set nindx 0]
  foreach ent $glob($inst,filelist) {
    # if {[lindex $ent 1] != [lindex $glob($inst,filelist) $nindx 1] } {
    #   frputs "Out of step  " last ind nindx oindx
    # }
    if {[lindex $old $oindx 1] != [lindex $ent 1]} {
      # we don't match. Either this is a new entry or there are deleted
      # entries.  If this file appears later in the old list, we need
      # to delete entries and check for update.
      # If it does not, we insert this entry.
      set ind [lsearch -exact -start $oindx -index 1 $old [lindex $ent 1]]
      if {$ind == -1} {
	# Not found, we need to insert this one
	#frputs "Insert  " nindx oindx
	fileListBoxInsert $inst $ent $nindx
	incr nindx
	continue
      }
      # We found it and it is $ind (relative to oindx).  Since both 
      # list are sorted we can delete all those up to here and then update
      #frputs "Delete entry  " nindx ind oindx "**********[expr {$ind - $oindx}] "
      fileListBoxDelete $inst $nindx [expr {$nindx + $ind - $oindx -1}]
      set oindx $ind
    }
    # same file, test if any changes
    fileListBoxUpdate $inst $nindx [lindex $old $oindx]
    set selUpdate($oindx) $nindx
    incr oindx
    incr nindx
  }
  if {$glob(select_cur_lr) == $inst} {
    # if there are current selections in this panel, update the selection list
    set glob(select_cur_s) [$glob(listbox,$inst).file curselection]
  }
  if {$glob(select_pry_lr) == $inst} {
    # if there are prior selections in this panel, update the pry list
    # a little messier but, we kept track above.
    set newPry {}
    foreach sel $glob(select_pry_s) {
      if {[info exists selUpdate($sel)] } {
	lappend newPry $selUpdate($sel)
      }
    }
    set glob(select_pry_s) $newPry
  }
}

proc fileListBoxDelete {inst from to} {
  global glob config
  
  foreach lbentry $config(ListBoxColumns,$inst) {
    set flist [lindex $lbentry 0]
    $glob(listbox,$inst).$flist delete $from $to
  }
  
}

proc fileListBoxUpdate {inst indx oldin} {
  global glob config
  if {[lindex $glob($inst,filelist) $indx] == $oldin} {return}
  lassign [lindex $glob($inst,filelist) $indx] {*}$glob(fListEl)
  set sindx 2
  #lassign [$glob(listbox,$inst).file yview] ypos yypos
  foreach old [lrange $oldin 3 end] \
      new [lrange [lindex $glob($inst,filelist) $indx] 3 end] {
	incr sindx
	if {$old == $new} {continue}
	set flist [lindex $glob(fListEl) $sindx]
	set no [llength $glob($inst,lvfile)]
	if {[lsearch -exact -index 0 \
		 $config(ListBoxColumns,$inst) $flist] == -1} {
	  # if column is not displayed, try the next one
	  continue
	}
	#frputs "Updating entry  " indx flist
	# The braces are needed because catch wants to do the
	# concat thing... 
	if {[catch "lset glob($inst,lv$flist) $indx \
		    {[eval $glob(lbscript,$flist)]}" out] != 0} {
	  frputs "ListBoxUpdate failed  " indx "[llength $glob($inst,lv$flist)]  " out flist
	}
      }
}

proc fileListBoxInsert {inst ent indx} {
  global glob config
  # insert "ent" at index indx in the "inst" file pane
  #set no [expr {[llength $glob($inst,lvfile)] + 1}]
  lassign $ent {*}$glob(fListEl)
  set ffile [lindex $ent 1][switch -glob -- $type {
      *ld {expr {"@/"}} 
      *d  {expr {"/"}} 
      *l  {expr {"@"}} 
      *n  {expr {""}} 
    }]
  foreach lbentry $config(ListBoxColumns,$inst) {
    set flist [lindex $lbentry 0]
    $glob(listbox,$inst).$flist insert $indx [eval $glob(lbscript,$flist)]
    # while {[llength $glob($inst,lv$flist)] != $no} {
    #   update idletasks
    #   if {[incr loop] >20} {break}
    # }
    # frputs "Insert wait loop  "  indx flist no loop
  }
}
