#!/usr/bin/perl -w
#
# Copyright 2002,03  August Hoerandl (august.hoerandl@gmx.at)
#                 http://elina.htlw16.ac.at/~hoerandl
# This program is free software.  You can redistribute it and/or modify
# it under the terms of the GNU General Public License v2
#
# Version 1.0   5 jul 2003
#
use XMLTV;
use Class::Date;
use Getopt::Long;

#
# Config

#
#  lower-case: different rows in output
#  upper-case: different row on previus day
#   length must be 24 - one / hour
#                   0         1         2
#                   012345678901234567890123
my $programm_row = "GGGGGGbbbbbbbccccdddeeff";

# show descr for these times
my $showdescr = "bcdefgG";

# min length of description
my $mindescr = 5;

# different pages
my %pages = ();

# predefined
#$pages{"Groupname"} = "TV1:TV2:TV3";

$width = 200;

$startfont = "<font size=\"-2\">";
$endfont = "</font>";

$starttimetag = "<i>";
$endtimetag = "";
$starttitletag = "";
$endtitletag = "</i>";

$repeatheader = 1;
$includecategoryshort = 0;
$includecategory = 1;

$showother = 0;

$showhelp = 0;
$debug = 0;
$showdots = 0;

$shownavi = 0;

#
# end of config - no user serviceable parts below
#

sub usage {
  die <<EOF;
create-html.pl [options] xmlfilename
  create html page from xmltv file
    --group name=channame1:channel2:...
                          group this channnels (may be repeated) *
    --showother           show group OTHER with unknown programs ($showother) *
    * one of these must be used to get any output

    --timeslots="$programm_row"
                          timeslots during the day
                           use 24 characters
                            lower-case: different row in output
                            upper-case: different row on previus day
    --showdescr="$showdescr"
                          show description for these slots

    --width=num           column width($width)
    --shownavi            show navigation links ($shownavi)
    --showcategory        show categorie ($includecategory)
    --repeatheader        repeat header after each block ($repeatheader)

    --debug               show debug output ($debug)
    --help                show this help
    --showdots            show . (progressinfo) ($showdots)
EOF
}

# ------------------------------------------------------------------
#
# program starts here
#

$res = GetOptions (
		   "debug!" => \$debug,
		   "help!" => \$showhelp,
		   "showdots!" => \$showdots,
		   "showother!" => \$showother,
		   "showcategory!" => \$includecategory,
		   "repeatheader!" => \$repeatheader,
		   "timeslots=s" => \$programm_row,
		   "showdescr=s" => \$showdescr,
                   "width=i" => \$width,
                   "shownavi!" =>  \$shownavi,
                   "group=s" => \%pages,
		  );
&usage if (!$res || $showhelp || $#ARGV != 0);

die "wrong number of timeslots\n" if (length($programm_row) != 24);

$xmlfilename = $ARGV[0];

print STDERR "parsing $xmlfilename\n" if ($debug);
#die "done";

my $data = XMLTV::parsefile($xmlfilename);
my ($encoding, $credits, $ch, $progs) = @$data;

foreach (values %$ch) {
  my $langs;
  my ($text, $lang) = @{XMLTV::best_name($langs, $_->{'display-name'})};

  $channelname{$_->{id}} = "$text";
#  print "channel $_->{id} has name $text\n";
#  print "...in language $lang\n" if defined $lang;
}

foreach (@$progs) {
  print STDERR "programme on channel $_->{channel} at time $_->{start}\n" if ($debug);
  print STDERR "title $_->{title}->[0]->[0]\n" if ($debug);
  print STDERR "."  if ($showdots);
  my $channel = $_->{channel};
  $channel = $channelname{$channel} if ($channelname{$channel});
  my $starttime = $_->{start};
  my $title = $_->{title}->[0]->[0];
  my $url = $_->{url}->[0];
  my $category = "";
  $category = $_->{category}->[0]->[0] if (defined $_->{category}->[0]->[0]);

  $category = "" if ($category =~ /unbekannt/);
  my $cat = "...";
  $cat = substr($category,0,1) if($includecategoryshort);
  $cat = $category if($includecategory);

  my $st_yr = substr($starttime, 0,4);
  my $st_mo = substr($starttime, 4,2);
  my $st_da = substr($starttime, 6,2);
  my $st_hr = substr($starttime, 8,2);
  my $st_mi = substr($starttime,10,2);

  my $start = Class::Date::date("$st_yr-$st_mo-$st_da $st_hr:$st_mi");
  my $row = substr($programm_row, $st_hr, 1);

  if ( $row le "Z") {
    $start = $start - "1D";
    $row =~ y/A-Z/a-z/;
#    print "yesterday : $start :";
    $st_mo = $start->mon;
    $st_da = $start->day;
    $st_mo = "0$st_mo" if ($st_mo < 10);
    $st_da = "0$st_da" if ($st_da < 10);
  } else {
    $days{"$st_mo,$st_da"} = 1;
  }

  my $descr = "";

  if (index($showdescr, $row) >= $[) {
    foreach (@{$_->{desc}}) {
      my ($text, $lang) = @$_;
      $descr .= "$text";
    }
  }

  if (defined $url) {
    $cat = "-" unless ($cat);
    $descr .= " <a href=\"$url\">$cat</a>";
  } else {
    $descr .= " $cat";
  }


  print STDERR "$channel,$st_yr,$st_mo,$st_da,$st_hr:$st_mi,$row,$title\n" if ($debug);

  my $index = "$st_mo,$st_da,$row,$channel";
  my $txt = "$starttimetag$st_hr:$st_mi$endtimetag $starttitletag$title$endtitletag";

  if (length($descr) > $mindescr) {
    $txt .= "\n      <br>" unless (substr($descr,0,1) eq "<");
    $txt .= "$descr";
  }

  print STDERR ":$index: => $txt\n" if ($debug);

  $text{"$index"} .= "$txt<br>";

  $rows{"$row"} = 1;
  $channels{"$channel"} = 1;
}

#my $header = "";
#foreach $channel (sort keys (%channels)) {
#  $header .= "<th>$channel</th>";
#}

foreach $page (sort keys (%pages)) {
  foreach $channel (split /:/, $pages{$page}) {
    $channels{"$channel"}++;
  }
}
if ($showother) {
  $pages{"OTHERS"} = "";
  foreach $channel (sort keys (%channels)) {
    $pages{"OTHERS"} .="$channel:" if ($channels{"$channel"} == 1);
  }
}

# OK - time to print

print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<html>\n";
print "<head><title>TV Listing</title></head>\n";
print "<base target=\"_blank\">\n";
print "<body>\n";

print "$startfont";

if ($shownavi) {
  print "<h1>Inhalt</h1>\n";
  foreach $date (sort keys (%days)) {
    print "<h3><a href=\"#a$date\">$date</h3>";
    print "<ul>\n";
    foreach $page (sort keys (%pages)) {
      print "<li><a target=\"_self\" href=\"#a$date$page\">$page</a> $pages{$page}</li>\n";
    }
    print "</ul>\n";
  }
}

foreach $date (sort keys (%days)) {
  print "<h1><a name=\"a$date\">Programm für: $date</a></h1>\n";

  foreach $page (sort keys (%pages)) {
    my @channels = split(/:/, $pages{$page});
    my $cnt = 1+$#channels;
    my $w = $cnt*$width;
    print "<h2><a name=\"a$date$page\">$page -- $date</a></h2>\n";
    print "<table border=\"1\" width=\"$w\">\n";
    print "<tr>\n";
    foreach $channel (@channels) {
      print "   <th width=\"$width\">$startfont<a name=\"c$date$channel\">$channel - $date</a>$endfont</th>\n";
    }
    print "</tr>\n";
	
    foreach $row (sort keys (%rows)) {
      print "  <tr>\n";
      foreach $channel (split /:/, $pages{$page}) {
	#      print "$channel ";
	my $index = "$date,$row,$channel";
	my $txt = "&nbsp;";
	$txt =  $text{"$index"} if (defined($text{"$index"}));
	print "    <td valign=\"top\" width=\"$width\">$startfont",$txt,"$endfont</td>\n";
      }
      print "  </tr>\n";
      if ($repeatheader) {
	print "  <tr>\n";
	foreach $channel (split /:/, $pages{$page}) {
	  print "   <th width=\"$width\">$startfont $channel - $date $endfont</th>\n";
	}
	print "  </tr>\n";
      }
    }
    print "</table>\n";
  }
}
print "$endfont";

print "</body>\n</html>\n";

