#!/usr/local/bin/perl
#
#
# copyright July 23, 1999, Bill Walker W5GFE, bw@cs.ecok.edu
# This software is available under the terms of the GNU Public License
############################################
require 5.002;
use Tk;
use strict;
############################################

## the expected RP card is:
##  RP  0  180    1 1001  -90.0  0.0  1.0  0.0  10000.0 0.00E+00



# Initialze Tk 
my $MW = MainWindow->new();


# set up the big frames

my $topframe = $MW->Frame()->pack();
my $middleframe= $MW->Frame()->pack();
my $bottomframe = $MW->Frame()->pack();



my $controlframe = $topframe->Frame() ->pack(-side=>'left');

my $arrlframe = $middleframe->Frame()->pack(-side=>'left');
my $polarframe = $middleframe->Frame()->pack(-side=>'left');

my $cartesianframe = $bottomframe->Frame()->pack(-side=>'left');
my $summaryframe = $bottomframe->Frame()->pack(-side=>'left');


my $controlframelabel = $controlframe->Label(-text=>"Elevation Plots")->pack();


# Create 'quit' button 
my $quitter = $controlframe->Button(-text => 'Quit',
                        -command => sub 
                          {
                           $MW->destroy;
                          })->pack(-side=>'left');



my $arrlframelabel = $arrlframe->Label(-text=>"ARRL Plot")->pack();
my $polarlabel=$polarframe->Label(-text=>"Polar Plot")->pack();
my $cartesianlabel=$cartesianframe->Label(-text=>"Cartesian Plot")->pack();
my $summarylabel=$summaryframe->Label(-text=>"Fact Box")->pack();



########### time to create three canvases -- or maybe four!

####### ARRL Graph

my $arrlgraph = $arrlframe->Scrolled(qw/Canvas -relief sunken -borderwidth 2
		       -scrollbars se -background yellow/);

$arrlgraph->pack();


####### Cartesian Graph

my $cartesiangraph = $cartesianframe->Scrolled(qw/Canvas -relief sunken -borderwidth 2
		       -scrollbars se -background yellow/);

$cartesiangraph->pack();


####### Polar Graph

my $polargraph = $polarframe->Scrolled(qw/Canvas -relief sunken -borderwidth 2
		       -scrollbars se -background yellow/);

$polargraph->pack();

####### Summaries Canvas

my $summarygraph = $summaryframe->Scrolled(qw/Canvas -relief sunken -borderwidth 2
		       -scrollbars se -background yellow /);

$summarygraph->pack();

##############################################33

## note:  origins are at top left

## as a point of reference, put a black blob at the origin in each canvas
my $centerx = 200;
my $centery = 200;


################### now we can read the data

my $filename = "fort.2";  #default file name

if (@ARGV) {
  $filename = $ARGV[0];
}

open(INFILE, "<".$filename) || die "cannot open $filename";

my @gain;
my @angle;
my  $linecounter = 0;
my  $maxgain =  -100.0;
my  $mingain =  500.0;
my  $maxangle =  0.0;
my  $maxindex = 0;
my $yes = 0;
my $no = 1;
my $inpattern = $no;

while (my $line = <INFILE> ){
  chomp($line);
  # a line consists of several fields ---
  # the first is elevation
  # the second is azimuth
  # the third and fourth are components
  # the fifth is gain
  # the rest are junk
  
  if ($line =~ m/RADIATION PATTERN/i) {
    $inpattern = $yes;
    # skip 7
    $line=<INFILE>;
    $line=<INFILE>;
    $line=<INFILE>;
    $line=<INFILE>;
    $line=<INFILE>;
    $line=<INFILE>;
    $line=<INFILE>;
    $line=<INFILE>;
    chomp($line);
  }

  # now we are in the PATTERN until we find a blank line

  if (length($line) == 0) {
    $inpattern = $no;
  }

  if ($inpattern == $yes) {
    $line =~ s/[\s,]+/:/g;
    $line =~ s/^[\s:]*//g;

    my (@TheTokens) = split(":",$line);
    
    my    $e0 = $TheTokens[0];
    my    $a0 = $TheTokens[1];
    my    $g0 = $TheTokens[4];
    
#    printf("e0 %f a0 %f g0 %f\n",$e0,$a0,$g0);
    
    
    # if the gain is very small, just set it to about -60
    if ($g0 <=  -60.0) {
      $g0 =  -60.0;
    }
    
    $gain[$linecounter] = $g0;
    
    if ($g0 > $maxgain) {
      $maxangle = $e0;
      $maxgain = $g0;
      $maxindex = $linecounter;
    }
    
    if ($g0 < $mingain){
      $mingain = $g0;
    }
    
    
    #	  angle[linecounter] = (float) ( 180.0 - linecounter);
    $angle[$linecounter] = 180 - $linecounter;
#    printf("linecount %d, angle %f, gain %f\n",$linecounter, $angle[$linecounter],$gain[$linecounter]);
    $linecounter = $linecounter + 1;
  }
  
}
close (INFILE);


###########################################

#printf(" facts:\n");
#printf("maxgain is %f, mingain is %f, maxangle is %f, maxindex is %d, linecounter is %d\n",$maxgain, $mingain, $maxangle, $maxindex, $linecounter);


############################################
my $radians;
my @unitx;
my @unity;

# we need to invent a "unit circle"
    for (my $i = 0; $i <= 180; $i++ ) {
      $radians =  $angle[$i]* 3.14159/180.0;
      $unitx[$i] = cos($radians);
      $unity[$i] = sin($radians);
    }


    my $fa0 =  0.0;
    
    my $scale = $maxgain - $mingain;

#############################################


# We first worry about creating the ARRL Graph


    my @newgain;
    my @xarrl;
    my @yarrl;
    
    for (my $i = 0; $i < $linecounter; $i++) {
      $newgain[$i] = $gain[$i] - $mingain;
      $radians =   $angle[$i]* 3.14159/180.0 ;
      $xarrl[$i] = ($unitx[$i] * exp(0.0443255 * $newgain[$i]))/(exp(0.0443255 * $scale));
      $yarrl[$i] = ($unity[$i] * exp(0.0443255 * $newgain[$i]))/(exp(0.0443255 * $scale));
    }


    my @arrlsteps = (0.0, 3.0, 6.0, 10.0, 20.0, 30.0, 40.0);

   my $arrlcounter = 0;
   my $side = 0;

   $arrlgraph->create('text',
			 400,
			 80,
			 -text=>'Scales -db'
			  );


# draw each circle
    foreach $arrlcounter (@arrlsteps) {
      my $thisstep = ($scale  - $arrlcounter);

      my $oldx = 200;
      my $oldy = 200;
      for (my  $i = 0; $i <= 180; $i++) {
      my  $b0 = int (($unity[$i] * exp(0.0443255 * $thisstep))/exp(0.0443325 * $scale) * 120.0); 
      my $a0 = int (($unitx[$i] * exp(0.0443255 * $thisstep))/exp(0.0443325 * $scale) * 120.0);
	$arrlgraph->create('line',$oldx, $oldy, $a0 + 200,200 -$b0, -width=>2, -fill=>'PaleGreen');

	$oldx = $a0 + 200;
	$oldy = 200 - $b0;
      }


      #label it
      my $TheLabel = $arrlcounter;


      $arrlgraph->create('text',
			 400,
			 $side * 20 + 100,
			 -text=>"-".$TheLabel
			  );
      $side = $side + 1;
	

    }


    # do the radials


    for (my $i = 0; $i <= 180; $i = $i + 15) {
      my $b0 =  int($unity[$i] * 120.0);
      my $a0 = int($unitx[$i] * 120.0);
      $arrlgraph->create('line',$centerx, $centery, $a0 + 200,200 -$b0, -width=>2, -fill=>'PaleGreen');
    }

    # now plot the data


       my $oldx = 200;
       my $oldy = $centery;

    
        for (my  $i = 0; $i <= 180; $i++) {
	  my $b0 = int ($yarrl[$i]   * 120.0);
	  my $a0 = int ($xarrl[$i]   * 120.0);
	  $arrlgraph->create('line',$oldx, $oldy, $a0 + 200,200 - $b0, -width=>2,
			     -fill=>'red');
	          
	  $oldx = $a0 + 200;
	  $oldy = 200 - $b0;
	}

$arrlgraph->configure(-scrollregion => [$arrlgraph->bbox("all")]);


#############################
## Now create the "Linear Polar System



my @polarsteps = (0.0, 10.0, 20.0, 30.0, 40.0);

my $polarcounter = 0;
$side = 0;
   $polargraph->create('text',
			 400,
			 80,
			 -text=>'Scales -db'
			  );


# draw each circle
    foreach $polarcounter (@polarsteps) {
      my $thisstep = ($scale  - $polarcounter);

      my $oldx = 200;
      my $oldy = 200;
      for (my  $i = 0; $i < 180; $i++) {
	my $b0 = int($thisstep * $unity[$i]/$scale * 120.0);
	my $a0 = int ( $thisstep * $unitx[$i]/$scale * 120.0);
	$polargraph->create('line',$oldx, $oldy, $a0 + 200,200 -$b0, -width=>2, -fill=>'PaleGreen');

	$oldx = $a0 + 200;
	$oldy = 200 - $b0;
      }

      #label it
      my $TheLabel = $polarcounter;

      $polargraph->create('text',
			 400,
			 $side * 20 + 100,
			 -text=>"-".$TheLabel
			  );

      $side = $side + 1;
	

    }


    # do the radials


    for (my $i = 0; $i <= 180; $i = $i + 15) {
      my $b0 =  int($unity[$i] * 120.0);
      my $a0 = int($unitx[$i] * 120.0);
      $polargraph->create('line',$centerx, $centery, $a0 + 200,200 -$b0, -width=>2, -fill=>'PaleGreen');
    }

    # now plot the data

       my $oldx =  200;
       my $oldy = $centery;
    
        for (my  $i = 0; $i <= 180; $i++) {
	  my $a0 = int ($newgain[$i]/$scale * $unitx[$i]   * 120.0);
	  my $b0 = int ($newgain[$i]/$scale * $unity[$i]   * 120.0);
	  $polargraph->create('line',$oldx, $oldy, $a0 + 200,200 - $b0, -width=>2,
			     -fill=>'red');

	  $oldx = $a0 + 200;
	  $oldy = 200 - $b0;
	}

$polargraph->configure(-scrollregion => [$polargraph->bbox("all")]);


##################### Cartesian System
############# do the fact box

      my $factxoffset = 100;
      my $factstep = 15;
      my $facty = 20;

sub addfact {
  my $fact = $_[0];
  $summarygraph->create('text',
			$factxoffset,$facty,
			-text=>$fact
		       );
  $facty = $facty + $factstep;
}

addfact("File is " . $filename);
    # add tick marks
    my $offsetx = 200;

    my $fa0 =  0.0;
    for (my  $i = 0; $i <= 180; $i = $i + 15) {
      my $a0 =  int(($i/180.0) * 300.0);
      # vertical line
      $cartesiangraph->create('line',$a0 + $offsetx, 0, $a0 + $offsetx, 210, -fill=>'PaleGreen');
      $cartesiangraph->create('line',$a0 + $offsetx, 0, $a0 + $offsetx, 210, -fill=>'PaleGreen');
      $cartesiangraph->create('line',$a0 + $offsetx, 225,$a0 + $offsetx,215, -fill=>'PaleGreen');
      my $PlotThisAngle = int ( 90 - $angle[$i]);
      $cartesiangraph->create('text',
			      $a0 +$offsetx - 5, 235,
			   -text=>$PlotThisAngle
			  );
    }

    # and horizontal scales
    my $lowerscale = int($mingain - 1.0);
  if ($lowerscale < -60 ) {
    $lowerscale = -60;
    addfact("minimum gain adjusted to -60 DB");
  }
#    my $plotgain = $mingain;
    my $plotgain = $lowerscale;

    while ($plotgain <= $maxgain) {
      my $b0 = 200 - int (($plotgain - $mingain)/($maxgain - $mingain)  * 200.0);
      $cartesiangraph->create('line',$offsetx, $b0, $offsetx + 300, $b0, -fill=>'PaleGreen');
      $cartesiangraph->create('text',$offsetx +350,$b0,-text=>$plotgain);
      $plotgain =  ($plotgain + 6.0);
    }

    # We need a vertical scale and horizontal scale
    $cartesiangraph->create('line',$offsetx,220, $offsetx + 300, 220, -fill=>'PaleGreen');


    # put the data on the graph
    $fa0 =  $offsetx;
    $oldx = $offsetx;
    $oldy = 200 - int (($gain[0] - $mingain)/($maxgain - $mingain) * 200.0);

    for (my  $i = 0; $i < 180; $i++) {
      my $b0 = 200 - int (($gain[$i] - $mingain)/($maxgain - $mingain)  * 200.0);
      $fa0 =  $fa0 +  (600.0/360.0);
      my $a0 = int($fa0);
      $cartesiangraph->create('line',$oldx, $oldy, $a0, $b0, -fill=>'red');
      $oldx = $a0;
      $oldy = $b0;
    }

$cartesiangraph->configure(-scrollregion => [$cartesiangraph->bbox("all")]);

############# do the fact box
      # and add the "facts"
      addfact("Maximum gain is " . $maxgain . " DB");
      addfact("Which occurs at elevation of " . $maxangle);
      addfact("and perhaps at other angles also");
      addfact("(Remember 0 degrees is vertical)");

      # look for -3db beamwidth by starting at maxindex, and
      # lookup up and down for first values that are less than maxgain - 3.0

      my  $up = $maxindex + 1;
      while (($gain[$up] > $maxgain - 3.0) &&  ($up != $maxindex) ){
	$up = ($up + 1) % ($linecounter + 1);
      }

      my  $down = ($maxindex + $linecounter -1) % ($linecounter + 1) ;
      while (($gain[$down] > $maxgain - 3.0) && ($down != $maxindex)) {
	$down = ($down + $linecounter - 1) % ($linecounter + 1);
      }
      my $threedb =   abs($angle[$up]  - $angle[$down]);

     addfact("-3 DB beamwidth is " . $threedb . " degrees");

$summarygraph->configure(-scrollregion => [$summarygraph->bbox("all")]);


# Interact...
MainLoop();




