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

proc newtrk {nhcts ts tp nm lat lng crs spd prs wnd gst eye {pe ""}} {
   global newtrk_used newtrk_list newtrk_data

   set newtrk_used 1
   lappend newtrk_list $nhcts
   set newtrk_data($nhcts) \
      [list $ts $tp $nm $lat $lng $crs $spd $prs $wnd $gst $eye $pe]
}


proc newtrk_curr {} {
   global newtrk_used newtrk_list newtrk_data advisory_list
   if {$newtrk_used == 0} { return }

   set tlist [lsort $newtrk_list]
   foreach idx $tlist {
#     set adv XX
#     catch { set adv $advisory_list($c$a) }
      foreach {a b c d e f g h i j k l} $newtrk_data($idx) { break }
      curr $a $b $c $d $e $f $g $h $i $j $k $l
#     set $advisory_list($c$a) $adv
   }
   set newtrk_used 0
   set newtrk_list [list]
   unset newtrk_data
}


proc test_st_data {{name ""}} {
   global st_times st_names

   if {$st_names == ""} {
         puts "No storm information is loaded"
         return -1
   } elseif {$name != "" && [array get st_times $name] == ""} {
         puts "Data for $name is not loaded."
         return -1
   }
   return 0
}


# Returns a single digit indicating the category rating of a hurricane
# (based only on the wind speeds).

proc st_cat {winds} {
   if {[string compare $winds "XX"] == 0} { return "" }
   set wnds [expr {round($winds * 1.15)}]
   if {$wnds > 155}  { return 5 }
   if {$wnds >= 131} { return 4 }
   if {$wnds >= 111} { return 3 }
   if {$wnds >= 96}  { return 2 }
   return 1
}


# Reads the forecast data from the file and puts it in variables

proc fc {name timestamp fc_ts fc_latt fc_long fc_winds fc_gusts {xt ""}} {
   global forecasts fc_tm_idx

   set name [string toupper $name]
   set timestamp [string toupper $timestamp]
   set fc_ts [string toupper $fc_ts]

   set idx "$name $timestamp $fc_ts"
   set forecasts($idx) [list $fc_latt $fc_long $fc_winds $fc_gusts]
   set forecasts($idx,xt) 0
   if {$xt == "EXTRATROPICAL"}     { set forecasts($idx,xt) 1
   } elseif {$xt == "SUBTROPICAL"} { set forecasts($idx,xt) 2
   } elseif {$xt == "REMLOW"}      { set forecasts($idx,xt) 3
   }

   if {[array get fc_tm_idx $name$timestamp] == ""} {
      set fc_tm_idx($name$timestamp) "$fc_ts"
   } elseif {[lsearch $fc_tm_idx($name$timestamp) $fc_ts] == -1} {
      set fc_tm_idx($name$timestamp) "$fc_tm_idx($name$timestamp) $fc_ts"
   }
}


# Handle position estimates---pass data to curr with 'XX' for empty fields

proc pos_est {timestamp type name latt long} {
   global advisory_list
   curr $timestamp $type $name $latt $long XX XX XX XX XX XX PE
   set advisory_list($name$timestamp) "PE"
} 


# Reads the position data from the file and puts it in variables

proc curr {ts type name latt long course speed press winds gusts eye {pe ""}} {
   global lastx lasty plot_all stinfo advisory_list
   global st_names st_times current_storm_name
   global full_update last_full_update ok_for_full_test new_pos_est

# puts "debug:  curr $ts $type $name $latt $long $course $speed $press $winds $gusts $eye $pe"

   set timestamp $ts
   # set the advisory_list to unknown---override later if known
   set advtmp XX
   catch { set advtmp $advisory_list($name$timestamp) }
   set advisory_list($name$timestamp) $advtmp

   if {[info exists last_full_update]} {
      if {[string compare $timestamp $last_full_update] == 0} {
         set ok_for_full_test 1
      } elseif {$ok_for_full_test} {
         if {[string compare $pe "PE"]} { set full_update 1
         } else { set new_pos_est 1 }
      }
   }

   if {[lsearch $st_names $name] == -1} {
      set st_times($name) "$timestamp"
      lappend st_names "$name"
   } elseif {[lsearch $st_times($name) $timestamp] == -1} {
      set st_times($name) "$st_times($name) $timestamp"
   }

   set current_storm_name $name

   if {$type == "HR"} {
      set cat [st_cat $winds]
      set category "  CATEGORY $cat"
   } else {
      set cat 0
      set category ""
   }

   curr_plot $timestamp $type $name $latt $long $course \
             $speed $press $winds $gusts $cat

   set stinfo($name$timestamp) [list $type $name $timestamp $latt \
      $long $course $speed $press $winds $gusts $eye]
}


# Reads the wind radii from the file and puts it in variables

proc radii {timestamp name winds ne se sw nw} {
   global stradii

   set stradii($name$timestamp$winds) "$winds $ne $se $sw $nw"
}


# Reads the 12' seas radii from the file and puts it in variables

proc twlv_ft_seas {timestamp name ne se sw nw} {
   global stradii_seas

   set stradii_seas($name${timestamp}12) "12 $ne $se $sw $nw"
}


# Reads the forecast wind radii from the file and puts it in variables

proc fc_radii {ts fc_ts name winds ne se sw nw} {
   global fc_stradii

   set fc_stradii($name$ts$fc_ts$winds) "$winds $ne $se $sw $nw"
}

# Converts the wind radii numbers to a number to add/subtract from the
# storm center's latt/long.

proc convert_radii {nm} {
   return [expr {sqrt(($nm * $nm) / 2) / 60}]
}


# Does the actual work for st_info.

proc puts_stinfo {data {cmd "puts"}} {
   global units advisory_list

foreach {type name timestamp latt long course speed press winds gusts eye} \
   $data { break }

   if {[string compare $winds "XX"] == 0} {
      puts_stinfo_pos_est $type $name $timestamp $latt $long $cmd
      return
   }
   if {$type == "HR"} {
      set category "  CATEGORY [st_cat $winds]"
   } else {
      set category ""
      if {$type == "ET"} { set type "Extratropical storm" }
      if {$type == "ST"} { set type "Subtropical storm" }
      if {$type == "RL"} { set type "Remnant Low" }
   }

   if {$units == "KT"} {
      set eye_units "NM"
   } else {
      set eye_units "Miles"
      if {[string compare $course XX]} { set speed [expr {$speed * 1.15}] }
      set winds [expr {$winds * 1.15}]
      if {[string compare $gusts XX]} { set gusts [expr {$gusts * 1.15}] }
      if {[string compare $eye XX]} { set eye [expr {$eye * 1.15}] }
   }

   set advtxt ""
   catch { set advtext "  (Advisory $advisory_list($name$timestamp))" }
   $cmd "$type $name at $timestamp:$category$advtext"
   $cmd "Location:  $latt N $long W"
   if {[string compare $course XX] == 0} {
      $cmd "Movement:  stationary (or no data available)"
   } else {
      $cmd "Movement:  $course at $speed $units"
   }
   $cmd "Estimated minimum central pressure:  $press"
   if {[string compare $gusts XX]} {
      $cmd "Max. winds:  $winds $units, with gusts to $gusts $units"
   } else {
      $cmd "Max. winds:  $winds $units"
   }
   if {[string compare $eye "XX"]} {
      $cmd "Eye diameter:  $eye $eye_units"
   } else {
      $cmd "Eye diameter:  (not available)"
   }
   $cmd ""
}


# Does the actual work for st_info WHEN DEALING WITH A POSITION ESTIMATE.

proc puts_stinfo_pos_est {type name timestamp latt long cmd} {
   $cmd "Position Estimate:"
   $cmd "$type $name at $timestamp"
   $cmd "Location:  $latt N $long W"
   $cmd ""
}


# Does the actual work for fc_index

proc display_indexes {name} {
   global st_times fc_tm_idx

   set name [string toupper $name]

   foreach timestamp $st_times($name) {
      puts -nonewline "$name $timestamp:"
      foreach fc_ts $fc_tm_idx($name$timestamp) {
      puts -nonewline "  $fc_ts"
      }
   puts ""
   }
}


# Does the actual work for fc_info

proc plot_fc_info {name ts fc_ts latt long winds gusts xt {cmd "puts"}} {
   global units

   set name [string toupper $name]
   set ts [string toupper $ts]
   set fc_ts [string toupper $fc_ts]

   if {$units == "MPH"} {
      set winds [expr {$winds * 1.15}]
      set gusts [expr {$gusts * 1.15}]
   }
   $cmd "$name:  $ts"
   $cmd "FORECAST VALID $fc_ts $latt N  $long W"
   $cmd "MAX WIND  $winds $units...GUSTS  $gusts $units"
   if {$xt == 1} { $cmd "EXTRATROPICAL"
   } elseif {$xt == 2} { $cmd "SUBTROPICAL"
   }
   $cmd ""
}


