
proc ShowStatistics {} {
    global WDStatistics InternalWindowing DialogFrame

    if {$InternalWindowing} {
        set WDStatistics $DialogFrame.statistics
        if {![winfo exists $WDStatistics]} {
            frame $WDStatistics
        }
        
        RegisterDialog "Problem Statistics" $WDStatistics ShowStatistics {}
    } else {
        set WDStatistics .statistics
        if {![winfo exists $WDStatistics]} {
            toplevel $WDStatistics
            wm title $WDStatistics "Problem Statistics"
            wm resizable $WDStatistics 0 0
        }
    }
    
    UpdateStatistics

    if {$InternalWindowing} {AlignActiveDialog}
}


proc UpdateStatistics {} {
    global ThisGraph goblinMethGeometry WDStatistics InternalWindowing DialogFrame \
        DefPadX DefPadY

    destroy $WDStatistics.frame1
    destroy $WDStatistics.frame2
    destroy $WDStatistics.frame3

    frame $WDStatistics.frame1
    frame $WDStatistics.frame2
    frame $WDStatistics.frame3

    pack $WDStatistics.frame1 $WDStatistics.frame2 $WDStatistics.frame3 \
        -side top -fill x -padx $DefPadX -pady 5m

    if {![winfo exists $WDStatistics.buttons]} {
        frame $WDStatistics.buttons
        button $WDStatistics.buttons.update -text "Update" -command { \
            UpdateStatistics
        }
    
        button $WDStatistics.buttons.done -text "Done" -command { \
            if {$InternalWindowing} {
                DestroyActiveDialog
            } else {
                destroy $WDStatistics
            }
        }
    
        pack $WDStatistics.buttons.update $WDStatistics.buttons.done \
            -side left -fill x -padx 3m

        pack $WDStatistics.buttons -padx 3m -pady 3m -side bottom
    }

    if {$InternalWindowing} {pack $WDStatistics -anchor nw}
    if {[$ThisGraph is mip]} {
        UpdateMIPStatistics
        return
    }


    label $WDStatistics.frame1.label -text "Problem Characteristics:" -anchor w

    if {[$ThisGraph is sparse]} {
        if {[$ThisGraph is undirected]} {
            if {[$ThisGraph is bipartite]} {
                set type "Bipartite Incidence Structure"
            } else {
                set type "Undirected Incidence Structure"
            }
        } else {
            if {[$ThisGraph is directed]} {
                set type "Directed Incidence Structure"
            } else {
                set type "Mixed Incidence Structure"
            }
        }
    } else {
        if {[$ThisGraph is undirected]} {
            if {[$ThisGraph is bipartite]} {
                set type "Complete Bipartite Graph"
            } else {
                set type "Complete Undirected Graph"
            }
        } else {
            set type "Complete Directed Graph"
        }
    }
    
    if {$goblinMethGeometry==0} {
        set geometry "Explicit Length Labels"
    } else {
        set geometry "2-Dimensional"
        if {$goblinMethGeometry==1} {set geometry "$geometry Manhattan Metrics"}
        if {$goblinMethGeometry==2} {set geometry "$geometry Euclidean"}
        if {$goblinMethGeometry==3} {set geometry "$geometry Maximum Metrics"}
    }
    
    label $WDStatistics.frame1.type -text "  $type" -anchor w
    label $WDStatistics.frame1.geometry -text "  $geometry" -anchor w

    pack $WDStatistics.frame1.label $WDStatistics.frame1.type $WDStatistics.frame1.geometry -fill x



    label $WDStatistics.frame2.label -text "Problem Dimensions:" -anchor w

    label $WDStatistics.frame2.nnodes -text "  Number of Nodes: [$ThisGraph #nodes]" -anchor w
    label $WDStatistics.frame2.narcs -text "  Number of Arcs: [$ThisGraph #arcs]" -anchor w

    if {![$ThisGraph constant ucap]} {
        set maxUCap "Maximum Upper Bound: [$ThisGraph max ucap]"
    } else {
        set maxUCap "Constant Upper Bounds: [$ThisGraph max ucap]"
    }
    label $WDStatistics.frame2.maxucap -text "  $maxUCap" -anchor w

    if {![$ThisGraph constant lcap]} {
        set maxLCap "Maximum Lower Bound: [$ThisGraph max lcap]"
    } else {
        set maxLCap "Constant Lower Bounds: [$ThisGraph max lcap]"
    }
    label $WDStatistics.frame2.maxlcap -text "  $maxLCap" -anchor w
    
    pack $WDStatistics.frame2.label $WDStatistics.frame2.nnodes $WDStatistics.frame2.narcs \
        $WDStatistics.frame2.maxucap $WDStatistics.frame2.maxlcap -fill x

    if {![$ThisGraph constant demand]} {
        set nDemands 0
        set nSupplies 0
        for {set v 0} {$v<[$ThisGraph #nodes]} {incr v} {
            if {[$ThisGraph node $v demand]>0} {incr nDemands}
            if {[$ThisGraph node $v demand]<0} {incr nSupplies}
        }
    
        if {$nDemands>0} {
            label $WDStatistics.frame2.ndemands -text "  Demand Nodes: $nDemands" -anchor w
            pack $WDStatistics.frame2.ndemands -fill x
        }
    
        if {$nSupplies>0} {
            label $WDStatistics.frame2.nsupplies -text "  Supply Nodes: $nSupplies" -anchor w
            pack $WDStatistics.frame2.nsupplies -fill x
        }
    
        set maxDemand "Maximum Node Demand: [$ThisGraph max demand]"
    } else {
        set maxDemand "Constant Node Demands: [$ThisGraph max demand]"
    }
    label $WDStatistics.frame2.maxdemand -text "  $maxDemand" -anchor w
    pack $WDStatistics.frame2.maxdemand -fill x

    if {![$ThisGraph constant length]} {
        set nNegative 0
        for {set a 0} {$a<[$ThisGraph #arcs]} {incr a} {
            if {[$ThisGraph arc [expr 2*$a] length]<0} {incr nNegative}
        }
    
        if {$nNegative>0} {
            label $WDStatistics.frame2.nnegative -text "  Negative Length Arcs: $nNegative" -anchor w
            pack $WDStatistics.frame2.nnegative -fill x
        }
    
        set maxLength "Maximum Arc Length: [$ThisGraph max length]"
    } else {
        set maxLength "Constant Arc Lengths: [$ThisGraph max length]"
    }
    label $WDStatistics.frame2.maxlength -text "  $maxLength" -anchor w

    label $WDStatistics.frame2.box -anchor w \
        -text "  Bounding Box: ([$ThisGraph max cx],[$ThisGraph max cy])"
    pack $WDStatistics.frame2.maxlength $WDStatistics.frame2.box -fill x
    

    label $WDStatistics.frame3.label -text "Solutions:" -anchor w

    label $WDStatistics.frame3.card \
        -text "  Subgraph Cardinality: [$ThisGraph cardinality]" -anchor w
    label $WDStatistics.frame3.weight \
        -text "  Subgraph Weight: [$ThisGraph weight]" -anchor w
    label $WDStatistics.frame3.length \
        -text "  Path/Tree Length: [$ThisGraph length]" -anchor w
    pack $WDStatistics.frame3.label $WDStatistics.frame3.card $WDStatistics.frame3.weight \
        $WDStatistics.frame3.length -fill x
}


proc UpdateMIPStatistics {} {
    global ThisGraph goblinMethGeometry WDStatistics InternalWindowing DialogFrame \
        DefPadX DefPadY

    label $WDStatistics.frame1.label -text "Problem Characteristics:" -anchor w

    set nInts 0
    set nFixed 0
    set nEqual 0
    set nPrimalInf 0
    set nDualInf 0
    set isSF true
    set isCF true
    
    for {set i 0} {$i<[$ThisGraph #variables]} {incr i} {
        if {[$ThisGraph variable $i type]=="integer"} {incr nInts}
        if {[$ThisGraph variable $i lrange] ==
            [$ThisGraph variable $i urange]} {incr nFixed}
        if {[$ThisGraph variable $i lrange]!=0 ||
            [$ThisGraph variable $i urange]!="*"} {set isSF false}
        if {[$ThisGraph variable $i lrange]!="*"} {set isCF false}
        
        set j [$ThisGraph variable $i index]
        
        if {[$ThisGraph row $j value lower]<-0.01} {incr nDualInf}
        if {[$ThisGraph row $j value upper]>0.01} {incr nDualInf}
        if {[$ThisGraph row $j value lower]<-0.01 &&
            [$ThisGraph row $j lbound]=="*"} {incr nDualInf}
            
        set j [expr [$ThisGraph #rows]+$i]

        if {[$ThisGraph row $j slack lower]<-0.01 ||
            [$ThisGraph row $j slack upper]<-0.01} {incr nPrimalInf}
    }
    
    for {set i 0} {$i<[$ThisGraph #rows]} {incr i} {
        if {[$ThisGraph row $i lbound] <
            [$ThisGraph row $i ubound]} {set isSF false} else {incr nEqual}
        if {[$ThisGraph row $i lbound]!="*"} {set isCF false}
        
        if {[$ThisGraph row $i slack lower]<-0.01 ||
            [$ThisGraph row $i slack upper]<-0.01} {incr nPrimalInf}
    }

    if {$nInts>0} {
        if {$nInts<[$ThisGraph #variables]} {
            set type "Mixed Integer Linear Program"
        } else {
            set type "Integer Linear Program"
        }
    } else {
        set type "Linear Program"
    }
    
    if {$isSF} {
        set form "Standard Form"
    } else {
        if {$isCF} {
            set form "Canonical Form"
        } else {
            set form "Indefinite Form"
        }
    }
    
    label $WDStatistics.frame1.type -text "  $type" -anchor w
    label $WDStatistics.frame1.form -text "  $form" -anchor w

    pack $WDStatistics.frame1.label $WDStatistics.frame1.type \
        $WDStatistics.frame1.form -fill x



    label $WDStatistics.frame2.label -text "Problem Dimensions:" -anchor w

    label $WDStatistics.frame2.ncols -text "  Number of Variables: [$ThisGraph #variables]" -anchor w
    label $WDStatistics.frame2.nints -text "  Integer Variables: $nInts" -anchor w
    label $WDStatistics.frame2.nfixed -text "  Fixed Variables: $nFixed" -anchor w
    label $WDStatistics.frame2.nrows -text "  Number of Restrictions: [$ThisGraph #rows]" -anchor w
    label $WDStatistics.frame2.nequal -text "  Equality Restrictions: $nEqual" -anchor w
    
    pack $WDStatistics.frame2.label $WDStatistics.frame2.ncols \
        $WDStatistics.frame2.nints $WDStatistics.frame2.nfixed \
        $WDStatistics.frame2.nrows $WDStatistics.frame2.nequal -fill x

    label $WDStatistics.frame3.label -text "Basis Information:" -anchor w

    label $WDStatistics.frame3.primal \
        -text "  Primal Infeasibilities: $nPrimalInf" -anchor w
    label $WDStatistics.frame3.dual \
        -text "  Dual Infeasibilities: $nDualInf" -anchor w
    label $WDStatistics.frame3.objective \
        -text "  Objective Value: [$ThisGraph objective primal]" -anchor w
    if {[set pivot [$ThisGraph pivot row]]=="*"} {
        label $WDStatistics.frame3.pivot \
            -text "  Next Pivot: *" -anchor w
    } else {
        label $WDStatistics.frame3.pivot \
            -text "  Next Pivot: $pivot [$ThisGraph pivot direction], [$ThisGraph pivot column]" -anchor w
    }
    pack $WDStatistics.frame3.label $WDStatistics.frame3.primal \
        $WDStatistics.frame3.dual $WDStatistics.frame3.objective \
        $WDStatistics.frame3.pivot -fill x
}

if {![info exists WDStatistics] || ![winfo exists $WDStatistics]} {ShowStatistics}

