#!/usr/bin/perl

############################
# by Void Main
# It's ugly so have at it
############################

use strict;
use Tk;
use Time::HiRes;
require Tk::FileSelect;
require Tk::Dialog;

# sound on: 1, sound off: 0
my $sound=1;
my $sa = 440;
my $sb = 494;
my $sc = 523;
my $sd = 582;
my $se = 659;
my $sf = 698;
my $sg = 787;
my $sha = 867;

my $lights=0;
system("./lptout $lights");

my $fname = $ARGV[0];
my $main = new MainWindow(-title => 'xLights');
$main->Label(-text => 'Select Lights')->pack;

my $lightframe=$main->Frame;
$lightframe->pack;
my $l1 = $lightframe->Checkbutton(-selectcolor => 'yellow',-command => sub{do_lights('1')});
$l1->pack(-side => 'left');
my $l2 = $lightframe->Checkbutton(-selectcolor => 'red',-command => sub{do_lights('2')});
$l2->pack(-side => 'left');
my $l3 = $lightframe->Checkbutton(-selectcolor => 'red',-command => sub{do_lights('4')});
$l3->pack(-side => 'left');
my $l4 = $lightframe->Checkbutton(-selectcolor => 'green',-command => sub{do_lights('8')});
$l4->pack(-side => 'left');
my $l5 = $lightframe->Checkbutton(-selectcolor => 'red',-command => sub{do_lights('16')});
$l5->pack(-side => 'left');
my $l6 = $lightframe->Checkbutton(-selectcolor => 'yellow',-command => sub{do_lights('32')});
$l6->pack(-side => 'left');
my $l7 = $lightframe->Checkbutton(-selectcolor => 'green',-command => sub{do_lights('64')});
$l7->pack(-side => 'left');
my $l8 = $lightframe->Checkbutton(-selectcolor => 'yellow',-command => sub{do_lights('128')});
$l8->pack(-side => 'left');

my $soundframe=$main->Frame;
$soundframe->pack;
my $sndbtn = $soundframe->Checkbutton(-text => 'Enable Sound',-command=> sub{sound_check()});
$sndbtn->select;
$sndbtn->pack(-side => 'left');

my $fileframe=$main->Frame;
$fileframe->pack;
my $filename = $fileframe->Entry(-width => 40, -textvariable => \$fname);
$filename->pack(-side => 'left');
$fileframe->Button(-text => 'Browse...',
	      -command => sub{$fname=do_browse($fname);}
		  )->pack(-side => 'right');
$main->Button(-text => 'Run Lights File', 
	      -command => sub{do_lightsfile($fname)}
	     )->pack;
MainLoop;

sub sound_check {
  if ($sound) { $sound=0; } else {$sound=1;}
}

sub bad_file {
  my ($sel) = @_;
  $sel="Your selection" unless $sel;
  my $dialog=$main->Dialog(-title => 'Not a text file',
			   -text => "$sel is not a Text File");
  $dialog->Show;
}

sub do_browse {
  my ($dir) = @_;

  my $fs=$main->FileSelect;
  my $new=$fs->Show;
  if (-T $new) {
    $dir=$new;
  } else {
    bad_file($new);
  }
  return $dir;
}

sub do_lights {
  my ($lt) = @_;
  my $note;
  $lights = $lights ^ $lt;
  if ($lt & 1) {$note=$sa;}
  if ($lt & 2) {$note=$sb;}
  if ($lt & 4) {$note=$sc;}
  if ($lt & 8) {$note=$sd;}
  if ($lt & 16) {$note=$se;}
  if ($lt & 32) {$note=$sf;}
  if ($lt & 64) {$note=$sg;}
  if ($lt & 128) {$note=$sha;}
  if ($sound) {
    system("xset b 50 $note 200;tput bel");
  }
  system("./lptout $lights");
  return $lt;
}

sub do_lightsfile {
  my ($f) = @_;

  unless (-T $f) {
    bad_file($f);
    return;
  }

  open (FILE,$f);
  my $line;
  my @tmp;
  my $t;
  my @lights;
  my @times;
  my $light;
  my $time;
  my $note;
  my $notecnt;
  my $pitch;

  while (<FILE>) {
    if (/^#/) {next;}
    if (/^$/) {next;}
    @tmp = split;
    foreach $t (<@tmp>) {
      ($light,$time) = split(/\//,$t);
      if ($light eq "") {next;}
      push(@lights,$light);
      push(@times,$time);
      $note = 0;
      $notecnt = 0;
      if ($light & 1) {$l1->select;$note+=$sa;$notecnt++;} else {$l1->deselect;}
      if ($light & 2) {$l2->select;$note+=$sb;$notecnt++;} else {$l2->deselect;}
      if ($light & 4) {$l3->select;$note+=$sc;$notecnt++;} else {$l3->deselect;}
      if ($light & 8) {$l4->select;$note+=$sd;$notecnt++;} else {$l4->deselect;}
      if ($light & 16) {$l5->select;$note+=$se;$notecnt++;} else {$l5->deselect;}
      if ($light & 32) {$l6->select;$note+=$sf;$notecnt++;} else {$l6->deselect;}
      if ($light & 64) {$l7->select;$note+=$sg;$notecnt++;} else {$l7->deselect;}
      if ($light & 128) {$l8->select;$note+=$sha;$notecnt++;} else {$l8->deselect;}
      $main->update;
      system("./lptout $light");
      if ($sound) {
        if ($notecnt) {
          $pitch = int($note / $notecnt);
          system("xset b 50 $pitch $time;tput bel");
        }
      }
      Time::HiRes::usleep($time * 1000);
    }
  }

  close FILE;
  system("./lptout 0");
}
