#!/bin/sh
# the next line restarts using wish (on cygwin, use wish84 or the like) \
WISH="wish"; if [ -f ~/.wishname ]; then WISH=`cat ~/.wishname`; fi; exec $WISH "$0" "$@"

#==========================================================================
#  DEMO
#  part of OMNeT++
#==========================================================================

#--------------------------------------------------------------
#  Copyright (C) 1992-2003 Andras Varga
#
#  This file is distributed WITHOUT ANY WARRANTY. See the file
#  `license' for details on this and other legal matters.
#--------------------------------------------------------------


#
# Configuration
#
set wantScrollbar 1
set unixbrowser "netscape"
#set unixbrowser "mozilla"
#set unixbrowser "konqueror"

array set colors {
   color1 #c1b59d
   color2 #e85b13
   color3 #c4c4cc
   color4 #4cb28a
   color5 #d0b48f
   color6 #80a3a7
}

#
# title line:   {"color" "title"}
# program line: {"color" "name" "directory" "unix-command" "windows-command"}
# readme line:  {"color" "name" "readme-file"}
# docu line:    {"color" "name" "readme-file"  "html-file"}
# separator:    {}
#
set i 0
set first ""
foreach line {
   {color1  "About..."         "README"}
   {color2  "Tictoc"           "tictoc"           "./tictoc"    "tictoc.exe"}
   {color3  "NEDDemo"          "neddemo"          "./neddemo"   "neddemo.exe"}
   {color3  "Hist"             "hist"             "./hist"      "hist.exe"}
   {color4  "Fifo"             "fifo"             "./fifo"      "fifo.exe"}
   {color4  "Queues"           "queues"           "./queues"    "queues.exe"}
   {color4  "CQN"              "cqn"              "./cqn"       "cqn.exe"}
   {color4  "Queueing"         "queueing"         "./queueing"  "queueing.exe"}
   {color5  "P-to-P"           "p-to-p"           "./p-to-p"    "p-to-p.exe"}
   {color5  "Aloha"            "aloha"            "./aloha"     "aloha.exe"}
   {color5  "Dyna"             "dyna"             "./dyna"      "dyna.exe"}
   {color5  "TokenRing"        "tokenring"        "./tokenring" "tokenring.exe"}
   {color5  "FDDI"             "fddi"             "./fddi"      "fddi.exe"}
   {color5  "HCube"            "hcube"            "./hcube"     "hcube.exe"}
   {color5  "Routing"          "routing"          "./routing"   "routing.exe"}
   {color5  "Routing/Networks" "routing/networks" "../routing"  "..\\routing.exe"}
   {color6  "Parallel CQN"     "cqn/parsim"       "./runparsim" "runparsim.bat"}
   {color6  "Dyna/RealTime"    "dyna/realtime"   "../dyna"     "..\\dyna.exe"}
   {color6  "Sockets/HTTP"     "sockets"          "./sockets -r 1"  "sockets.exe -r 1"}
   {color6  "Sockets/Telnet"   "sockets"          "./sockets -r 2"  "sockets.exe -r 2"}
} {
   lappend samples $i
   if {[llength $line]==0} {
       set db($i,type) "spacer"
   } elseif {[llength $line]==2} {
       set db($i,type) "heading"
       set db($i,color) $colors([lindex $line 0])
       set db($i,title) [lindex $line 1]
   } elseif {[llength $line]==3} {
       set db($i,type) "readme"
       set db($i,color) $colors([lindex $line 0])
       set db($i,title) [lindex $line 1]
       set db($i,readme) [lindex $line 2]
       if {$first==""} {set first $i}
   } elseif {[llength $line]==4} {
       set db($i,type) "docu"
       set db($i,color) $colors([lindex $line 0])
       set db($i,title) [lindex $line 1]
       set db($i,readme) [lindex $line 2]
       set db($i,docu) [lindex $line 3]
       if {$first==""} {set first $i}
   } elseif {[llength $line]==5} {
       set db($i,type) "program"
       set db($i,color) $colors([lindex $line 0])
       set db($i,title) [lindex $line 1]
       set db($i,dir)   [lindex $line 2]
       set db($i,uprog) [lindex $line 3]
       set db($i,wprog) [lindex $line 4]
       if {$first==""} {set first $i}
   } else {
       tk_messageBox -title {Error} -type ok -icon error -message "Error in table: wrong #items in {$line}"
       exit
   }
   incr i
}


proc createWindow {} {
    global wantScrollbar samples first db fonts colors tcl_platform

    wm focusmodel . passive
    wm minsize . 1 1
    wm overrideredirect . 0
    wm resizable . 1 1
    wm deiconify .
    wm title . "OMNeT++ Demo Simulations"
    wm protocol . WM_DELETE_WINDOW {exit}

    if {$tcl_platform(platform) == "unix"} {
        wm geometry . "690x570"
    } else {
        wm geometry . "650x510"
    }

    #################################
    # Menu bar
    #################################

    menu .menubar
    . config -menu .menubar

    # Create menus
    foreach i {
       {filemenu     -label File -underline 0}
       {helpmenu     -label Help -underline 0}
    } {
       eval .menubar add cascade -menu .menubar.$i
       menu ".menubar.[lindex $i 0]" -tearoff 0
    }

    # File menu
    foreach i {
      {command -command exit -label Exit -underline 1}
    } {
      eval .menubar.filemenu add $i
    }

    # Help menu
    foreach i {
      {command -command helpAbout -label {About OMNeT++} -underline 0}
    } {
      eval .menubar.helpmenu add $i
    }

    #################################
    # Create main display area
    #################################

    frame .sel -bd 2 -relief groove
    frame .main -bd 2 -relief groove
    pack .sel -expand 0 -fill y  -side left -padx 2
    pack .main -expand 1 -fill both  -side right  -padx 2

    frame .main.up
    frame .main.lo
    frame .main.mid
    pack .main.up -expand 0 -fill x  -side top
    pack .main.lo -expand 0 -fill x  -side bottom
    pack .main.mid -expand 1 -fill both -side top

    label .main.up.banner -bg $colors(banner) -relief groove  -font $fonts(bold)
    pack .main.up.banner -fill x -side top

    text .main.mid.text -yscrollcommand ".main.mid.sb set" -width 80 -height 20  -wrap none
    scrollbar .main.mid.sb -command ".main.mid.text yview"
    pack .main.mid.sb -anchor center -expand 0 -fill y  -side right
    pack .main.mid.text -anchor center -expand 1 -fill both -side left

    button .main.lo.start -font $fonts(bold) -bg $colors(startbutton)
    pack .main.lo.start -expand 1 -fill x  -padx 10 -pady 6

    canvas .sel.c -width 200
    pack .sel.c -side left -expand yes -fill both
    if {$wantScrollbar} {
        .sel.c config -yscrollcommand ".sel.s set"
        scrollbar .sel.s -command ".sel.c yview"
        pack .sel.s -side right -fill y
    }
    frame .sel.c.f
    .sel.c create window 0 0 -anchor nw -window .sel.c.f
    set f .sel.c.f

    #label $f.banner -text "Sample simulations:" -bg $colors(banner) -relief groove -font $fonts(bold)
    #pack $f.banner -fill x -side top
    foreach i $samples {
        if {$db($i,type)=="spacer"} {
            frame $f.$i -relief flat
            pack $f.$i -fill x -side top -pady 5
        } elseif {$db($i,type)=="heading"} {
            label $f.$i -text $db($i,title) -bg $colors(banner) -relief groove  -font $fonts(bold)
            pack $f.$i -fill x -side top -padx 5 -pady 5
        } elseif {$db($i,type)=="readme" || $db($i,type)=="docu" || $db($i,type)=="program"} {
            button $f.$i -text $db($i,title) -bd 1 -command "showDemo $i"
            if {$db($i,color)!=""} {$f.$i config -bg $db($i,color)}
            pack $f.$i -fill x -side top -padx 5 -pady 2
        } else {
            tk_messageBox -title {Error} -type ok -icon error -message "internal error: wrong type '$db($i,type)'"
            exit
        }
    }

    update
    .sel.c config -width [winfo width .sel.c.f]
    .sel.c config -scrollregion "0 0 0 [winfo height .sel.c.f]"
    showDemo $first
}

proc helpAbout {} {
    tk_messageBox -title {About} -type ok -icon info -message {Demo simulations for OMNEST/OMNeT++.}
}

proc showDemo {sample} {
   global samples db colors tcl_platform

   set f .sel.c.f
   foreach i $samples {
        if {$db($i,type)=="readme" || $db($i,type)=="docu" || $db($i,type)=="program"} {
            #$f.$i config -relief raised -bg $colors(unselbutton)
            $f.$i config -relief raised
        }
   }

   #$f.$sample config -relief sunken -bg $colors(selbutton)
   $f.$sample config -relief sunken

   if {$db($sample,type)=="readme"} {

       .main.up.banner config -text "$db($sample,title)"
       pack forget .main.lo
       loadFile .main.mid.text $db($sample,readme)

   } elseif {$db($sample,type)=="docu"} {
       .main.up.banner config -text "$db($sample,title)"
       .main.lo.start config -text "Open documentation\n($db($sample,docu))"
       .main.lo.start config -command "openDocu $sample"
       pack forget .main.lo
       pack .main.lo -expand 0 -fill x -side bottom -before .main.mid
       loadFile .main.mid.text $db($sample,readme)

   } elseif {$db($sample,type)=="program"} {

       if {$tcl_platform(platform) == "unix"} {
           set cmd "cd $db($sample,dir); $db($sample,uprog)"
       } else {
           set cmd "cd $db($sample,dir); $db($sample,wprog)"
       }
       .main.up.banner config -text "$db($sample,title) README"
       .main.lo.start config -text "Launch $db($sample,title)\n($cmd)"
       .main.lo.start config -command "runSample $sample"
       pack forget .main.lo
       pack .main.lo -expand 0 -fill x -side bottom -before .main.mid
       loadFile .main.mid.text "$db($sample,dir)/README"

   } else {
       tk_messageBox -title {Error} -type ok -icon error -message "internal error: wrong type '$db($sample,type)'"
       exit
   }
}

proc loadFile {t filename} {
    $t delete 1.0 end

    if [catch {
       # try with ".txt" suffix as well
       if [catch {set f [open $filename r]}] {set f [open "$filename.txt" r]}
       set contents [read $f]
       close $f
    } err] {
       #tk_messageBox -title {OMNeT++ Demo} -type ok -icon error -message "Cannot display README: $err"
       return
    }

    $t insert end $contents
    $t mark set insert 1.0
}

proc runSample {sample} {
    global samples db tcl_platform

   if {$tcl_platform(platform) == "unix"} {
      set prog $db($sample,uprog)
   } else {
      set prog $db($sample,wprog)
      regsub -- {\\} $prog {\\\\} prog
   }

   set pwd [pwd]
   if [catch {
      cd $db($sample,dir)
      #exec $prog &
      #exec [lindex $prog 0] [lindex $prog 1] [lrange $prog 2 end] &
      eval exec $prog &
    } err] {
      tk_messageBox -title {OMNeT++ Demo} -type ok -icon error -message "Error running the simulation program: $err"
   }
   cd $pwd
}

proc openDocu {sample} {
    global samples db tcl_platform unixbrowser

    if [catch {
       if {$tcl_platform(platform) == "windows"} {
           exec cmd.exe /c start $db($sample,docu)
       } else {
           exec $unixbrowser $db($sample,docu) &
       }
     } err] {
       tk_messageBox -title {OMNeT++ Demo} -type ok -icon error -message "Error running the simulation program: $err"
    }
}

#===================================================================
#    GENERIC BINDINGS
#===================================================================

proc generic_bindings {} {
   bind Button <Return> {tkButtonInvoke %W}
}

#===================================================================
#    FONT BINDINGS
#===================================================================

proc font_bindings {} {
   global fonts tcl_platform colors

   set colors(banner)      #e0e0a0
   set colors(unselbutton) #c0c0c0
   set colors(selbutton)   #ffffff
   set colors(startbutton) #e0e0a0

   #
   # fonts() array elements:
   #  normal:  menus, labels etc
   #  bold:    buttons
   #  icon:    toolbar 'icons'
   #  big:     STOP button
   #  msgname: message name during animation
   #  fixed:   text windows and listboxes
   #

   if {$tcl_platform(platform) == "unix"} {
      set fonts(normal) -Adobe-Helvetica-Medium-R-Normal-*-*-120-*-*-*-*-*-*
      set fonts(bold)   -Adobe-Helvetica-Bold-R-Normal-*-*-120-*-*-*-*-*-*
      set fonts(icon)   -Adobe-Times-Bold-I-Normal-*-*-120-*-*-*-*-*-*
      set fonts(big)    -Adobe-Helvetica-Medium-R-Normal-*-*-180-*-*-*-*-*-*
      set fonts(msgname) -Adobe-Helvetica-Medium-R-Normal-*-*-120-*-*-*-*-*-*
      set fonts(fixed)  fixed
      set fonts(balloon) -Adobe-Helvetica-Medium-R-Normal-*-*-120-*-*-*-*-*-*
   } else {
      # Windows, Mac
      set fonts(normal) -Adobe-Helvetica-Medium-R-Normal-*-*-140-*-*-*-*-*-*
      set fonts(bold)   -Adobe-Helvetica-Bold-R-Normal-*-*-140-*-*-*-*-*-*
      set fonts(icon)   -Adobe-Helvetica-Bold-R-Normal-*-*-140-*-*-*-*-*-*
      set fonts(big)    -Adobe-Helvetica-Medium-R-Normal-*-*-180-*-*-*-*-*-*
      set fonts(msgname) -Adobe-Helvetica-Medium-R-Normal-*-*-140-*-*-*-*-*-*
      set fonts(fixed)  FixedSys
      set fonts(balloon) -Adobe-Helvetica-Medium-R-Normal-*-*-140-*-*-*-*-*-*
   }

   if {$tcl_platform(platform) == "unix"} {
       option add *Scrollbar.width  12
       option add *Menubutton.font  $fonts(normal)
       option add *Menu.font        $fonts(normal)
       option add *Label.font       $fonts(normal)
       option add *Entry.font       $fonts(normal)
       option add *Listbox.font     $fonts(fixed)
       option add *Text.font        $fonts(fixed)
       option add *Button.font      $fonts(bold)
   }
}

proc checkVersion {} {

   global tk_version tk_patchLevel

   catch {package require Tk}
   if {$tk_version<8.0} {
      wm deiconify .
      wm title . "Bad news..."
      frame .f
      pack .f -expand 1 -fill both -padx 2 -pady 2
      label .f.l1 -text "Your version of Tcl/Tk is too old!"
      label .f.l2 -text "Tcl/Tk 8.0 or later required."
      button .f.b -text "OK" -command {exit}
      pack .f.l1 .f.l2 -side top -padx 5
      pack .f.b -side top -pady 5
      focus .f.b
      wm protocol . WM_DELETE_WINDOW {exit}
      tkwait variable ok
   }
   if {[string compare $tk_patchLevel "8.0p1"]<0} {
      tk_messageBox -title {Warning} -type ok -icon warning \
        -message {Old Tcl/Tk version. At least 8.0p1 is strongly recommended!}
   }
}

proc checkDirNoSpaces {} {
   set pwd [pwd]
   if {[string first " " $pwd]!=-1} {
      wm withdraw . 
      tk_messageBox -title "OMNeT++/OMNEST Demo" -type ok -icon error \
        -message "The current working directory is \"$pwd\", which contains a space. Please reinstall OMNeT++/OMNEST into a directory whose name doesn't contain space!"
      exit 1
   }
}


set tk_strictMotif 1
cd [file dirname [info script]]
checkVersion
checkDirNoSpaces
generic_bindings
font_bindings
createWindow

