#!/usr/bin/wish -f
#
# urusaiclient.tcl
#
# Partially based on
#   http://wiki.tcl.tk/10968
#   http://wiki.tcl.tk/16733
#
# Author: Dario Rodriguez dario@softhome.net
#

package require udp
package require sha1

set host "192.168.1.249"
set port 20245
set from htpc
#set to yurie
set to otro
set myport 20246
set curserial 1

labelframe .top -text "Conversation"
labelframe .bottom -text "Message"

text .t -wrap word -yscrollcommand {.s set} -state disabled
scrollbar .s -command {.t yview}
entry .e -textvariable e

grid .top -sticky nsew
grid .bottom -sticky nsew
grid row . 0 -weight 1
grid column . 0 -weight 1
pack .s .t -in .top -side right -fill both
pack configure .t -expand 1
pack .e -in .bottom -fill both -expand 1

focus .e
update
bind .e <Return> {newmessage $e; set e {};break}

proc appendline { from line } {
        .t conf -state normal
        .t insert end "$from: $line\n"
        .t conf -state disabled
        .t yview end
}

# AI
proc newmessage { line } {
        global from to
        appendline "Me" $line
        sendmessage [genserial] $from $to message $line
}

# Network code
proc recvmessage {} {
        global sock from
        set data [read $sock]
        binary scan $data H* hex
        puts $hex
        set pos 1
        set num ""
        set mystr ""
        set elems [list]
        foreach c [split $hex ""] {
                set num "$num$c"
                set pos [expr 1-$pos]
                if { $pos == 1 } {
                        if { [string compare $num "00"]==0 } {
                                lappend elems $mystr
                                set mystr ""
                        } else {
                                set mystr "$mystr[binary format H* $num]"
                        }
                        set num ""
                }
        }
        set serial [lindex $elems 0]
        set msgfrom [lindex $elems 1]
        set msgto [lindex $elems 2]
        set cmd [lindex $elems 3]
        set contents [lindex $elems 4]
        appendline "server" "$serial|$msgfrom|$msgto|$cmd|$contents"
        if { [string compare $cmd "message"]==0 } {
                sendmessage $serial $from $msgfrom "receipt" ""
        }
}

proc sendmessage { serial from to cmd contents } {
        global sock host port
        set msg [format "%s\0%s\0%s\0%s\0%s\0" $serial $from $to $cmd $contents]
        udp_conf $sock $host $port
        puts -nonewline $sock $msg
}

proc genserial { } {
        global curserial from to
        incr curserial
        return [string range [::sha1::sha1 -hex -- "[clock seconds]|[set from]|[set to]|[set curserial]"] 0 8]

}


if { [llength $argv]>=3 } {
        set from [lindex $argv 0]
        set myport [lindex $argv 1]
        set to [lindex $argv 2]
}

wm title . "urusai/tcl - $from"
set sock [udp_open]
udp_conf $sock $host $myport
fconfigure $sock -buffering none -translation binary
fileevent $sock readable recvmessage

sendmessage [genserial] $from "" ping ""