# discover.tcl
# Copyright (c) 2003 Digi International Inc., All Rights Reserved
# 
# This software contains proprietary and confidential information of Digi
# International Inc.  By accepting transfer of this copy, Recipient agrees
# to retain this software in confidence, to prevent disclosure to others,
# and to make no use of this software other than that for which it was
# delivered.  This is an unpublished copyrighted work of Digi International
# Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
# prohibited.
# 
# Restricted Rights Legend
#
# Use, duplication, or disclosure by the Government is subject to
# restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
# Technical Data and Computer Software clause at DFARS 252.227-7031 or
# subparagraphs (c)(1) and (2) of the Commercial Computer Software -
# Restricted Rights at 48 CFR 52.227-19, as applicable.
#
# Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
#
# ***************************************************************************

namespace eval Discover {}

proc Discover::MainGuts {w} {
    variable Tab1st
    set frmMain $w.frmdiscover
    if {![winfo exists $frmMain]} {
        frame $frmMain
        BuildPage $frmMain
        grid $frmMain -row 0 -column 0 -sticky news \
         -padx [expr $::numTitleBoldXPad + $::numBorderWidth] -pady 5
    }
    raise $frmMain
    bind $::Tab1st <<ShiftTab>> {}
    set ::Tab1st $Tab1st
    bind $::Tab1st <<ShiftTab>> {focus $::btnHelp;break}
}

proc Discover::BuildPage {w} {
    set lblHeading $w.lblheading
    ::LabelHeading $lblHeading [mc discover.body.heading [mc discover.notfound]]
    set lblTitle [label $w.lblHeading -text [mc discover.body.title]]
    set frmTable [frame $w.frmtable]
    Table $frmTable
    set lblContinue [label $w.lblcont -text [mc guts.tocontinue] -font fontRegularBold]
    grid $lblHeading -row 0 -column 0 -sticky nw
    grid $lblTitle -row 1 -column 0 -sticky nw
    grid $frmTable -row 2 -column 0 -sticky news
    grid $lblContinue -row 3 -column 0 -sticky sw

    grid rowconfigure $w 2 -weight 1
    grid columnconfigure $w 0 -weight 1
}

proc Discover::Table {w} {
    variable Tab1st
    set frmTbl $w
    set tbl $frmTbl.tbl
    set ::tblWidget $tbl
    set vsb $frmTbl.vsb
    set hsb $frmTbl.hsb
    tablelist::tablelist $tbl \
    -columns [list 0 [mc table.ip] \
          0 [mc table.mac] \
          10 [mc table.host] \
          0 [mc table.product]] \
    -labelcommand tablelist::sortByColumn \
    -xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set] \
    -height 8 -stretch all \
    -background white -resizablecolumns 1 -showarrow 1 \
    -activestyle underline -takefocus 1 \
    -listvariable ::lstDisplayed -labelfont fontRegular -font fontRegular \
    -selectborderwidth 1

    $tbl columnconfigure 0 -sortmode command 
    $tbl columnconfigure 0 -sortcommand Discover::_cmdIPSort
    $tbl columnconfigure 1 -sortmode command -sortcommand Discover::_cmdMACSort
    $tbl columnconfigure 2 -sortmode command -sortcommand Discover::_cmdHostSort
    $tbl columnconfigure 3 -sortmode command -sortcommand Discover::_cmdProdSort
    scrollbar $vsb -orient vertical   -command [list $tbl yview] -takefocus 0
    scrollbar $hsb -orient horizontal -command [list $tbl xview]
    set btnRefresh [button $frmTbl.btnrefresh -text [mc button.refresh] -width $::numButtonWidth \
     -command ::Discover::RunAddp]
    
    set ::tblBody [$tbl bodypath]
    bind $::tblBody <Double-1> [list ::Discover::LaunchWebui $tbl]
    
    grid $tbl -row 0 -column 0 -sticky news
    grid $vsb -row 0 -column 1 -sticky ns
    grid $hsb -row 1 -column 0 -columnspan 2 -sticky ew
    grid $btnRefresh -row 2 -column 0 -columnspan 2 -sticky e -pady 5
    grid columnconfigure $frmTbl 0 -weight 1
    grid rowconfigure $frmTbl 0 -weight 1
    set Tab1st $::tblBody
}

proc Discover::LaunchWebui {tblWidget} {
    set numIndex [$tblWidget curselection]
    set strIP [$tblWidget cellcget $numIndex,0 -text]
    if {![string equal $strIP "0.0.0.0"]} {
        catch [list exec -- $::pathBrowser $strIP &]
    }
}

proc Discover::_cmdIPSort {a b} {
    set lstA [split $a .]
    set lstB [split $b .]
    foreach {A1 A2 A3 A4} $lstA {}
    foreach {B1 B2 B3 B4} $lstB {}
    set A [format "%03s%03s%03s%03s" $A1 $A2 $A3 $A4]
    set B [format "%03s%03s%03s%03s" $B1 $B2 $B3 $B4]
    return [string compare $A $B]
}

proc Discover::_cmdMACSort {a b} {
    return [string compare -nocase $a $b]
}
proc Discover::_cmdHostSort {a b} {
    return [string compare -nocase $a $b]
}
proc Discover::_cmdProdSort {a b} {
    ## This sort will only work for 2 digit port counts (i.e. "PortServer
    ## TS 128" compared to "PortServer TS 64" won't work)
    
    ## Add a leading zero to one digit port counts (i.e. "PortServer TS 
    ## 4" becomes "PortServer TS 04"
    regsub {([^0-9]+)([0-9])([^0-9]|$)} $a {\10\2\3} A
    regsub {([^0-9]+)([0-9])([^0-9]|$)} $b {\10\2\3} B
    return [string compare -nocase $A $B]
}

proc Discover::dispList {lstItems } {
    foreach item $lstItems {
        set strIP     [lindex $item 0]
        set strMAC    [lindex $item 1]
        set strName   [lindex $item 2]
        set strHardware [lindex $item 3]
        
        set ::boolTabFixed 1
        Discover::dispItem $strIP $strMAC $strName $strHardware
    }
}

proc Discover::dispItem {strIP strMAC strName strHardware {imgCell imgConfig}}  {
    lappend ::lstDisplayed [list $strIP $strMAC $strName $strHardware]
    set numRow [expr [llength $::lstDisplayed] - 1]
    if {[string equal $strIP "0.0.0.0"]} {
        $::tblWidget rowconfigure $numRow -fg red
        set imgCell imgNotfound
    }
    $::tblWidget cellconfigure $numRow,0 -image $imgCell
}

proc Discover::RunAddp {} {
    set lstAddp {}
    $::btnNext configure -state disabled
    set ::lstDisplayed {}
    $::tblWidget delete 0 end
    dispItem [mc discover.searching] {} {} {} imgSearch
    . configure -cursor watch
    update
    set ::stateDiscover running
    set lstAddp [exec -- $::pathAddp -Q]
    set lstAddp [split $lstAddp \n]
    set ::lstDisplayed {}
    while {[set index [lsearch $lstAddp MAC*]] >= 0 && $::stateDiscover == "running"} { 
        set lstMAC [split [lindex $lstAddp $index] :]
        set lstIP [split [lindex $lstAddp [expr $index + 1 ]] :]
        set lstName [split [lindex $lstAddp [expr $index + 3 ]] :]
        set lstHardware [split [lindex $lstAddp [expr $index + 6]] :]
        set lstMAC "[string trim [lindex $lstMAC 1]] [lrange $lstMAC 2 end]"
        set strMAC  [join $lstMAC :]
        set strIP [string trim [lindex $lstIP 1]]
        set strName [string trim [lindex $lstName 1]]
        set strHardware [string trim [lindex $lstHardware 1]]
        if {[string equal $strName "(null)"]} {
            set strName ""
        }
        
        
        dispItem $strIP $strMAC $strName $strHardware
        
        ## Remove the first device (7 isn't special, it's just an
        ## index after the current MAC,IP and Hardware fields)
        set lstAddp [lrange $lstAddp [expr $index + 7] end]
    }
    . configure -cursor {} 
    dispItem [mc discover.notfound] {} {} {} imgNotfound
    set numSortCol [$::tblWidget sortcolumn]
    set strSortOrder [$::tblWidget sortorder]
    if {$numSortCol == -1} {
        set numSortCol 0
        set strSortOrder "increasing"
    }
    $::tblWidget sortbycolumn $numSortCol -$strSortOrder
    $::tblWidget selection set 0
    $::btnNext configure -state normal
}

proc Discover::GetSettings {strMAC} {
    return [::MainGetSettings $strMAC ::Discover::arrSettings]
}

proc Discover::InitSettings {} {
    variable arrSettings
    foreach name [array names arrSettings] {
        set arrSettings($name) {}
    }
}
