#!/usr/local/bin/perl -w

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



my (@colors) = ( 'green',  'cyan',  
    'PeachPuff3',  'RosyBrown1', 'IndianRed1',
     'PaleVioletRed1', 'MediumOrchid1','pink','blue');

my $colorindex = 0;
my @USECOLOR;


#######################################
########## globals

my $theta = 0;
my $phi = 0;
my $radfactor = 3.1415926/180.0;

my $Xx = 0;
my $Xy = 0;
my $Xz = 0;

my $Yx = 0;
my $Yy = 0;
my $Yz = 0;
my $counter = 0;

my @Translate = (200,200);

my $axislength = 150;
my $maxaspect = $axislength;
###############################3

# initialize the axis arrays
my @AX0 = (0,0,0,0);
my @AX1 = ($axislength,0,-$axislength,0);
my @AY0 = (0,0,0,0);
my @AY1 = (0,$axislength,0,-$axislength);
my @AZ0 = (0,0,0,0);
my @AZ1 = (0,0,0,0);

################################33
my @X0;
my @X1;
my @Y0;
my @Y1;
my @Z0;
my @Z1;
my @RADIUS;

  


################################## subprograms

sub proj {
  my ($x,$y,$z) = @_;
  my $newx;
  my $newy;
  $newx = $Xx * $x + $Xy * $y + $Xz * $z + $Translate[0];
  $newy = $Yx * $x + $Yy * $y + $Yz * $z - $Translate[1];
  # use this to flip the thing
  return ($newx, -$newy);
  
}

sub makematrix {
  my ($theta,$phi) = @_;
  $Xz = 0;
  $Yz = -sin($theta * $radfactor);
  $Xx = -sin($phi * $radfactor);
  $Xy = cos($phi * $radfactor);
  $Yx = cos($theta * $radfactor) * cos($phi * $radfactor);
  $Yy = sin($phi * $radfactor) * cos($theta * $radfactor);
  
}


sub maxmin {
  # returns ($max, $min) of a vector

  my $max = $_[0];
  my $min = $_[0];

  my $i = 0;
  while ($i < @_ ) {
    $max = ($max < $_[$i] ? $_[$i] : $max);
    $min = ($min > $_[$i] ? $_[$i] : $min);
    $i = $i + 1;
  }

  return ($max,$min);
  
}



sub loadantenna {
  my $filename = $_[0];

  my $GW;
  my $GR;
  my $Repeats;
  my $tag;
  my $segments;

  undef @X0;
  undef @X1;
  undef @Y0;
  undef @Y1;
  undef @Z0;
  undef @Z1;
  undef @RADIUS;


  @X0 = (0);
  @X1 = (0);

  @Y0 = (0);
  @Y1 = (0);

  @Z0 = (0);
  @Z1 = (0);
  
  my $line;

  $counter = 0;

  open (FH,"<" . $filename);
  while ($line = <FH> ) {
    chomp($line);
    if ($line =~ /^GW/ ) {
      # next two for somnec input
      $line =~ s/^GW/GW /;
      $line =~ s/,/ /g;
      
      $line =~ s/^[ \t][ \t]*//g;
      $line =~ s/[ \t][ \t]*/|/g;
      ($GW,$tag,$segments,$X0[$counter],$Y0[$counter],$Z0[$counter],
       $X1[$counter],$Y1[$counter],$Z1[$counter],$RADIUS[$counter]) = split('\|',$line);
      $USECOLOR[$counter] = $colors[$counter % (@colors)];
      $counter++;
    }
    if ($line =~ /^GR/ ) { # added July 25, 1999 --- BKW
      # I have to duplicate everything to date
      # next two for somnec input
      $line =~ s/^GR/GR /;
      $line =~ s/,/ /g;
      
      $line =~ s/^[ \t][ \t]*//g;
      $line =~ s/[ \t][ \t]*/|/g;
      ($GR, $tag, $Repeats) = split('\|',$line);
      #printf("repeat stuff to date %d times on a cylinder\n",$Repeats);
      # the Z axis stuff remains the same, but the X and Y coordinates must change
      # there should be a total of $Repeats copies of the structure,
      # not $Repeats more copies

      # use these angle increments
      my $increment = 360.0 / $Repeats * 3.1415926/180.0; # radians
      
      # the structure is in X0,Y0,Z0,Z1,Y1,Z1  [0 .. $counter - 1],
      # Z0 and Z1  and USECOLOR  and RADIUS stay the same
      # step through each of the old points

      my $specialcounter = $counter;
      for (my $newcounter = 0; $newcounter < $counter; $newcounter++) {
	#repeat entire structure at each angle
	my $repeatcounter = 0;

	# here are the initial angles for each of the  endpoints of a segment
	my $theta = 0;
	my $theta1 = 0;
	if ($X0[$newcounter] != 0.0 ) {
	  $theta = atan2($X0[$newcounter],$Y0[$newcounter]);
	}
	if ($X1[$newcounter] != 0.0) {
	  $theta1 = atan2($X1[$newcounter],$Y1[$newcounter]);
	}

	$theta = $theta + $increment;
	$theta1 = $theta1 + $increment;
			 
	while ($repeatcounter < $Repeats) {
	  my $dist0 = sqrt($X0[$newcounter] * $X0[$newcounter] + $Y0[$newcounter] * $Y0[$newcounter]);
	  $X0[$specialcounter] = $dist0 * cos($theta);
	  $Y0[$specialcounter] = $dist0  * sin($theta);
	  $Z0[$specialcounter] = $Z0[$newcounter] ;

	  my $dist1 = sqrt($X1[$newcounter] * $X1[$newcounter] + $Y1[$newcounter] * $Y1[$newcounter]);
	  $X1[$specialcounter] = $dist1 * cos($theta1);;
	  $Y1[$specialcounter] = $dist1  * sin($theta1);
	  $Z1[$specialcounter] = $Z1[$newcounter] ;

	  $RADIUS[$specialcounter] = $RADIUS[$newcounter];
	  $USECOLOR[$specialcounter] = $USECOLOR[$newcounter];
	  $specialcounter++;
	  $repeatcounter++;
	  $theta = $theta + $increment;
	  $theta1 = $theta1 + $increment;
	}
	
      }
	
	
      # fix the $counter
      # there should be $counter + ($Repeats -1) * $counter cells now
      $counter = $specialcounter;
      
    } # of GR
  }
  close(FH);

  


  my ($MAXSCALE,$MINSCALE) = maxmin (maxmin(@X0),maxmin(@Y0),maxmin(@Z0),
				     maxmin(@X1),maxmin(@Y1),maxmin(@Z1));


  my $SCALE;
  if ($MAXSCALE == $MINSCALE) {
    $SCALE = $maxaspect;
  } else {
    $SCALE = $maxaspect/($MAXSCALE - $MINSCALE);
  }

  #scale it
  my $i = 0;
  while ($i < $counter) {
    #scale it and put it on the graphs
    $X0[$i] = $SCALE *$X0[$i];
    $X1[$i] = $SCALE *$X1[$i];
    $Y0[$i] = $SCALE *$Y0[$i];
    $Y1[$i] = $SCALE *$Y1[$i];
    $Z0[$i] = $SCALE *$Z0[$i];
    $Z1[$i] = $SCALE *$Z1[$i];

    $i++;
  }

}

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

################################# frames
my $canvasframe = $MW->Frame(-background=>'green');
$canvasframe->pack(-side=>'top' );

my $sliderframe = $MW->Frame(-background=>'green')->pack(-side=>'top');

my $bottomframe = $MW->Frame(-background=>'green')->pack(-side=>'top');

my $c = $canvasframe->Scrolled('Canvas', -scrollbars=>'se',
			       -background=>'yellow',
			       -width=>3*$axislength,
			       -height=>3*$axislength
			      )->pack(-side=>'left');

my $vertscale = $canvasframe->Scale(-from => -90, -to => 0, -orient=>'vertical',
				     -tickinterval =>20,-length=>2*$axislength,
				    -variable=>\$theta,
				    -command => sub{
#				     printf("theta is %d\n",$theta);
				     makematrix($theta,$phi);
				     drawaxes();
				     drawantenna();
				    })->pack(-side=>'left');


my $filebox = $canvasframe->Scrolled('Listbox',
				      -width => '30',
				     -height=>'10',
				       -setgrid=> 1,
				       -scrollbars=>'e') ->pack (-side=>'left');

$filebox->configure(-background=>'pink');

my $horizscale = $sliderframe->Scale(-from => 0, -to => 360,-orient=>'horizontal',
				     -tickinterval =>20,-length=>4*$axislength,
				     -variable=>\$phi,
				      -command => sub{
	#			     printf("phi is %d\n",$phi);
				     makematrix($theta,$phi);
				     drawaxes();
				     drawantenna();
				    })->pack(-side=>'top');

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



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



#################### a button





$filebox->bind ('<Button-1>', [ sub {
				  loadantenna($filebox->get('active'));
				  drawaxes();
				  drawantenna();
				}]);



## add borders

$c->createOval(0,0,5,5,-tags=>'border');
$c->createLine(4*$axislength,4*$axislength,4*$axislength+5,4*$axislength+5,-tags=>'border');


my $lastx;
my $lasty;

my $x;
my $y;
my $e;



###############
# drawaxes

sub drawaxes {
    $c->delete('axes');
       
    $c->createLine(proj($AX0[0],$AY0[0],$AZ0[0]),proj($AX1[0],$AY1[0],$AZ1[0]),
		   -tags=>'axes',-arrow=>'last',-width=>3);
    $c->createLine(proj($AX0[0],$AY0[0],$AZ0[0]),proj($AX1[2],$AY1[2],$AZ1[2]),
		   -tags=>'axes');
    $c->createLine(proj($AX0[0],$AY0[0],$AZ0[0]),proj($AX1[1],$AY1[1],$AZ1[1]),
		   -tags=>'axes',-arrow=>'last',-width=>3);
    $c->createLine(proj($AX0[0],$AY0[0],$AZ0[0]),proj($AX1[3],$AY1[3],$AZ1[3]),
		   -tags=>'axes')
  }


sub drawantenna {
  $c->delete('lines');
  my $i = 0;
  while ($i < $counter) {
    $c->createLine(proj($X0[$i],$Y0[$i],$Z0[$i]),proj($X1[$i],$Y1[$i],$Z1[$i]),
		  -tags=>'lines',-fill=>$USECOLOR[$i],-width=>2);
    $i = $i + 1;
    
  }
  $c->configure(-scrollregion => [$c->bbox("all")]);
}

###############3

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

## populate the file box

my $line;

open (FILEBOX,"ls |") || die "can't read this directory";

while ($line = <FILEBOX> ) {
  chomp($line);
  $filebox->insert('end',$line);
}

close (FILEBOX);


# Interact...
MainLoop();


