
#-------------------------------------------------------------------------------
# Module:     editPivot.tk
# Activation: Dynamically loaded on user request
# Scope:      Perform single pivoting steps on LP objects
# 
# Updated: 2003/03/12 Initial version
#-------------------------------------------------------------------------------




proc CheckPivotRow {} {
    global ThisGraph LpPivotRow StatusInfo DialogPar
    
    set k [$ThisGraph #rows]
    if {$DialogPar("LpRowLabel")==""} {return [expr [CheckLpVar]+$k]}

    for {set i 0} {
        $i<$k && $DialogPar("LpRowLabel")!=[$ThisGraph row $i label]} {incr i} {}
    if {$i==$k} {
        set StatusInfo "row label \"$DialogPar("LpRowLabel")\" not found"
        return -1
    } else {
        return $i
    }
}

proc PivotNow {} {
    global ThisGraph StatusInfo PivotDirection DialogPar
    
    set j [CheckLpVar]
    if {$j>=0} {
        set i [CheckPivotRow]
        if {$i>=0} {
            if {[$ThisGraph tableau coeff $j $i]==0} {
                set StatusInfo "cannot pivot on zero coefficient"
                return
            }

            if {[catch {$ThisGraph pivot $i $j $DialogPar("LpPivotDir")}]} {
                ViewMessenger
                set StatusInfo "pivoting has failed"
            } else {
                PropagateModifications
                set StatusInfo "basis has been updated"
            }
        }
    }
}

proc Pivoting {} {
    global WDPivoting InternalWindowing DialogFrame DefPadX DefPadY \
        ActiveDialog LpPivotVar LpPivotCol PivotDirection ThisGraph DialogPar

    if {$ActiveDialog=="Pivoting"} {return}

    if {$InternalWindowing} {
        set WDPivoting $DialogFrame.pivoting
        if {![winfo exists $WDPivoting]} {
            frame $WDPivoting
        }
        
        RegisterDialog "Pivoting" $WDPivoting Pivoting {}
    } else {
        set WDPivoting .pivoting
        if {![winfo exists $WDPivoting]} {
            toplevel $WDPivoting
            wm title $WDPivoting "Pivoting"
            wm resizable $WDPivoting 0 0
        } else {return}
    }
    
    if {![info exists DialogPar] ||
        ![info exists DialogPar("LpVarIndex")]} {
        set DialogPar("LpVarIndex") 0
    }
    set DialogPar("LpVarLabel") [$ThisGraph variable $DialogPar("LpVarIndex") label]
    set i [$ThisGraph variable $DialogPar("LpVarIndex") index]
    if {$i<[$ThisGraph #rows]} {
        set DialogPar("LpRowLabel") [$ThisGraph row $i label]
    } else {
        set DialogPar("LpRowLabel") ""
    }
    set DialogPar("LpPivotDir") "lower"
    
    frame $WDPivoting.element
    frame $WDPivoting.direction
    pack $WDPivoting.element $WDPivoting.direction \
        -side top -fill x -padx  $DefPadX -pady 5m

    label $WDPivoting.element.label1 -text "Variable Label:" \
        -anchor w
    grid $WDPivoting.element.label1 -in $WDPivoting.element  \
        -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news -padx 1m
    entry $WDPivoting.element.variable -textvariable DialogPar("LpVarLabel") \
        -bg white -width 5
    grid $WDPivoting.element.variable -in $WDPivoting.element \
        -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news -padx 1m
    frame $WDPivoting.element.sep
    grid $WDPivoting.element.sep -in $WDPivoting.element  \
        -row 1 -column 0 -rowspan 1 -columnspan 2 -sticky news -pady 1m
    label $WDPivoting.element.label2 -text "Entering Row:" \
        -anchor w
    grid $WDPivoting.element.label2 -in $WDPivoting.element  \
        -row 2 -column 0 -rowspan 1 -columnspan 1 -sticky news -padx 1m
    entry $WDPivoting.element.entering -textvariable DialogPar("LpRowLabel") \
        -bg white -width 5
    grid $WDPivoting.element.entering -in $WDPivoting.element \
        -row 2 -column 1 -rowspan 1 -columnspan 1 -sticky news -padx 1m
    label $WDPivoting.element.label3 -text "(Leave blank for variable bounds)" \
        -anchor w
    grid $WDPivoting.element.label3 -in $WDPivoting.element  \
        -row 3 -column 0 -rowspan 1 -columnspan 2 -sticky news -padx 1m
    
    radiobutton $WDPivoting.direction.lower \
        -text "Set to Lower Bound" -variable DialogPar("LpPivotDir") \
        -value "lower" -anchor w
    radiobutton $WDPivoting.direction.upper \
        -text "Set to Upper Bound" -variable DialogPar("LpPivotDir") \
        -value "upper" -anchor w
    pack $WDPivoting.direction.lower $WDPivoting.direction.upper \
        -fill x


    frame $WDPivoting.buttons
    button $WDPivoting.buttons.apply -text "Apply" -command PivotNow
    
    button $WDPivoting.buttons.done -text "Done" -command { \
        if {$InternalWindowing} {
            DestroyActiveDialog
        } else {
            destroy $WDPivoting
        }
    }
    
    pack $WDPivoting.buttons.apply $WDPivoting.buttons.done \
        -side left -fill x -padx 3m
     
    pack $WDPivoting.buttons -padx 3m -pady 3m -side bottom

    bind $WDPivoting.element.variable <Return> {
        if {[CheckLpVar]>=0} {focus $WDPivoting.element.entering}
    }
    bind $WDPivoting.element.variable <FocusOut> {
        if {[CheckLpVar]<0} {focus $WDPivoting.element.variable}
    }
    bind $WDPivoting.element.variable <Down> {
        set j [CheckLpVar]
        if {$j<0} {set j $DialogPar("LpVarIndex")}
        if {$j==[$ThisGraph #variables]-1} {set j 0} else {incr j}
        set DialogPar("LpVarLabel") [$ThisGraph variable $j label]
        set DialogPar("LpVarIndex") $j
    }
    bind $WDPivoting.element.variable <Up> {
        set j [CheckLpVar]
        if {$j<0} {set j $DialogPar("LpVarIndex")}
        if {$j==0} {set j [$ThisGraph #variables]}
        incr j -1
        set DialogPar("LpVarLabel") [$ThisGraph variable $j label]
        set DialogPar("LpVarIndex") $j
    }
    bind $WDPivoting.element.entering <Return> {
        if {[CheckPivotRow]>=0} {
            PivotNow
            focus $WDPivoting.element.variable
        }
    }
    bind $WDPivoting.element.entering <FocusOut> {
        if {[CheckLpVar]<0} {focus $WDPivoting.element.entering}
    }
    bind $WDPivoting.element.entering <Down> {
        set j [CheckLpRow]
        if {$j<0} {set j $DialogPar("LpRowIndex")} else {
            if {$j<[$ThisGraph #rows]} {
                if {$j<[$ThisGraph #variables]-1} {incr j} else {
                    set j [expr [CheckLpVar]+[$ThisGraph #rows]]
                }
            } else {set j 0}
        }
        if {$j<[$ThisGraph #rows]} {
            set DialogPar("LpRowLabel") [$ThisGraph row $j label]
        } else {set DialogPar("LpRowLabel") ""}
        set DialogPar("LpRowIndex") $j
    }
    bind $WDPivoting.element.entering <Up> {
        set j [CheckLpRow]
        if {$j<0} {set j $DialogPar("LpRowIndex")} else {
            if {$j<[$ThisGraph #rows]} {
                if {$j>0} {incr j -1} else {
                    set j [expr [CheckLpVar]+[$ThisGraph #rows]]
                }
            } else {set j [expr [$ThisGraph #rows]-1]}
        }
        if {$j<[$ThisGraph #rows]} {
            set DialogPar("LpRowLabel") [$ThisGraph row $j label]
        } else {set DialogPar("LpRowLabel") ""}
        set DialogPar("LpRowIndex") $j
    }

    focus $WDPivoting.element.variable

    if {$InternalWindowing} {
        pack $WDPivoting -anchor nw
        AlignActiveDialog
    }
}

if {![info exists WDPivoting] || ![winfo exists $WDPivoting]} {Pivoting}
