#!/usr/bin/perl -w
#
# This program is initially based on test/x11amp.pl of the official 
# lcdproc distribution (http://lcdproc.omnipotent.net/)
#
##################################################
#
# GiantDisc mp3 Jukebox, LCD Client script
# 
# © 2000-2002, Rolf Brugger
#
##################################################
# 
# gdlcdclient.pl displays the current state of the GiantDisc server
# on a LC-Display. 
# 
# - requires a running LCDproc server (http://lcdproc.omnipotent.net/)
# - supports all types of LC-Displays that are supported by LCDproc
# 
#


# THIS IS A PRELIMINARY VERSION THAT ONLY DISPLAYS TWO LINES OF TEXT ON A 2x16 LCD

use strict;

use IO::Socket;
use Fcntl;


use lib '/home/music/bin';
use gddb;
use gdparams;
use gdgentools;

use DBI;


##################################################
### get Parameters
if(scalar(@ARGV) != 4){
  print("gdplayd needs three parameters (host-ip, player-id, audiochannel, layout)\n");
  print("\"host-ip player-id player-type\" is usually \"localhost 0 0\"\n");
  print("If this doesn't work, the id and type are printed on the console\n");
  print("if them menu item 'DB/Disc statistics' in the Palm is selected.\n");
  print("List all layouts with the command      grep \"layout"." eq\" gdlcdclient.pl \n");
exit(0);}
my $dbhost     = $ARGV[0];
my $playerid   = $ARGV[1];
my $audiochannel = $ARGV[2]; 
my $layout     = $ARGV[3]; 

$gdparms::dbhost = $dbhost;

### read parameters from configfile
my (%keymap);
gdparams::get_otherclients_params(\%keymap);


##################################################
### Constants
my $ds = "h 6";		     # direction and speed of a scrolling text widget
my $bcklghtduration = 20;    # backlight-on duration (seconds)
my $bcklghton       = 0;     # turn backlight on


##################################################
### LCDproc Initialization

# Connect to the server...
my $remote = IO::Socket::INET->new(
		Proto     => "tcp",
		PeerAddr  => "localhost",
	       #PeerAddr  => $dbhost,
		PeerPort  => "13666",
	)
	|| die "Cannot connect to LCDproc port\n";


$remote->autoflush(1);	# Make sure our messages get there right away
sleep 1;		# Give server plenty of time to notice us...

print $remote "hello\n";
my $lcdresponse = <$remote>;
#print $lcdresponse;

# Turn off blocking mode...
fcntl($remote, F_SETFL, O_NONBLOCK);

# Set up some screen widgets...
print $remote "client_set name {GiantDisc}\n";
print $remote "screen_add gdlcd\n";
print $remote "screen_set gdlcd -heartbeat off\n";

print $remote "widget_add gdlcd scr1 scroller\n";	# scrolling text widget
print $remote "widget_add gdlcd scr2 scroller\n";	# scrolling text widget
print $remote "widget_add gdlcd scr3 scroller\n";	# scrolling text widget
print $remote "widget_add gdlcd scr4 scroller\n";	# scrolling text widget
print $remote "widget_add gdlcd ptime string\n";	# normal text widget

# listen to specified keys (specified in .gdconfig)
my $key;
foreach $key (sort keys %keymap){
  #print "listen to key $key\n";
  print $remote "client_add_key $key\n";
}

### open DB connection
my $dbh = DBI->connect("DBI:mysql:GiantDisc:".$dbhost, "music", undef)
    or die "unable to connect to GiantDisc db";

### set termination handler
$SIG{TERM} = sub { print "gdlcdclient.pl killed\n"; $dbh->disconnect; exit;}; # set Kill event handler


##################################################
### Begin
my $base = gdparams::gdbase();

my ($sth, $trow, $albh, $arow, $mp3file, $trackind, $trackid, $state, $startframe);

my($ptime_f, $ptime_sm, $tottime_f, $tottime_sm, $titart, $redraw_track);
my $prev_trackid = -1;
my $albavailable = 0;

my $cntr = 0;
my $bcklghtcntr = $bcklghtduration;
print $remote "backlight on\n";

while(1){
  sleep (1);  # sleep a second
  #if (($cntr % 100) == 0){print "$cntr seconds alive\n";}; $cntr++;
  #print ">"; while(defined($lcdresponse = <$remote>)){ print "response: $lcdresponse";}

  ### Handle input
  handle_key_input();


  ### Send data to LCD
  # Get State of player
  ($trackind, $state, $startframe) = gdgentools::pll_get_playstate($dbh, $playerid, $audiochannel);
  
  # get currently played track
  $trackid = gdgentools::tracklist_get_item($dbh, $playerid, 0, $trackind);
  $sth = $dbh->prepare("SELECT * FROM tracks WHERE id = $trackid");
  $sth->execute;
  if ($trow = $sth->fetchrow_hashref){
    # get current playtime position
    ($ptime_f, $tottime_f) = gdgentools::pll_get_playtime($dbh, $playerid, $audiochannel);
    #print "time: $ptime_f, tot: $tottime_f\n";
  
    $redraw_track = ($trackid != $prev_trackid);	# id of current track has changed
    if ($redraw_track){
      ### a new track is being played
      
      $albh = $dbh->prepare("SELECT * FROM album WHERE cddbid = '$trow->{sourceid}'");
      $albh->execute;
      $albavailable = ($arow = $albh->fetchrow_hashref);
      
      $prev_trackid = $trackid;

      $bcklghton = 1;
    }
    $tottime_sm = gdgentools::seconds_to_sm($tottime_f/ gdgentools::frames_per_second());
    $ptime_sm   = gdgentools::seconds_to_sm($ptime_f  / gdgentools::frames_per_second());


    ### backlight control
    if($bcklghton){
      print $remote "backlight on\n";
      $bcklghtcntr = $bcklghtduration;
      $bcklghton = 0;
    }
    if($bcklghtcntr > 0){
      $bcklghtcntr--;	 # countdown
      if($bcklghtcntr == 0){
        print $remote "backlight off\n";
      }
    }

    ####################################################################
    ####################################################################
    ### Layouts
    ### (Add your custom layouts here)


    if    ($layout eq "2x16-1"){ # 1: artist+title  2: playtime
      if($redraw_track){
        print $remote "widget_set gdlcd scr1 1 1 16 1 $ds {$trow->{artist} - $trow->{title}}\n";
      }
      print $remote "widget_set gdlcd ptime 1 2 {$ptime_sm $tottime_sm}\n";
    }


    elsif ($layout eq "2x16-2"){ # 1: title         2: playtime
      if($redraw_track){
        print $remote "widget_set gdlcd scr1 1 1 16 1 $ds {$trow->{title}}\n";
      }
      print $remote "widget_set gdlcd ptime 1 2 {$ptime_sm $tottime_sm}\n";
    }


    elsif ($layout eq "2x16-3"){ # 1: artist        2: title
      if($redraw_track){
        print $remote "widget_set gdlcd scr1 1 1 16 1 $ds {$trow->{artist}}\n";
        print $remote "widget_set gdlcd scr2 1 2 16 1 $ds {$trow->{title}}\n";
      }
    }


    elsif ($layout eq "2x16-4"){ # 1: artist+album  2: title playtime
      if($redraw_track){
        if ($albavailable){
          print $remote "widget_set gdlcd scr1 1 1 16 1 $ds {$trow->{artist} ($arow->{title})}\n";
        }
        else{
          print $remote "widget_set gdlcd scr1 1 1 16 1 $ds {$trow->{artist}}\n";
        }
        print $remote "widget_set gdlcd scr2 1 2 11 1 $ds {$trow->{title}}\n";
      }
      print $remote "widget_set gdlcd ptime 13 2 {$ptime_sm}\n";
    }


    else{
      print "unknown layout '$layout'\n";
      exit;
    }

    ####################################################################
    ####################################################################
    
    
  }
  else{
    print $remote "widget_set gdlcd scr1 1 1 16 1 $ds  {-empty-}\n";
    print $remote "widget_set gdlcd ptime 1 2 {-stopped-}\n";
  }

  $sth->finish;
  ### get track-ID at current index
  $trackid = gdgentools::tracklist_get_item($dbh, $playerid, 0, $trackind);
}

$dbh->disconnect;



### close LCDproc connection

close ($remote)            || die "close: $!";
exit;



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

sub handle_key_input{
  my ($lcdresponse, @items, $command, $key);
  
  while(defined($lcdresponse = <$remote>)){ 
    #print "response: $lcdresponse";
    @items = split(" ", $lcdresponse);
    $command = shift @items;
    if($command eq "key"){	# 
      no strict 'refs';
      
      $key = shift @items;
      #print "key: '$key'  cmd: $keymap{$key}\n";
      &{$keymap{$key}} ();	# call function that is mapped to the key

      $bcklghton = 1;		# any key pressed, turn light on
    }
    # Ignore other responses
    elsif($command eq "connect")
    {
    }
    elsif($command eq "listen")
    {
    }
    elsif($command eq "ignore")
    {
    }
    elsif($command eq "success")
    {
    }
    else {
      if($lcdresponse =~ /\S/) {print "Error?  $lcdresponse\n";}
    }
  }
}


####################################################################
### Keypad Functions

sub cmd_stop{
  gdgentools::pl_stop($dbh, $playerid, $audiochannel);
}

sub cmd_pause{
  gdgentools::pl_pause($dbh, $playerid, $audiochannel);
}

sub cmd_play{
  gdgentools::pl_play($dbh, $playerid, $audiochannel);
}

sub cmd_prev{
  gdgentools::pl_prev($dbh, $playerid, $audiochannel);
}

sub cmd_next{
  gdgentools::pl_next($dbh, $playerid, $audiochannel);
}

sub cmd_fastfwd{
  gdgentools::pl_ff($dbh, $playerid, $audiochannel);
}

sub cmd_rewind{
  gdgentools::pl_rw($dbh, $playerid, $audiochannel);
}


sub cmd_bcklghton{
  $bcklghton = 1;
}

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

#