#==============================================================================
# Contains the implementation of a multi-entry widget for IP addresses.
#
# Copyright (c) 1999-2002  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Public procedures
# =================
#

#------------------------------------------------------------------------------
# mentry::ipAddrMentry
#
# Creates a new mentry widget win that allows to display and edit IP addresses.
# Sets the type attribute of the widget to IPAddr and returns the name of the
# newly created widget.
#------------------------------------------------------------------------------
proc mentry::ipAddrMentry {win args} {
    #
    # Create the widget and set its type to IPAddr
    #
    eval [list mentry $win] $args
    ::$win configure -body {3 . 3 . 3 . 3}
    ::$win attrib type IPAddr

    #
    # Allow only unsigned integers of maximal value 255 in all entry children
    #
    foreach w [::$win entries] {
	wcb::cbappend $w before insert "wcb::checkEntryForUInt 255"
    }

    return $win
}

#------------------------------------------------------------------------------
# mentry::putIPAddr
#
# Outputs the IP address addr to the mentry widget win of type IPAddr.
#------------------------------------------------------------------------------
proc mentry::putIPAddr {addr win} {
    set errorMsg "expected an IP address but got \"$addr\""

    #
    # Check the syntax of addr
    #
    set lst [split $addr .]
    if {[llength $lst] != 4} {
	return -code error $errorMsg
    }

    #
    # Try to convert the four components of addr to decimal
    # strings and check whether they are in the range 0 - 255
    #
    for {set n 0} {$n < 4} {incr n} {
	set val [lindex $lst $n]
	if {[catch {format %d $val} str$n] != 0 || $val < 0 || $val > 255} {
	    return -code error $errorMsg
	}
    }

    checkIfIPAddrMentry $win
    ::$win put 0 $str0 $str1 $str2 $str3
}

#------------------------------------------------------------------------------
# mentry::getIPAddr
#
# Returns the IP address contained in the mentry widget win of type IPAddr.
#------------------------------------------------------------------------------
proc mentry::getIPAddr win {
    checkIfIPAddrMentry $win

    #
    # Scan the contents of the entry children;
    # generate an error if any of them is empty
    #
    for {set n 0} {$n < 4} {incr n} {
	set w [::$win entrypath $n]
	set str [$w get]
	if {[string compare $str ""] == 0} {
	    focus $w
	    return -code error EMPTY
	}
	scan $str %d val$n
    }

    return $val0.$val1.$val2.$val3
}

#
# Private procedure
# =================
#

#------------------------------------------------------------------------------
# mentry::checkIfIPAddrMentry
#
# Generates an error if win is not a mentry widget of type IPAddr.
#------------------------------------------------------------------------------
proc mentry::checkIfIPAddrMentry win {
    if {![winfo exists $win]} {
	return -code error "bad window path name \"$win\""
    }

    if {[string compare [winfo class $win] Mentry] != 0 ||
	[string compare [::$win attrib type] IPAddr] != 0} {
	return -code error \
	       "window \"$win\" is not a mentry widget for IP addresses"
    }
}
