# JStrack:  copyright 1997/2010 by Jim Graham, N5IAL, all rights reserved.
#

# The procedures in this file allow the user to enter data manually,
# and assume that the full NHC data is not available at the time.
#
# Assumptions:
#    * certain minimal data *IS* available, such as position, course,
#      speed, pressure, max winds, and max gusts.
#    * data such as wind radii and forecast positions is *NOT* available.

proc prompt_user {null_ok text} {
   if {$null_ok} {
      puts -nonewline "$text  "
      flush stdout
      set userin [gets stdin]
      if {$userin != ""} { return [string toupper "$userin"] }
      return -1
   } else {
      while {1} {
         puts -nonewline "$text  "
         flush stdout
         set userin [gets stdin]
         if {$userin != ""} { return [string toupper "$userin"] }
      }
   }
}


proc course_menu {} {
   while {1} {
      puts ""
      puts "1) N    (  0.0 deg.)    9) S    (180.0 deg.)"
      puts "2) NNE  ( 22.5 deg.)   10) SSW  (202.5 deg.)"
      puts "3) NE   ( 45.0 deg.)   12) SW   (225.0 deg.)"
      puts "4) ENE  ( 67.5 deg.)   13) WSW  (247.5 deg.)"
      puts "5) E    ( 90.0 deg.)   14) W    (270.0 deg.)"
      puts "6) ESE  (112.5 deg.)   15) WNW  (292.5 deg.)"
      puts "7) SE   (135.0 deg.)   16) NW   (315.0 deg.)"
      puts "8) SSE  (157.5 deg.)   17) NNW  (337.5 deg.)"
      puts ""
      flush stdout

      set choice [gets stdin]
      if {$choice == "1"}  { return   0 }
      if {$choice == "2"}  { return  22.5 }
      if {$choice == "3"}  { return  45 }
      if {$choice == "4"}  { return  67.5 }
      if {$choice == "5"}  { return  90 }
      if {$choice == "6"}  { return 112.5 }
      if {$choice == "7"}  { return 135 }
      if {$choice == "8"}  { return 157.5 }
      if {$choice == "9"}  { return 180 }
      if {$choice == "10"} { return 202.5 }
      if {$choice == "12"} { return 225 }
      if {$choice == "13"} { return 247.5 }
      if {$choice == "14"} { return 270 }
      if {$choice == "15"} { return 292.5 }
      if {$choice == "16"} { return 315 }
      if {$choice == "17"} { return 337.5 }
   }
}


proc timestamp_menu {} {
   set seconds [clock seconds]

   set timezone [clock format $seconds -format %Z]
   if {[regexp ".DT" $timezone] == 1} {
      set etz "EDT" ; set egmt 4 ; set msg "appears"
   } else {
      set etz "EST" ; set egmt 5 ; set msg "does not appear"
   }
   puts "Daylight savings time $msg to be in effect (TZ=$timezone)."
   puts ""
   set ld [clock format $seconds -format %d]
   set localhour [clock format $seconds -format %H]
   set gmtdate [clock format $seconds -format %d -gmt true]
   set gmthour [clock format $seconds -format %H -gmt true]
   set gmtdiff [clock format [clock scan "00:00"] -format %H -gmt true]
   set etzdiff [expr {$gmtdiff - $egmt}]
   set nhcdate [clock format [clock scan "$etzdiff hour"] -format %d]
   set nhchour [clock format [clock scan "$etzdiff hour"] -format %H]

   puts "Based on the current date and time, I'm guessing that the storm data"
   puts -nonewline "is from the [subst $localhour]00 $timezone advisory, or "
   puts "[subst $nhchour]00 $etz, for day $ld ($timezone) of the"
   puts -nonewline "month.  In other words, it appears to be for "
   puts "[subst $gmtdate/$gmthour]00Z."
   puts ""

   set usedef [prompt_user 1 "Is this ok? (CR for yes, anything else for no)"]
   if {$usedef == "-1"} { return "[subst $gmtdate/$gmthour]00Z" }

# If we're still here, the default wasn't ok.

# Let's use some real values to look better/cleaner
   set mont [clock format [clock seconds] -format %b]
   set monn [clock format [clock seconds] -format %m]
   set lh [subst $localhour]00
   set eh [subst $nhchour]00
   set gh [subst $gmthour]00
   set gd $gmtdate
   set ed $nhcdate

   while {1} {
      puts "Ok, I need you to enter the correct date/time for the advisory."
      puts "The format for this is as in the examples below:"
      puts ""
      puts "      $mont $ld $lh $timezone   -OR-   $monn/$ld $lh $timezone"
      puts "      $mont $ed $eh $etz   -OR-   $monn/$ed $eh $etz"
      puts "      $mont $gd $gh UTC   -OR-   $monn/$gd $gh UTC"
      puts "      $mont $gd $gh GMT   -OR-   $monn/$gd $gh GMT"
      puts ""
      puts -nonewline "Date/time:  "
      flush stdout
      set dt [gets stdin]
      if {[catch { set ds [clock scan "$dt"] } err] == 1} {
         puts ""
         puts $err
         puts ""
      } else {
         set ldt [clock format $ds -format %c]
         set gdt [clock format $ds -format %c -gmt true]
         set retval [clock format $ds -format "%d/%H00Z" -gmt true]
         puts ""
         puts "Local:  $ldt"
         puts "UTC:    $gdt     Timestamp:  $retval"
         set ok [prompt_user 1 "Is this ok (CR for yes, anything else for no)"]
         if {$ok == "-1"} { return $retval }
      }
   }

}


proc st_data {{name "noname"}} {
   global advisory_list storms
   if {"$name" == "noname"} {
      set name [prompt_user 1 "What storm (name only)?"]
      if {$name == "-1"} return
   }
   set type [prompt_user 0 \
      "Hurricane (HR), Tropical Storm (TS), or Tropical Depression (TD)?"]

   puts ""
   puts "Timestamps use the format MM/hhmmZ, and must be in UTC (aka GMT)."
   puts "Remember, if UTC is (for example) 6 hours ahead of you"
   puts "(i.e., CST), and it's 2300 local on the 5th of the month,"
   puts "the timestamp would be 06/0500Z, not 05/0500Z."
   puts ""
   puts "Press RETURN for a menu to help convert times."

   set timestamp [prompt_user 1 "Time (e.g., 06/2100Z for 06 Sep 2100 UTC):"]
   if {$timestamp == "-1"} { set timestamp [timestamp_menu] }
   if {[regexp  \
          "^\[0-9]\[0-9]/\[0-9]\[0-9]\[0-9]\[0-9]$" $timestamp] == 1} {
      set timestamp "[subst $timestamp]Z"
   }
   set latt [prompt_user 0 "Latitude (e.g., 21.0 for 21.0N):"]
   set long [prompt_user 0 "Longitude (e.g., 50.0 for 50.0W):"]

   puts ""
   puts "NOTE:  If you don't have the course in degrees, press RETURN"
   puts "       If the storm is stationary, enter XX"
   puts ""
   set course [prompt_user 1 "Course (degrees):"]
   if {$course == "-1"} { set course [course_menu] }

   puts ""
   set course [string toupper $course]
   if {[string compare $course XX] == 0} {
      puts "NOTE:  I need to know whether you will be entering the wind"
      puts "       speeds and eye diameter (if available) in MPH/miles"
      puts "       or KT/nautical miles."
      puts ""
      set units [prompt_user 0 \
         "Units:  Enter MPH for Miles/MPH or KT for NM/KT"]
#        set speed XX
      set speed [prompt_user 0 "Speed (e.g., 20 for 20 $units):"]
   } else {
      puts "NOTE:  I need to know whether you will be entering the"
      puts "       storm's wind speeds and eye diameter (if available)"
      puts "       in MPH/miles or KT/nautical miles."
      puts ""
      set units [prompt_user 0 \
         "Units:  Enter MPH for Miles/MPH or KT for NM/KT"]
      set speed [prompt_user 0 "Speed (e.g., 20 for 20 $units):"]
   }
   set press [prompt_user 0 "Minimum central pressure in MB:"]
   set winds [prompt_user 0 "Maximum sustained winds (in $units):"]
   set gusts [prompt_user 0 "Maximum gusts (in $units):"]

   puts ""
   puts "NOTE:  For the eye diameter and NHC advisory number, press"
   puts "       RETURN if you do not have that information."
   puts ""

   set eye [prompt_user 1 "Eye diameter (in $units):"]
   if {[string compare $eye -1] == 0} { set eye XX }

   set adno [prompt_user 1 "NHC Advisory number"]
   if {[string compare $adno -1] == 0} { set adno "XX" }
   set advisory_list($name$timestamp) $adno

   if {$units == "MPH"} {
      if {$speed != "XX"} { set speed [expr {round($speed / 1.15)}] }
      if {$winds != -1} { set winds [expr {round($winds / 1.15)}] }
      if {$gusts != -1} { set gusts [expr {round($gusts / 1.15)}] }
      if {$eye != "XX"} { set eye [expr {round($eye / 1.15)}] }
   }

   curr $timestamp $type $name $latt $long \
         $course $speed $press $winds $gusts $eye

   set save [prompt_user 1 "Append to $storms/$name.trk ? \[Y/n]"]
   set save [string toupper $save]
   if {[string compare $save "-1"] == 0 || [string compare $save] == 0} {
      set f [open $storms/[string tolower $name].trk a]
      puts -nonewline $f "curr $timestamp $type $name $latt $long "
      puts $f "$course $speed $press $winds $gusts $eye"
      puts $f "set advisory_list($name$timestamp) \"$adno\""
      close $f
   }
}


