#!//usr/bin/perl -w

use Tk 8.0;
use Getopt::Long;
use IO::Socket;

use strict;

sub mark5_connect ($$);

# Getopt options

my $mark5host = 'localhost';
my $mark5port = '2620';

# Options
my $host = 'localhost';
#my $port = 2630;
my $winsize = 1024; # 1 MB
my $mtu = 1500; # 1 MB
my $ipd = 10; # uSec
my $trackrate = 8;
my $ntrack = 64;
my $mask = '0xffffffff';
my $rate = 32;
my $bandwidth = 16;
my $test = 0;
my $udp = 1;
my $mark5b = 0;

# Appearance
my $bgColour = "#c7adc7adc7ad";   # grey

my $font = '-adobe-courier-medium-r-normal--0-0-75-75-m-0-iso8859-1';
my $boldfont = '-adobe-courier-bold-r-normal--0-0-75-75-m-0-iso8859-1';

#my %lPars=(-bg, $bgColour, -fg, 'black', -font, $font);   # label
my %lPars=(-bg, $bgColour, -fg, 'black');   # label
my %ePars=(-bg, 'white', -fg, 'black', -font, $font);    # entry
my %bPars=(-bg, 'white', -fg, 'black', -font, $font,
	   -padx, 1, -pady, 1, -relief, 'sunken');        # button

GetOptions('host=s'=>\$mark5host, 'port=i'=>\$mark5port, 'mark5b'=>\$mark5b);

my $mark5 = mark5_connect($mark5host, $mark5port);


my $title;
if ($mark5b) {
  $title = 'Mark5b Control';
} else {
  $title = 'Mark5a Control';
}

my $mw = MainWindow->new(-title => 'Mark5 Control',
                         -bg => $bgColour);

my $fa = $mw->Frame(-background=>$bgColour)->pack(-side => 'top', -padx => 5);
my $fb = $mw->Frame(-background=>$bgColour)->pack(-side => 'bottom', -padx => 5,
						  -expand=>1);
my $fc = $mw->Frame(-background=>$bgColour)->pack(-side => 'bottom', -padx => 5);

my $lhost = $fa->Label(-text => 'Correlator Host', %lPars);
my $whost = $fa->Entry(-textvariable => \$host, -width => 15, %ePars);

#my $lport = $fa->Label(-text => 'Correlator Port', %lPars)->pack();
#my $wport = $fa->Entry(-textvariable => \$port, -width => 10, %ePars);

my $lwinsize = $fa->Label(-text => 'Window Size (kB)', %lPars);
my $wwinsize = $fa->Entry(-textvariable => \$winsize, -width => 10, %ePars);

my $lmtu = $fa->Label(-text => 'MTU', %lPars);
my $wmtu = $fa->Entry(-textvariable => \$mtu, -width => 10, %ePars);

my $lipd = $fa->Label(-text => 'Interpacket Delay (us)', %lPars);
my $wipd = $fa->Entry(-textvariable => \$ipd, -width => 10, %ePars);

my $ltrate = $fa->Label(-text => 'Track Rate (Mbps)', %lPars);
my $wtrate = $fa->Entry(-textvariable => \$trackrate, -width => 10, %ePars);

my $ltracks = $fa->Label(-text => 'Number of Tracks', %lPars);
my $wtracks = $fa->Entry(-textvariable => \$ntrack, -width => 10, %ePars);

my $lmask = $fa->Label(-text => 'Bitmask', %lPars);
my $wmask = $fa->Entry(-textvariable => \$mask, -width => 10, %ePars);

my $lrate = $fa->Label(-text => 'Clock rate (MHz)', %lPars);
my $wrate = $fa->Entry(-textvariable => \$rate, -width => 10, %ePars);

my $lbandwidth = $fa->Label(-text => 'Bandwidth (MHz)', %lPars);
my $wbandwidth = $fa->Entry(-textvariable => \$bandwidth, -width => 10, %ePars);

my $wtest = $fa->Checkbutton(-text => 'Test', -variable =>\$test);
my $wudp = $fa->Checkbutton(-text => 'UDP', -variable =>\$udp);

my $row = 0;
Tk::grid($lhost, -row=>$row,   -column=>0, -sticky=>'e');
Tk::grid($whost, -row=>$row++, -column=>1, -sticky=>'w');
#Tk::grid($lport, -row=>$row,   -column=>0, -sticky=>'e');
#Tk::grid($wport, -row=>$row++, -column=>1, -sticky=>'w');
Tk::grid($lwinsize, -row=>$row,   -column=>0, -sticky=>'e');
Tk::grid($wwinsize, -row=>$row++, -column=>1, -sticky=>'w');
Tk::grid($lmtu, -row=>$row,   -column=>0, -sticky=>'e');
Tk::grid($wmtu, -row=>$row++, -column=>1, -sticky=>'w');
Tk::grid($lipd, -row=>$row,   -column=>0, -sticky=>'e');
Tk::grid($wipd, -row=>$row++, -column=>1, -sticky=>'w');
if ($mark5b) {
  Tk::grid($lmask, -row=>$row,   -column=>0, -sticky=>'e');
  Tk::grid($wmask, -row=>$row++, -column=>1, -sticky=>'w');
  Tk::grid($lrate, -row=>$row,   -column=>0, -sticky=>'e');
  Tk::grid($wrate, -row=>$row++, -column=>1, -sticky=>'w');
  Tk::grid($lbandwidth, -row=>$row,   -column=>0, -sticky=>'e');
  Tk::grid($wbandwidth, -row=>$row++, -column=>1, -sticky=>'w');
} else {
  Tk::grid($ltracks, -row=>$row,   -column=>0, -sticky=>'e');
  Tk::grid($wtracks, -row=>$row++, -column=>1, -sticky=>'w');
  Tk::grid($ltrate, -row=>$row,   -column=>0, -sticky=>'e');
  Tk::grid($wtrate, -row=>$row++, -column=>1, -sticky=>'w');
}
Tk::grid($wudp, -row=>$row, -column=>0, -sticky=>'e');
Tk::grid($wtest, -row=>$row++, -column=>1, -sticky=>'w');

my $bstart = $fb->Button(-text => 'Start', -command=>\&mark5_start
			)->pack(-side=>'left');
my $bstop = $fb->Button(-text => 'Stop', -command=>\&mark5_stop
		       )->pack(-side=>'left');
my $bconfig = $fb->Button(-text => 'Config', -command=>\&mark5_config
			 )->pack(-side=>'left');
my $bstatus = $fb->Button(-text => 'Status?', 
			  -command=> sub {mark5_command("status?")}
			 )->pack(-side=>'left');
my $bquit = $fb->Button(-text => 'Quit', -command=>sub {exit}
		       )->pack(-side=>'right');

my $log = $fc->Scrolled('Text',
			-relief => 'sunken',
			-borderwidth => 2,
			-setgrid => 'true',
			-width => 40,
			-height => 10,
			-background => $bgColour,
			-scrollbars => 'e')
  ->pack(-expand => 1, -fill =>  'both');


# UDP/TCP    select

MainLoop;

sub mark5_command ($) {
  my $cmd = shift;

  print $mark5 "$cmd\n";
  my $response =  <$mark5>;

  $log->insert('end',$response);
  $log->yview(moveto => 1);
  $log->update;
}

sub mark5_connect ($$) {
  my ($host, $port) = @_;

  $mark5 = IO::Socket::INET->new(PeerAddr => $host,
				 PeerPort => $port,
				);
  if (!$mark5) {
    die "Could not connect to $host:$port\n";
  }
  return $mark5;
}

sub mark5_config {
  my $winbytes = $winsize*1024;
  my $protocol;

  if ($udp) {
    mark5_command("mtu=$mtu");
    $protocol = 'udp';
  } else {
    $protocol = 'tcp';
  }

  if ($mark5b) {
    mark5_command("1pps_source=vsi"); 
    if ($test) {
      mark5_command("clock_set=$rate:int:$rate");
    } else {
      mark5_command("clock_set=$rate:ext:$rate");
    }
    mark5_command("dot_set=:force");
    mark5_command("dot?");

    my $decimation = $rate/($bandwidth*2);
    if ($test) {
      mark5_command("mode=tvg:$mask:$decimation");
    } else {
      mark5_command("mode=ext:$mask:$decimation");
    }
  } else {
    if ($test) {
      mark5_command("mode=tvg:$ntrack");
    } else {
      mark5_command("mode=mark4:$ntrack");
    }
    mark5_command("play_rate=data:$trackrate");
  }

  mark5_command("net_protocol=$protocol:$winbytes:131072:8");
  mark5_command("ipd=$ipd") if $udp;

}

sub mark5_start {
  mark5_command("in2net=connect:$host");
  mark5_command("in2net=on");
}

sub mark5_stop {
  mark5_command("in2net=disconnect");
}
