#!/usr/bin/wish -f
#====================================================================================
# Design unit  : SEUs Simulation Tool
#
# File name    : SST_gui.tcl
#
# Purpose      : Graphic user Interface for the SEUs Simulation Tool
#
# Authors      : Daniel González Gutiérrez TEC-EDM
#
# Contact      : mailto:microelectronics@estec.esa.int
#                http://www.estec.esa.int/microelectronics
#
# Copyright (C): European Space Agency (ESA) 2004. No part may be reproduced
#                in any form without the prior written permission of ESA.
#
# Disclaimer   : All information is provided "as is", there is no warranty that
#                the information is correct or suitable for any purpose,
#                neither implicit nor explicit. This information does not
#                necessarily reflect the policy of the European Space Agency.
#====================================================================================
#====================================================================================
# Revision control
# 
###Version 1.0	31/10/03 --DGG
#
###Revision 1.1	22/03/04 --DGG
#  -GUI added
#
###Revision 1.2	27/07/04 --DGG
#
###Revision 1.3	25/11/04 --DGG
#====================================================================================

#----------------------------------------------------------------------------
# Main window
#---------------------------------------------------------------------------- 

toplevel .gui
wm title .gui {Single Event Upsets Simulation Tool}
frame .gui.mbar -relief groove -bd 2
frame .gui.interface -width 10c -height 10c -relief groove -bd 2 
pack .gui.mbar -side top -fill both
pack .gui.interface -side top -fill both -expand 1 
pack propagate .gui.interface 0

#------------------------------------
# Menu bar declaration
#------------------------------------
menubutton .gui.mbar.actions -text Actions -menu .gui.mbar.actions.menu
menubutton .gui.mbar.config -text Configuration -menu .gui.mbar.config.menu 
menubutton .gui.mbar.help -text Help -menu .gui.mbar.help.menu
pack .gui.mbar.actions .gui.mbar.config -side left
pack .gui.mbar.help -side right

#------------------------------------
# Menu bar -> Actions    
#------------------------------------
menu .gui.mbar.actions.menu 

# Gather information of the design -> execute SST_startup.tcl
.gui.mbar.actions.menu add command -label "Gather design information" -command {
  set cancel [tk_dialog .d {Gather information about the design} {Please make sure that \
                              the design is already loaded} warning 0 {Continue} {Cancel}] 
  focus .gui.interface
  eval destroy [winfo children .gui.interface]
  if {$cancel == 0} {
    do SST_startup.tcl 
  }
}

# Generate upsets -> execute SST_upset_generator.tcl
.gui.mbar.actions.menu add command -label "Generate upsets" -command { 
  generate_upsets
  if {$cb_m} {.gui.interface.m.cb_m invoke}
  if {$cb_ir} {.gui.interface.i.r.cb_ir invoke}
  .gui.interface.i.n.en_in delete 0 end
  .gui.interface.i.f.en_if delete 0 end
  if {$cb_nnf} {.gui.interface.n.nf.cb_nnf invoke}
  .gui.interface.n.n.en_nn delete 0 end
  .gui.interface.n.f.en_nf delete 0 end
  set en_tst 0
  set en_twl 0 
  set tst_u ns
  set twl_u ns
}  

# Run a simulation introducing the upsets -> execute sst.do
.gui.mbar.actions.menu add command -label "Run a simulation introducing the upsets" -command {
  focus .gui.interface
  eval destroy [winfo children .gui.interface]
  echo {Starting simulation...}
  restart -f
  do [file join $control_f_dir sst.do]
}

#------------------------------------
# Menu bar -> Config
#------------------------------------
menu .gui.mbar.config.menu

# Edit SST_config.tcl
.gui.mbar.config.menu add command -label "Edit Configuration File" -command {
  edit [file join "$env(DOPATH)" SST_config.tcl]
}  

#------------------------------------
# Menu bar -> Help
#------------------------------------
menu .gui.mbar.help.menu
.gui.mbar.help.menu add command -label "Help Contents" -command {
  tk_dialog .d {Help Contents} {Please refer to the SST User Manual and Functional Description} warning 0 {OK}  
}  
focus .gui.mbar

#----------------------------------------------------------------------------
# subroutines from here down
#---------------------------------------------------------------------------- 

#---------------------------------------------------------------------------- 
# switch_state
# This procedure is used to disable/enable a frame and all its buttons
# It sets a new state value (if the state option is available) in a particular
# widget and all its children . If there is no state option for a given widget  
# it changes its backfround color. 
#---------------------------------------------------------------------------- 
proc switch_state {w state color} { 
  set w_class [winfo class $w]
  if { ($w_class == "Button") ||
       ($w_class == "Checkbutton") ||
       ($w_class == "Entry") ||
       ($w_class == "Menubutton") } {
    $w configure -state $state
  } elseif { $w_class == "Frame" } {
  
  } else {
    $w configure -foreground $color
  }  
  set w_children [winfo children $w]
  foreach window $w_children {
    switch_state $window $state $color
  }
}  

#---------------------------------------------------------------------------- 
# generate_upsets
# This procedure creates an interactive window in which the user can set
# different values for the options and switches of the script
# SPT_chek_and_upset.pl and run it.
#---------------------------------------------------------------------------- 
proc generate_upsets {} {
  focus .gui.interface
  
  #------------------------------------
  # Create main frames 
  #------------------------------------
  eval destroy [winfo children .gui.interface]
  frame .gui.interface.m -relief groove -bd 2 
  frame .gui.interface.i -relief groove -bd 2 
  frame .gui.interface.n -relief groove -bd 2 
  frame .gui.interface.t -relief groove -bd 2  
  frame .gui.interface.bottom
  
  pack .gui.interface.m -fill x -side top 
  pack .gui.interface.bottom -fill x -side bottom 
  pack .gui.interface.i .gui.interface.n .gui.interface.t -side top -fill both -expand 1
  pack propagate .gui.interface.i 0
  pack propagate .gui.interface.n 0 
  pack propagate .gui.interface.t 0
  
  #------------------------------------
  # Add widgets to the 'Manual' frame   
  #------------------------------------
  label .gui.interface.m.lb_m -text {Manual Option} 
  checkbutton .gui.interface.m.cb_m -text {Set manual option} -anchor w -command {
    if {$cb_m == 1} {
      switch_state .gui.interface.i disable grey40
      switch_state .gui.interface.n disable grey40
      switch_state .gui.interface.t disable grey40
    } else {
      switch_state .gui.interface.i normal black
      switch_state .gui.interface.n normal black
      switch_state .gui.interface.t normal black
    }
  }  
  pack .gui.interface.m.lb_m -anchor w
  pack .gui.interface.m.cb_m -anchor w 
  
  #------------------------------------
  # Add widgets to the 'Instances' frame     
  #------------------------------------  
  label .gui.interface.i.lb_i -text {Instances Option} 
  pack .gui.interface.i.lb_i -anchor w 
  
  frame .gui.interface.i.r 
  frame .gui.interface.i.n   
  frame .gui.interface.i.f   
  pack .gui.interface.i.r .gui.interface.i.n .gui.interface.i.f -side top -fill both -expand 1  
  
  checkbutton .gui.interface.i.r.cb_ir -text {Read all_instances.dat} -anchor e -command {
    if {$cb_ir == 1} {
      switch_state .gui.interface.i.n disable grey40
      switch_state .gui.interface.i.f disable grey40
    } else {
      switch_state .gui.interface.i.n normal black
      switch_state .gui.interface.i.f normal black
    }
  }    
  pack .gui.interface.i.r.cb_ir -anchor w 
  
  label .gui.interface.i.n.lb_in -text {Number:} -width 10 
  entry .gui.interface.i.n.en_in -width 4  -textvariable en_in
  pack .gui.interface.i.n.lb_in .gui.interface.i.n.en_in -side left -anchor w 
  
  label .gui.interface.i.f.lb_if -text {Filter pattern:} -width 10 
  entry .gui.interface.i.f.en_if -textvariable en_if
  pack  .gui.interface.i.f.lb_if .gui.interface.i.f.en_if -side left -anchor w 
  
  #------------------------------------
  # Add widgets to the 'Number' frame
  #------------------------------------
  label .gui.interface.n.lb_n -text {Number Option}
  pack .gui.interface.n.lb_n -anchor w 
  
  frame .gui.interface.n.nf 
  frame .gui.interface.n.n   
  frame .gui.interface.n.f   
  pack .gui.interface.n.nf .gui.interface.n.n .gui.interface.n.f -side top -fill both -expand 1  
  
  checkbutton .gui.interface.n.nf.cb_nnf -text {Not fixed switch} -anchor e -command {
    if {$cb_nnf == 1} {
      switch_state .gui.interface.n.n disable grey40
      switch_state .gui.interface.n.f disable grey40
    } else {
      switch_state .gui.interface.n.n normal black
      switch_state .gui.interface.n.f normal black
    }
  }
  
  pack .gui.interface.n.nf.cb_nnf -anchor w  
  
  label .gui.interface.n.n.lb_nn -text {Number:} -width 10
  entry .gui.interface.n.n.en_nn -width 4  -textvariable en_nn
  pack .gui.interface.n.n.lb_nn .gui.interface.n.n.en_nn -side left -anchor w 
  
  label .gui.interface.n.f.lb_nf -text {Filter pattern:} -width 10
  entry .gui.interface.n.f.en_nf -textvariable en_nf
  pack  .gui.interface.n.f.lb_nf .gui.interface.n.f.en_nf -side left -anchor w   

  #------------------------------------
  # Add widgets to the 'Time' frame
  #------------------------------------
  label .gui.interface.t.lb_t -text {Time Option}
  pack .gui.interface.t.lb_t -anchor w 
  
  frame .gui.interface.t.st
  frame .gui.interface.t.wl
  pack .gui.interface.t.st .gui.interface.t.wl -side top -fill both -expand 1
  
  label .gui.interface.t.st.lb_tst -text {Start time:} -width 13
  entry .gui.interface.t.st.en_tst -width 4 -textvariable en_tst
  pack .gui.interface.t.st.lb_tst .gui.interface.t.st.en_tst -side left -anchor w
  
  label .gui.interface.t.st.lb_tst_u -text {Time Unit} -width 10
  tk_optionMenu .gui.interface.t.st.om_tst_u tst_u fs ps ns us ms s
  .gui.interface.t.st.om_tst_u configure -indicatoron 0 -relief sunken -activebackground white -bd 2 -pady 1  
  pack .gui.interface.t.st.lb_tst_u .gui.interface.t.st.om_tst_u -side left -anchor w -ipadx 2
  
  label .gui.interface.t.wl.lb_twl -text {Window length:} -width 13
  entry .gui.interface.t.wl.en_twl -width 4 -textvariable en_twl
  pack .gui.interface.t.wl.lb_twl .gui.interface.t.wl.en_twl -side left -anchor w
  
  label .gui.interface.t.wl.lb_twl_u -text {Window unit:} -width 10
  tk_optionMenu .gui.interface.t.wl.om_twl_u twl_u fs ps ns us ms s
  .gui.interface.t.wl.om_twl_u configure -indicatoron 0 -relief sunken -activebackground white -bd 2 -pady 1
  pack .gui.interface.t.wl.lb_twl_u .gui.interface.t.wl.om_twl_u -side left -anchor w -ipadx 2
    
  #------------------------------------
  # Add widgets to the 'Bottom' frame 
  #------------------------------------
  
  # 'Continue' button
  # When this button is pressed, the information of the "Generate Upsets" 
  # window is gathered. That information will be passed to the script SPT_check_and_upset
  
  button .gui.interface.bottom.bt_cont -text Continue -command {
    set i_option ""
    set n_option ""
    set t_option ""    
    # Gather information of the 'Manual' frame 
    if {$cb_m == 1} {
      set command_line {-m}
    } else {
      # Gather information of the 'Instances' frame 
      if { ($cb_ir) || ($en_if != "") || ($en_in != "") } {
        # Read switch
        if {$cb_ir} {
          set i_option {-ir}
        # Filter switch
        } elseif {$en_if != ""} {
          if {$en_in != ""} {
            set i_option "-if $en_in $en_if"
          } else {set i_option "-if $en_if"}
        # Number switch
        } else { set i_option "-i $en_in" }
      }
      # Gather information of the 'Number' frame  
      if { ($cb_nnf) || ($en_nf != "") || ($en_nn != "")  } {
        # Not fixed switch
        if {$cb_nnf} {
          set n_option {-nn}
        # Filter switch
        } elseif {$en_nf != ""} {
          if {$en_nn != ""} {
            set n_option "-nf $en_nn $en_nf"
          } else {set n_option "-nf $en_nf"}
        } else {set n_option "-n $en_nn"} 
      }
      # Gather information of the 'Time' frame 
      set t_option "-t $en_tst $tst_u $en_twl $twl_u"
      set command_line [concat $i_option $n_option $t_option]
    }  
    puts stdout [exec perl -S SST_upset_generator.pl $command_line]
  }
  # 'Reset'button
  button .gui.interface.bottom.bt_reset -text Reset -command {
   .gui.mbar.actions.menu invoke "Generate upsets"
  }  
  pack .gui.interface.bottom.bt_cont .gui.interface.bottom.bt_reset -side left -expand 1 -padx 3m -pady 1m -ipadx 2m 
}  