#
# run a scengen mobility script
proc wlanRunMobilityScript { wlan } {
    global DEFAULT_SCRIPT_MODEL

    set models [netconfFetchSection $wlan "mobmodel"]
    if { [lsearch $models $DEFAULT_SCRIPT_MODEL] < 0 } { return }

    set scriptcfg [getCustomConfigByID $wlan $DEFAULT_SCRIPT_MODEL]
    if { $scriptcfg == "" } { return }

    global script_${wlan}
    # the end time of the script
    set script_${wlan}(max_time) 1
    # script filename 
    set fn [file tail [getKeyValue "file" $scriptcfg 50]]
    set script_${wlan}(filename) $fn
    # resolution for timer firing in milliseconds
    set script_${wlan}(res) [getKeyValue "refresh_ms" $scriptcfg 50]
    # simulated time -- tied to timescale widget
    set script_${wlan}(time) 0
    # used for updating simulated time
    set script_${wlan}(last_time) 0
    # tied to loop checkbox
    set script_${wlan}(loop) [getKeyValue "loop" $scriptcfg 0]
    # tied to play/pause/stop buttons
    set script_${wlan}(state) init
}

#
# show a script dialog box
proc showMobilityScriptPopup { wlan } {
    global script_$wlan CORE_DATA_DIR

    if { ![info exists script_$wlan] } {
	set msg "No script configured for WLAN $wlan."
	tk_messageBox -type ok -icon warning -message $msg
	return
    }

    set w .scriptpopup$wlan
    catch {destroy $w}
    toplevel $w

    wm transient $w .
    wm title $w "[getNodeName $wlan] mobility script"
    wm geometry $w 320x80

    ttk::frame $w.name -borderwidth 0
    ttk::label $w.name.lab -text "Script file:"
    ttk::label $w.name.file -text [set script_${wlan}(filename)]
    pack $w.name.lab $w.name.file -side left -padx 4 -pady 0
    pack $w.name -side top -anchor w

    #
    # scale frame
    #frame $w.fsc -borderwidth 4
    ttk::frame $w.fsc -borderwidth 0
    ttk::scale $w.fsc.timescale -from 0 -to [set script_${wlan}(max_time)] \
    	-orient horizontal -variable script_${wlan}(time)
    ttk::label $w.fsc.lab -textvariable script_${wlan}(time)
    # -state disabled
    pack $w.fsc.timescale -side left -fill x -expand true
    pack $w.fsc.lab -side left 
    pack $w.fsc -side top -anchor w -padx 4 -fill x -expand true
    
    #
    # control frame
    #
    ttk::frame $w.fctl -borderwidth 0
    # play/pause buttons
    foreach b {play pause stop} {
	set fn "$CORE_DATA_DIR/icons/tiny/script_$b.gif"
	set img$b [image create photo -file $fn]
	ttk::radiobutton $w.fctl.$b -image [set img${b}] \
		-variable script_${wlan}(state) -value $b -style Toolbutton
    }
    $w.fctl.play configure -command "controlMobilityScript $wlan start"
    $w.fctl.stop configure -command "controlMobilityScript $wlan stop"
    $w.fctl.pause configure -command "controlMobilityScript $wlan pause"
    # loop checkbox
    ttk::checkbutton $w.fctl.loop -text "loop" -variable script_${wlan}(loop) \
    	-state disabled
    # resolution text entry
    ttk::label $w.fctl.resl -text "resolution:"
    ttk::entry $w.fctl.res -width 4 -textvariable script_${wlan}(res) \
			-state disabled
    ttk::label $w.fctl.resl2 -text "ms"
    pack $w.fctl.play $w.fctl.pause $w.fctl.stop -side left
    pack $w.fctl.loop -side left
    pack $w.fctl.resl $w.fctl.res $w.fctl.resl2 -side left -padx 4 -pady 4
    pack $w.fctl -side bottom -anchor w

    #$w.fctl.res insert 0 [set script_${wlan}(res)]
    
}

#
# this loop fires periodically, started from exec.tcl/setOperMode(exec)
proc mobility_script_loop {} {
    global oper_mode
    set c .c
    set now [clock clicks -milliseconds]
    set refresh_ms 5000

    set wlanlist [findWlanNodes ""]

    # terminates this event loop
    if { $oper_mode != "exec" } {
	# close any script windows, cleanup
	foreach wlan $wlanlist {
	    global script_$wlan
	    if { [info exists script_$wlan] } {
		set script_${wlan}(state) stop
	        catch {destroy .scriptpopup$wlan}
	    }
	}
        return
    }

    foreach wlan $wlanlist {
        # skip wlan nodes that do not have a mobility script
	global script_$wlan
    	if { ![info exists script_$wlan] } {
	    continue
	}
	if { [set script_${wlan}(state)] == "pause" ||
	     [set script_${wlan}(state)] == "stop" } {
            set script_${wlan}(last_time) 0
	    continue
	}
	if { [set script_${wlan}(state)] == "init" } {
	    if { ![info exists .scriptpopup$wlan] } { 
	        showMobilityScriptPopup $wlan
	    }
	    set script_${wlan}(state) stop
	    continue
	}
	if { [set script_${wlan}(state)] == "play" } {
	    if { [set script_${wlan}(last_time)] == 0 } {
		set script_${wlan}(last_time) $now
	    }
	    # dt is time in seconds since last loop update
	    set dt [expr { ($now - [set script_${wlan}(last_time)]) / 1000.0}]
	    set script_${wlan}(last_time) $now
	    set t [set script_${wlan}(time)]
	    set t [expr {$t + $dt}]
	    set script_${wlan}(time) [format "%.03f" $t]
	}
#	if { [set script_${wlan}(res)] < $refresh_ms } { 
#		set refresh_ms [set script_${wlan}(res)] 
#	}
    }
    
    after 90 { mobility_script_loop }
}

# send an Event Message to the mobility script for start/stop/pause
proc controlMobilityScript { wlan cmd } {
    global DEFAULT_SCRIPT_MODEL
    global eventtypes

    set plugin [lindex [getEmulPlugin "*"] 0]
    set sock [pluginConnect $plugin connect true]

    set type $eventtypes(event_$cmd)
    set nodenum [string range $wlan 1 end]
    set name "mobility:$DEFAULT_SCRIPT_MODEL"
    set data ""

    sendEventMessage $sock $type $nodenum $name $data 0
}

# Event Message has been received indicating a mobility script has been
# started/stopped/paused. Set the global state that controls the WLAN script
# dialog, and correct the end (max) time.
proc handleMobilityScriptEvent { node etype edata etime } {
    global script_${node}

    if { ![info exists script_${node}] } {
	set msg "Received Event Message, but no script configured for $node."
	puts "warning: $msg"
	return
    }

    if { $etype == 7 } {
	set script_${node}(state) "play"
    } elseif { $etype == 8 } {
	set script_${node}(state) "stop"
    } elseif { $etype == 9 } {
	set script_${node}(state) "pause"
    }

    set t [getKeyValue "start" $edata [set script_${node}(time)]]
    set max [getKeyValue "end" $edata [set script_${node}(max_time)]]
    # event time etime is currently ignored

    set script_${node}(time) $t
    set script_${node}(max_time) $max

    set w .scriptpopup$node
    if {[winfo exists $w]} { $w.fsc.timescale configure -to $max }
}