# Program: xf
# Description: specify packing for widget
#
# $Header: xfpacking.tcl fuddled for Tk 3.3 by 850347s@dragon.acadiau.ca$

###
# Bugs:
# the window opens with the listboxes squished!
# - (not any more, but it meant giving an explicit
#   wm command... i think XFTmpltToplevel is messed up)
###

# xfPack(currMaster)
# the current master being edited in the 

# xfPack(enablePUP)
# used to disable the dialogue widgets while they're being
# set to match the slave

# xfPackConfgEdit($slave)
# changes to packing configuration for slave $slave

# xfPackConfgOrig($slave)
# original geometry management for $slave

# xfPackOrderEdit($master)
# packing order for $master since last apply

# xfPackOrderOrig($master)
# original packing order for $master

# xfPack(Forget)
# log of slaves to forget

##########
# Procedure: XFPacking
# Description: specify packing for widget
# Arguments: xfW - the widget we configure
#            xfType - the type of configuration (add, config)
#            xfClass - ignored
#            xfLeader - the leading window
# Returns: none
# Sideeffects: none
##########
proc XFPacking {xfW xfType xfClass {xfLeader ""}} {
  global xfBind xfPack xfStatus xfConf
       
  XFEditSetStatus "Calling packing..."

  set xfPack(expand) 0
  set xfPack(packAnchor) center
  set xfPack(fillX) 0
  set xfPack(fillY) 0
  set xfPack(side) top
  set xfPack(currMaster) ""
  set xfPack(enablePUP) 0

  XFPackingClearUndo

  # build widget structure
  XFTmpltToplevel .xfPacking 500x600 \
   "XF packing:[XFMiscPathTail $xfW]" $xfLeader
  # the window wasn't getting the right size until i added this
  # is XFTmpltToplevel screwed up???
  wm geometry .xfPacking 500x600

  XFTmpltFrame .xfPacking.frame1 0

  button .xfPacking.frame1.ok \
    -text {OK}\
    -command "XFPackingApply;destroy .xfPacking"

  button .xfPacking.frame1.apply \
    -text {Tentative}\
    -command "XFPackingApply;XFPackingGetOrder;XFPackingGetPacking"

  checkbutton .xfPacking.frame1.applyperm \
    -text {Synchronous} \
    -variable xfConf(applyPacking) \
    -command {
      if {$xfConf(applyPacking)} {XFPackingApply}
      .xfPacking.functions.remaster config -state [if {$xfConf(applyPacking)} {format normal} {format disabled}]
    }\
    -onvalue 1 \
    -offvalue 0

  button .xfPacking.frame1.confident \
    -text {Confident}\
    -command "XFPackingApply;XFPackingClearUndo;XFPackingGetOrder;XFPackingGetPacking"

  button .xfPacking.frame1.undo \
    -text {Undo}\
    -command "XFPackingUndoPacking;XFPackingGetOrder;XFPackingGetPacking"

  button .xfPacking.frame1.cancel \
    -text {Cancel}\
    -command "XFPackingUndoPacking;destroy .xfPacking"

  XFTmpltFrame .xfPacking.additional 0

  button .xfPacking.additional.parameters \
    -text {Master Parameters}\
    -command "XFProcConfParametersSmall \$xfPack(currMaster) .xfPacking"

  button .xfPacking.additional.chldparameters \
    -text {Slave parameters}\
    -command "
      set xfCurSelected \
        \[.xfPacking.frame2.children.childs.childs curselection\]
      if {\$xfCurSelected >= 0} {
        XFProcConfParametersSmall \[lindex \[.xfPacking.frame2.children.childs.childs get \$xfCurSelected\] 1\] .xfPacking
      }"

  button .xfPacking.additional.binding \
    -text {Master Bindings}\
    -command "XFProcConfBinding \$xfPack(currMaster) .xfPacking"

  button .xfPacking.additional.chldbinding \
    -text {Slave bindings}\
    -command "
      set xfCurSelected \
        \[.xfPacking.frame2.children.childs.childs curselection\]
      if {\$xfCurSelected >= 0} {
        XFProcConfBinding \[lindex \[.xfPacking.frame2.children.childs.childs get \$xfCurSelected\] 1\] .xfPacking
      }"

  XFTmpltFrame .xfPacking.functions 0

  button .xfPacking.functions.rescan \
    -text {Rescan}\
    -command "
      XFMiscReadTree \$xfPack(currMaster) .xfPacking.frame2.children.widgets.widgets all;XFPackingGetOrder;XFPackingGetPacking"

  button .xfPacking.functions.manageslave \
    -text {Manage Slave}\
    -command {
      set xfCS [.xfPacking.frame2.children.childs.childs curselection]
      if {$xfCS >= 0} {
        XFPackingMakeMaster [lindex [.xfPacking.frame2.children.childs.childs get $xfCS] 1]
      }
    }

  button .xfPacking.functions.managemaster \
    -text {Manage Master}\
    -command {
      if {![catch {pack newinfo $xfPack(currMaster)} xfCS]} {
      XFPackingMakeMaster [lindex $xfCS 1]
      }
    }

  button .xfPacking.functions.remaster\
    -text {Enslave}\
    -command {XFPackingRemaster}\
    -state [if {$xfConf(applyPacking)} {format normal} {format disabled}]

  button .xfPacking.functions.unchild \
    -text {Forget}\
    -command "XFPackingForgetSlave"

  XFTmpltFrame .xfPacking.frame2

  XFTmpltFrame .xfPacking.frame2.side 0

  XFTmpltFrame .xfPacking.frame2.expand 0

  XFTmpltFrame .xfPacking.frame2.fill 0

  XFTmpltFrame .xfPacking.frame2.anchor 0

  XFTmpltFrame .xfPacking.frame2.anchor.f1 0

  XFTmpltFrame .xfPacking.frame2.anchor.f2 0

  XFTmpltFrame .xfPacking.frame2.anchor.f3 0

  XFTmpltFrame .xfPacking.frame2.chldframe 0

  XFTmpltFrame .xfPacking.frame2.children 0

  label .xfPacking.frame2.side.message2 \
    -text {Side:}

  foreach xfi {top bottom left right} {
    radiobutton .xfPacking.frame2.side.$xfi \
      -text [string toupper [string range $xfi 0 0]][string range $xfi 1 end] \
      -value $xfi \
      -variable xfPack(side)\
      -command "XFPackingSmallUpdate  -side \$xfPack(side)"    
  }
  .xfPacking.frame2.side.top select

  checkbutton .xfPacking.frame2.expand.expand \
    -text {Expand widget} \
    -variable xfPack(expand) \
    -command "XFPackingSmallUpdate  -expand \$xfPack(expand)"\
    -onvalue 1 \
    -offvalue 0

  label .xfPacking.frame2.fill.message4 \
    -text {Fill:}

  checkbutton .xfPacking.frame2.fill.fillx \
    -text {X} \
    -command "XFPackingSmallUpdate  -fill \[lindex {none x y both} \[expr \$xfPack(fillX)+\$xfPack(fillY)\]\]"\
    -onvalue 1 \
    -offvalue 0 \
    -variable xfPack(fillX)

  checkbutton .xfPacking.frame2.fill.filly \
    -text {Y} \
    -command "XFPackingSmallUpdate  -fill \[lindex {none x y both} \[expr \$xfPack(fillX)+\$xfPack(fillY)\]\]"\
    -onvalue 2 \
    -offvalue 0 \
    -variable xfPack(fillY)

  label .xfPacking.frame2.anchor.message5 \
    -text {Anchor:}

  foreach xfi {nw w sw n center s ne e se} {
    radiobutton .xfPacking.frame2.anchor.$xfi\
      -anchor w \
      -command "XFPackingSmallUpdate  -anchor \$xfPack(packAnchor)"\
      -value $xfi\
      -text [if {$xfi == "center"} {format "C"} {string toupper $xfi}] \
      -variable xfPack(packAnchor)
  }

  XFTmpltFrame .xfPacking.frame2.chldframe.pad 0

  XFTmpltFrame .xfPacking.frame2.chldframe.ipad 0
  label .xfPacking.frame2.chldframe.ipad.label\
    -text "Internal Padding:"
  scale .xfPacking.frame2.chldframe.ipad.xscale\
    -from 0 \
    -label "X" \
    -orient horizontal \
    -relief sunken \
    -sliderlength 15 \
    -to 300 \
    -command "XFPackingSmallUpdate  -ipadx"\
    -width 8
  scale .xfPacking.frame2.chldframe.ipad.yscale\
    -from 0 \
    -label "Y" \
    -orient horizontal \
    -relief sunken \
    -sliderlength 15 \
    -to 300 \
    -command "XFPackingSmallUpdate  -ipady"\
    -width 8

  XFTmpltFrame .xfPacking.frame2.chldframe.epad 0
  label .xfPacking.frame2.chldframe.epad.label\
    -text "External Padding:"
  scale .xfPacking.frame2.chldframe.epad.xscale\
    -from 0 \
    -label "X" \
    -orient horizontal \
    -relief sunken \
    -sliderlength 15 \
    -to 300 \
    -command "XFPackingSmallUpdate  -padx"\
    -width 8
  scale .xfPacking.frame2.chldframe.epad.yscale\
    -from 0 \
    -label "Y" \
    -orient horizontal \
    -relief sunken \
    -sliderlength 15 \
    -to 300 \
    -command "XFPackingSmallUpdate  -pady"\
    -width 8

  XFTmpltListbox .xfPacking.frame2.children widgets
  .xfPacking.frame2.children.widgets.widgets config -geometry 10x5

  label .xfPacking.frame2.children.widgets.message6 \
    -text {Widgets}\
    -borderwidth 0
  pack configure .xfPacking.frame2.children.widgets.message6\
    -fill x\
    -before .xfPacking.frame2.children.widgets.vscroll
               
  XFTmpltListbox .xfPacking.frame2.children childs
  .xfPacking.frame2.children.childs.childs config -geometry 10x5

  frame .xfPacking.frame2.children.childs.message6\
    -borderwidth 0
  label .xfPacking.frame2.children.childs.message6.fix \
    -text {Slaves of }\
    -borderwidth 0
  label .xfPacking.frame2.children.childs.message6.var \
    -textvariable xfPack(currMaster)\
    -borderwidth 0
  pack configure .xfPacking.frame2.children.childs.message6.fix .xfPacking.frame2.children.childs.message6.var\
    -side left
  pack configure .xfPacking.frame2.children.childs.message6\
    -fill x\
    -before .xfPacking.frame2.children.childs.vscroll
              
  scale .xfPacking.frame2.children.childs.mover \
    -orient vertical \
    -width 8 \
    -sliderlength 15 \
    -from 0\
    -command "XFPackingReorder"

  pack configure .xfPacking.frame2.children.childs.mover\
    -side right\
    -fill y\
    -before .xfPacking.frame2.children.childs.vscroll
  
  XFMiscReadTree $xfW .xfPacking.frame2.children.widgets.widgets all

  XFPackingMakeMaster $xfW 

  # bindings
  bind .xfPacking.frame2.children.widgets.widgets <Double-[string range $xfBind(select1) 1 end] {
    set xfCS [.xfPacking.frame2.children.widgets.widgets curselection]
    if {$xfCS >= 0} {
      XFPackingMakeMaster [lindex [.xfPacking.frame2.children.widgets.widgets get $xfCS] 1]
    }
  }
  bind .xfPacking.frame2.children.widgets.widgets <Button1-Motion> "
    XFBindSelectOne %W %y"
  bind .xfPacking.frame2.children.widgets.widgets <Shift-ButtonPress-1> "
    XFBindSelectOne %W %y"
  bind .xfPacking.frame2.children.widgets.widgets <Shift-Button1-Motion> "
    XFBindSelectOne %W %y"


  bind .xfPacking.frame2.children.childs.childs <ButtonPress-1> "
    XFBindSelectOne %W %y"
  bind .xfPacking.frame2.children.childs.childs <Button1-Motion> "
    XFBindSelectOne %W %y"
  bind .xfPacking.frame2.children.childs.childs <ButtonRelease-1> "
    XFBindSelectOne %W %y
    XFPackingGetPacking "
  bind .xfPacking.frame2.children.childs.childs <Button1-Motion> "
    NoFunction"

  # packing
  pack configure .xfPacking.frame1.ok .xfPacking.frame1.apply .xfPacking.frame1.applyperm .xfPacking.frame1.confident .xfPacking.frame1.undo .xfPacking.frame1.cancel\
    -side left\
    -fill both\
    -expand 1
  pack configure .xfPacking.functions.managemaster .xfPacking.functions.manageslave .xfPacking.functions.rescan .xfPacking.functions.remaster .xfPacking.functions.unchild\
    -side left\
    -fill both\
    -expand 1
  pack configure .xfPacking.additional.parameters .xfPacking.additional.chldparameters .xfPacking.additional.binding .xfPacking.additional.chldbinding\
    -side left\
    -fill both\
    -expand 1
  pack configure .xfPacking.frame2.side.message2 .xfPacking.frame2.side.top .xfPacking.frame2.side.bottom .xfPacking.frame2.side.left .xfPacking.frame2.side.right\
    -side left

  pack configure .xfPacking.frame2.chldframe.epad.label\
    -side top\
    -anchor w
  pack configure .xfPacking.frame2.chldframe.epad.xscale\
    -side left\
    -fill x\
    -expand true
  pack configure .xfPacking.frame2.chldframe.epad.yscale\
    -side right\
    -fill x\
    -expand true

  pack configure .xfPacking.frame2.chldframe.ipad.label\
    -side top\
    -anchor w
  pack configure .xfPacking.frame2.chldframe.ipad.xscale\
    -side left\
    -fill x\
    -expand true
  pack configure .xfPacking.frame2.chldframe.ipad.yscale\
    -side right\
    -fill x\
    -expand true

  pack configure .xfPacking.frame2.chldframe.ipad .xfPacking.frame2.chldframe.epad\
    -fill x

  pack configure .xfPacking.frame2.expand.expand\
    -side bottom\
    -pady 6
  pack configure .xfPacking.frame2.fill.message4 .xfPacking.frame2.fill.fillx .xfPacking.frame2.fill.filly\
    -side left

  pack configure .xfPacking.frame2.anchor.nw .xfPacking.frame2.anchor.w .xfPacking.frame2.anchor.sw\
    -in  .xfPacking.frame2.anchor.f1\
    -fill x
  pack configure .xfPacking.frame2.anchor.n .xfPacking.frame2.anchor.center .xfPacking.frame2.anchor.s\
    -in  .xfPacking.frame2.anchor.f2\
    -fill x
  pack configure .xfPacking.frame2.anchor.ne .xfPacking.frame2.anchor.e .xfPacking.frame2.anchor.se\
    -in  .xfPacking.frame2.anchor.f3\
    -fill x
  pack configure .xfPacking.frame2.anchor.message5
  pack configure .xfPacking.frame2.anchor.f1 .xfPacking.frame2.anchor.f2 .xfPacking.frame2.anchor.f3\
    -side left

  pack configure .xfPacking.frame2.children.widgets .xfPacking.frame2.children.childs\
    -side left\
    -fill both\
    -expand 1
  pack configure .xfPacking.frame2.side .xfPacking.frame2.fill .xfPacking.frame2.anchor\
    -pady 6
  pack configure .xfPacking.frame2.expand\
    -fill x\
    -pady 6\
    -after .xfPacking.frame2.side
  pack configure .xfPacking.frame2.chldframe\
    -fill x\
    -pady 6
  pack configure .xfPacking.frame2.children\
    -fill both\
    -pady 6\
    -expand 1

  pack configure .xfPacking.frame1 .xfPacking.additional .xfPacking.functions\
    -side bottom\
    -fill both
  pack configure .xfPacking.frame2\
    -fill both\
    -expand 1

  XFEditSetStatus "Calling packing... done."
}

##########
# Procedure: XFPackingGetPacking
# Description: set dialogue widgets to match slave's packing instructions
# Arguments: none
# Returns: none
# Sideeffects: none
##########
proc XFPackingGetPacking {} {
  global xfPack xfPackConfgEdit

  set xfCurSelected [.xfPacking.frame2.children.childs.childs curselection]

  if {$xfCurSelected >= 0} {
    set xfSlave [lindex [.xfPacking.frame2.children.childs.childs get $xfCurSelected] 1]

    # get packing instructions that account for logged edits
    if {[catch {set xfPackConfgEdit($xfSlave)} xfPacking]} {
      set xfPacking {}
    }
    set xfPacking [concat [pack newinfo $xfSlave] $xfPacking] 

    # disable dialogue widgets while setting them
    set xfPack(enablePUP) 0

    while {[set xfKey [lindex $xfPacking 0]]!= ""} {
      set xfValue [lindex $xfPacking 1]
      set xfPacking [lrange $xfPacking 2 end]

      switch -- $xfKey\
      -side {.xfPacking.frame2.side.$xfValue select}\
      -expand {.xfPacking.frame2.expand.expand [if {!$xfValue} {format de}]select}\
      -fill {.xfPacking.frame2.fill.fillx [if {$xfValue=="y" || $xfValue=="none"} {format de}]select
             .xfPacking.frame2.fill.filly [if {$xfValue=="x" || $xfValue=="none"} {format de}]select}\
      -padx {.xfPacking.frame2.chldframe.epad.xscale set $xfValue}\
      -pady {.xfPacking.frame2.chldframe.epad.yscale set $xfValue}\
      -ipadx {.xfPacking.frame2.chldframe.ipad.xscale set $xfValue}\
      -ipady {.xfPacking.frame2.chldframe.ipad.yscale set $xfValue}\
      -anchor {.xfPacking.frame2.anchor.[string tolower $xfValue] select}
    }

    XFMiscFlash $xfSlave

    set xfPack(enablePUP) 1
  }
}

##########
# Procedure: XFPackingMakeMaster
# Description: establish a new master for dialogue
# Arguments: xfW - the window to be the new master
# Returns: none
# Sideeffects: none
##########
proc XFPackingMakeMaster {xfW} {
  global xfPack

  set xfPack(currMaster) $xfW
  wm title .xfPacking "XF packing:[XFMiscPathTail $xfW]"

  XFPackingRememberOrder $xfW
  XFPackingGetOrder
  XFPackingGetPacking
}

##########
# Procedure: XFPackingForgetSlave
# Description: unpack the currently selected widget - action of Forget button
# Arguments: none
# Returns: none
# Sideeffects: none
##########
proc XFPackingForgetSlave {} {
  global xfPack xfConf

  set xfCS [.xfPacking.frame2.children.childs.childs curselection]
  if {$xfCS >= 0} {
    set xfSlave [lindex [.xfPacking.frame2.children.childs.childs get $xfCS] 1]

    .xfPacking.frame2.children.childs.childs delete $xfCS

    # record state of widget for cancel
    XFPackingRememberConfg $xfSlave

    if {$xfConf(applyPacking)} {
      pack forget $xfSlave
    } {
      lappend xfPack(Forget) $xfSlave
    }
  }
}

##########
# Procedure: XFPackingUndoPacking
# Description: undo packing
# Arguments: none
# Returns: none
# Sideeffects: none
##########
proc XFPackingUndoPacking {} {
  global xfPack xfPackOrderOrig xfPackOrderEdit xfPackConfgOrig xfPackConfgEdit

  # restore slave configurations
  catch {
    foreach xfi [array names xfPackConfgOrig] {
      # maybe there should be a catch here too...
      eval $xfPackConfgOrig($xfi)
    }
  }
  # restore packing orders
  catch {
    foreach xfi [array names xfPackOrderOrig] {
      if {$xfPackOrderOrig($xfi) != ""} {
	# maybe there should be a catch here too...
	eval "pack configure $xfPackOrderOrig($xfi) -in $xfi"
      }
    }
  }
  # make a fresh start
  XFPackingClearUndo
}

##########
# Procedure: XFPackingFindWidget
# Description: find index in Widgets listbox matching named widget
# Arguments: xfW - the widget to search for
# Returns: index, or "" if not found
# Sideeffects: none
##########
proc XFPackingFindWidget {xfW} {
  set xfIndex [.xfPacking.frame2.children.widgets.widgets size]
  while {$xfIndex > 0} {
    incr xfIndex -1
    if {$xfW == [lindex [.xfPacking.frame2.children.widgets.widgets get $xfIndex] 1]} {
      return $xfIndex
    }
  }
  return ""
}

##########
# Description: reconfigure the current slave
# Arguments: xfKey - the configuration option to set
#            xfValue - the value to set it to
##########
proc XFPackingSmallUpdate {xfKey xfValue} {
  global xfPack xfConf xfPackConfgEdit

  if {$xfPack(enablePUP)} {
    set xfCounter [.xfPacking.frame2.children.childs.childs curselect]
    set xfSlave [lindex [.xfPacking.frame2.children.childs.childs get $xfCounter] 1]

    # record state of widget for cancel
    XFPackingRememberConfg $xfSlave

    if {$xfConf(applyPacking)} {
      # update widget directly
      pack configure $xfSlave $xfKey $xfValue
    } {
      # log the update
      set xfVar "xfPackConfgEdit($xfSlave)"
      if {[catch {set $xfVar} xfVal]} {
        set xfVal [set $xfVar ""]
      }
      if {[set xfI [lsearch $xfVal $xfKey]] > -1} {
        incr xfI
        set $xfVar [lreplace $xfVal $xfI $xfI $xfValue]
      } {
        lappend $xfVar $xfKey $xfValue
      }
    }
  }
}

##########
# Description: action of Apply button - carry out
#              all logged packing edit instructions
# Arguments: none 
##########
proc XFPackingApply {} {
  global xfPack xfPackOrderEdit

  # do logged slave reconfigures
  catch {
    foreach xfi [array names xfPackConfgEdit] {
      # maybe there should be a catch here too...
      eval "pack configure $xfi $xfPackConfgEdit($xfi)"
    }
    unset xfPackConfgEdit
  }
  # do logged master reorderings
  catch {
    foreach xfi [array names xfPackOrderEdit] {
      # maybe there should be a catch here too...
      eval "pack configure $xfPackOrderEdit($xfi) -in $xfi"
    }
    unset xfPackOrderEdit
  }
  # do logged forgets
  if {$xfPack(Forget) != ""} {
    eval "pack forget $xfPack(Forget)"
    set xfPack(Forget) {}
  }
}

##########
# Description: action of mover scale -
#              change packing order within master
# Arguments: xfI - position to move slave to
##########
proc XFPackingReorder {xfI} {
  global xfPack xfPackOrderEdit xfConf

  set xfMaster $xfPack(currMaster)
  set xfSlaveLB .xfPacking.frame2.children.childs.childs
  set xfCS [$xfSlaveLB curselection]
  if {$xfCS != ""} {
    # rearrange slaves list
    set xfTmp [$xfSlaveLB get $xfCS]
    $xfSlaveLB delete $xfCS
    $xfSlaveLB insert $xfI $xfTmp
    $xfSlaveLB select from $xfI
    $xfSlaveLB select to $xfI
    
    # construct slaves list
    set xfLst {}
    for {set xfJ 0} "\$xfJ < [$xfSlaveLB size]" {incr xfJ} {
      lappend xfLst [lindex [$xfSlaveLB get $xfJ] 1]
    }

    if {$xfConf(applyPacking)} {
      # reorder slaves directly
      eval "pack config $xfLst -in $xfMaster"
    } {
      # log new packing order
      set xfPackOrderEdit($xfMaster) $xfLst
    }
  }
}

##########
# Description: set contents of slaves window
# Arguments: none
##########
proc XFPackingGetOrder {} {
  global xfPack xfPackOrderEdit xfPackOrderOrig

  set xfMaster $xfPack(currMaster)

  # fetch packing order from log or Tk
  if {[catch {set xfPackOrderEdit($xfMaster)} xfSlaves]} {
    # filter out XF windows and logged forgets
    set xfSlaves {}
    foreach xfi [pack slaves $xfMaster] {
      if {![string match xf* [winfo name $xfi]] &&
          [lsearch -exact $xfPack(Forget) $xfi] == -1} {
	lappend xfSlaves $xfi
      }
    }
  }

  # fill listbox
  XFMiscClearList .xfPacking.frame2.children.childs.childs
  foreach xfi $xfSlaves {
    .xfPacking.frame2.children.childs.childs insert end "<[winfo class $xfi]> $xfi"
  }

  if {$xfSlaves != ""} {
    .xfPacking.frame2.children.childs.childs select from 0
    .xfPacking.frame2.children.childs.childs select to 0
    XFPackingGetPacking 
    .xfPacking.frame2.children.childs.mover configure \
      -to [llength $xfSlaves]
  } {
    .xfPacking.frame2.children.childs.mover configure \
      -to 1
  }
}

##########
# Description: erase all undo information
# Arguments: none
##########
proc XFPackingClearUndo {} {
  global xfPack xfPackOrderOrig xfPackOrderEdit xfPackConfgOrig xfPackConfgEdit

  set xfPack(Forget) {}
  catch {unset xfPackConfgOrig}
  catch {unset xfPackConfgEdit}
  catch {unset xfPackOrderEdit}
  catch {unset xfPackOrderOrig}  
}

##########
# Description: action of Enslave button - makes
#              selected widget a slave of current master
# Arguments: none
##########
proc XFPackingRemaster {} {
  global xfPack xfConf

  # make sure we're in the right mode
  if {$xfConf(applyPacking)} {
    set xfCS [.xfPacking.frame2.children.widgets.widgets curselection]
    if {$xfCS >= 0} {
      set xfSlave [lindex [.xfPacking.frame2.children.widgets.widgets get $xfCS] 1]
      set xfMaster $xfPack(currMaster)

      XFPackingRememberConfg $xfSlave
      if {![catch {pack newinfo $xfSlave} xfOldConfg]} {
        if {[lindex $xfOldConfg 0] != "-in"} {
	  error "\"-in\" problem with \[pack newinfo $xfSlave\]"
	}
        XFPackingRememberOrder [lindex $xfOldConfg 1]
      }

      # execute the remastering
      if {![catch {pack configure $xfSlave -in $xfMaster}]} {
	place forget $xfSlave
	XFPackingGetOrder
	XFPackingGetPacking
      }
    }
  }
}
   
##########
# Description: unless we've already done so, record the
#              packing order of master
# Arguments: xfMaster - master to record
##########
proc XFPackingRememberOrder {xfMaster} {
  global xfPackOrderOrig

  if {[catch {set xfPackOrderOrig($xfMaster)}]} {
    set xfPackOrderOrig($xfMaster) [pack slaves $xfMaster]
  } 
}

##########
# Description: unless we've already done so, record the
#              geometry management of slave
# Arguments: xfMaster - master to record
##########
proc XFPackingRememberConfg {xfSlave} {
  global xfPackConfgOrig

  if {[catch {set xfPackConfgOrig($xfSlave)}]} {
    # delete the -in parameter; packing order is preserved per-master.
    # the manual says -in is always first, but i found otherwise
    # in Tk3.3beta3... it seems to be fixed in the official release,
    # but for now, be assertive.
    if {![catch {pack newinfo $xfSlave} xfl]} {
      if {[lindex $xfl 0] == "-in"} {
	set xfl [lrange $xfl 2 end]
      } {
	error "\"-in\" problem in \[pack newinfo $xfSlave\]"
      }
      set xfPackConfgOrig($xfSlave) "pack configure $xfSlave $xfl"
    } {
      set xfPackConfgOrig($xfSlave) "pack forget $xfSlave; place configure $xfSlave [place info $xfSlave]"
    }
  }
}

#proc xfTracer {name index op} {
#  global $name
#  #if {$op == "w" && [string match {*,currMaster} $index]} {
#  #  puts stdout "$name\($index\) == [set $name\($index\)]"
#  #  flush stdout
#  #}
#  puts stdout "$name\($index) == $name($index)"
#}

# eof
