#!/usr/bin/perl
#
# tvm2xml.pl
#
# Converts epg-data from different sources to xmltv
#
# This software is released under the GNU GPL
#
# Version 0.2
# - fixed: title,subtitle,description not initiliased
# Version 0.3
# - fixed: missing special charakters in description
# Version 0.4
# - update: compatibility to tvm2vdr 0.5.12
# Version 0.5
# - update: compatibility to tvm2vdr 0.5.14
#
# ToDo: fix malformed utf-8 problem

use IO::Socket;
use Getopt::Std;
use Date::Manip;
use Date::Format;
use HTML::Entities qw(encode_entities_numeric);
use DBI;
&Date_Init("Language=German","DateFormat=non-US");

push (@INC, "./config");
require ("config.pl");
require ("channels.pl");
require ("channels_wanted.pl");

push (@INC, "./inc");
require ("helperfunc");

#---------------------------------------------------------------------------
# main

my $Usage = qq{
Usage: $0 [options]

Options: -v                    Show verbose messages

};

die $Usage if (!getopts('h:v') || $opt_h);

our $verbose = $opt_v || 0;

$heute   = UnixDate("heute", "%Y%m%d");
$gestern = UnixDate("gestern", "%Y%m%d");

if ($cleanupoldfiles) {
	print "cleanup old files ..\n";
	cleanup();
}

require ("tvmoviefetch");
require ("hoerzufetch");
require ("tvinfofetch");
require ("infosatfetch");
require ("premierefetch");
require ("tvtodayfetch");

if (! -w $imagepath and $writeimages) {
  die "cannot write to $imagepath!\n";
  }

if (! -w $downloadprefix) {
  die "cannot write to $downloadprefix!\n";
  }

if (! -w $updateprefix) {
  die "cannot write to $updateprefix!\n";
  }

if ($writeimages) {
  eval 'use Image::Magick';
  our $ckimage = Image::Magick->new;
  }


$SIG{'INT'}  = \&SIGhandler;

our $EXIT = false;
our %XML;

foreach $sender (keys(%chan_wanted)) {
    # print STDERR $sender, "\n";
    if ($chan_wanted{$sender} eq "1") {
        ReadExternalEPG_tvmovie();
        last;
    }
}

foreach $sender (keys(%chan_wanted)) {
    if ($chan_wanted{$sender} eq "2") {
        ReadExternalEPG_tvinfo();
        last;
    }
}

foreach $sender (keys(%chan_wanted)) {
    if ($chan_wanted{$sender} eq "3") {
        ReadExternalEPG_hoerzu(); 
        last;
    }
}

foreach $sender (keys(%chan_wanted)) {
    if ($chan_wanted{$sender} eq "4") {
        ReadExternalEPG_infosat();
        last;
    }
}

foreach $sender (keys(%chan_wanted)) {
	if ($chan_wanted{$sender} eq "5") {
		ReadExternalEPG_premiere();
		last;
	}
}

foreach $sender (keys(%chan_wanted)) {
	if ($chan_wanted{$sender} eq "6") {
		ReadExternalEPG_tvtoday();
		last;
	}
}

open(EPGFILE," >$epgfile") || die "cannot write epgfile $epgfile : $!";


# EPG & XML-Infos sind beide sortiert im Speicher - jetzt vergleichen.
my $chancounter = 0;
my $chancounts=0;
foreach $sender (keys(%chan)) {
	next if $chan_wanted{$sender} == "0";
	$chancounts++;
	}


WriteEPG("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
WriteEPG("<!DOCTYPE tv SYSTEM \"xmltv.dtd\">\n");
WriteEPG("<tv>\n"); 
foreach $sender (keys(%chan)) {
	next if $chan_wanted{$sender} == "0";
    WriteEPG("\t<channel id=\"$sender\">\n\t<display-name lang=\"de\">$sender</display-name>\n\t</channel>\n");
}	

foreach $sender (keys(%chan)) {
	next if $chan_wanted{$sender} == "0";
    
    $xmlcount = $#{$XML{$sender}};      # Anzahl XML-Eintr�ge f�r diesen Sender

    # EPG-Sendername suchen
#     my $found=0;
#     for my $channel (@channels) {
#         if ($channel->{xmltvid} eq $chan{$sender}[0]) {
#             $sendername = $channel->{name};
#             $found=1;
#             print "EPG-Info for $sender:  $#{$XML{$sender}}\n";
#             last;
#         }
#     }

#    if ($found eq 0) {
        $sendername = $sender;
#         print "\n\n!!!WARNING!!! $sender configured for fetching EPG,\n";
#         print "but ".$chan{$sender}[0]." not found in channels.conf!\n";
#         print "Please use contrib/printchannels.pl to sync channels.pl!!\n\n";
#     }

      
    
    for ($i=0; $i<=$xmlcount ;$i++) {
        #doexit() if $please_exit;
        WriteProgramme(@{$XML{$sender}}[$i]);
    }
}

WriteEPG("</tv>\n");

close EPGFILE;

exit;


sub WriteProgramme {

    my $grabProg = shift; 
    
    my $found_orig_event = 0;
    my $tline = "";
    my $sline = "";
    my $dline = "";
      
    if ($grabProg->{state} <= 0) {
        return;
    }

    my $unixstart=time2str("%Y%m%d%H%M%S", "$grabProg->{start}");
    my $unixstop=time2str("%Y%m%d%H%M%S", "$grabProg->{stop}");
    # my $length = "$grabProg->{duration}";   TODO....
    my $tline  = enc($grabProg->{title});
    
    if ($tline eq ""){
        return;
    } 

    my $sline  = enc($grabProg->{subtitle});
    my $dline  = enc($grabProg->{summary});
    #$vline  = "@{$XML{$sender}}[$i]->{vpsstart}";

    WriteEPG("\t<programme start=\"$unixstart +0100\" stop=\"$unixstop +0100\" channel=\"$sendername\">\n");
            # workaround for encode_entities problem
            #$tline = decode("iso-8859-3", $tline);
            #encode_entities_numeric($tline);
            #print $tline."\n";
    
    my $title = "";

    $title = "\t\t<title lang=\"de\">$tline</title>\n";

    my $subtitle = "";
    $subtitle = "\t\t<sub-title lang=\"de\">$sline</sub-title>\n" if ($desc ne "");
    # ($category,$special,$flags,@desc) = split ( /\|/, encode_entities_numeric($dline) );
    ($category,$special,$flags,@desc) = split ( /\|/, $dline );
    my $credits = "";
    my $desc = "";
    my $category = "";
    my $genre = "";
    my $country = "";
    my $date = "";
    my $episode_num = "";
    my $video = "";
    my $audio = "";
    my $rating = "";
    my $star_rating = "";
    foreach $field ( @desc ){
        $field =~ s/[ |\t]+$//g;
        if ( $field =~ s/Category:[ \?]+// ){
            $category .= "\t\t<category lang=\"de\">$field</category>\n";
        }elsif ( $field =~ s/Genre:[ \?]+// ){
            $genre .= "\t\t<genre lang=\"de\">$field</genre>\n";
        }elsif ( $field =~ s/Originaltitle:[ \?]+// ){
            $title .= "\t\t<title lang=\"en\">$field</title>\n";
        }elsif ( $field =~ s/Country:[ \?]+// ){
            $country .= "\t\t<country lang=\"de\">$field</country>\n";
        }elsif ( $field =~ s/Year:[ \?]+// ){
            $date .= "\t\t<date lang=\"de\">$field</date>\n";
        }elsif ( $field =~ s/Episode:[ \?]+// ){
            $episode_num .= "\t\t<episode-num>$field</episode-num>\n";
        }elsif ( $field =~ s/Format:[ \?]+// ){
            $video .= "\t\t<video>\n\t\t<aspect>$field</aspect>\n\t\t</video>\n";
        }elsif ( $field =~ s/Cast:[ \?]+// ){
            @actors = split( /, /, $field);
            foreach $actor ( @actors ){
                $actor =~ s/[ ,]+$//g;
                $credits .= "\t\t<actor>$actor</actor>\n";
            }
        }elsif ( $field =~ s/Director:[ \?]+// ){
            @directors = split( /, /, $field);
            foreach $director ( @directors ){
                $director =~ s/[ ,]+$//g;
                $credits .= "\t\t<director>$director</director>\n";
            }
        }elsif ( $field =~ s/Audio:[ \?]+// ){
            if($field eq "Dolby"){ 
                $field = "dolby";
            }
            $audio .= "\t\t<audio>\n\t\t<stereo>$field</stereo>\n\t\t</audio>\n";
        }elsif ( $field =~ s/FSK:[ \?]+// ){
            $rating .= "\t\t<rating system =\"FSK\">\n\t\t<value>$field</value>\n\t\t</rating>\n";
        }elsif ( $field =~ s/Rating:[ \?]+// ){
            $stars = length($field);
            $star_rating .= "\t\t<star-rating>\n\t\t<value>$stars/4</value>\n\t\t</star-rating>\n";
        }else{
            $field =~ s/[^a-zA-Z0-9,.!?;]+$//;
            $desc .= $field;
        }
                
    }
    WriteEPG($title);
    WriteEPG($subtitle);
    WriteEPG("\t\t<desc lang=\"de\">$desc</desc>\n") if ($desc ne "");
    WriteEPG("\t\t<credits>\n$credits\t\t</credits>\n") if ($credits ne "");
    WriteEPG($date);
    WriteEPG($category);
    WriteEPG($country);
    WriteEPG($episode_num);
    WriteEPG($video);
    WriteEPG($audio);
    WriteEPG($rating);
    WriteEPG($star_rating);
    WriteEPG("\t</programme>\n");
}


sub WriteEPG {
    my $line = pack "U0C*", unpack "C*", shift;
    use bytes;
    print EPGFILE $line;
    no bytes;
}

sub Error
{
  print STDERR "Fehler: @_\n";
  close(SOCK);
  exit 0;
}

sub enc {
    my $result = pack "C*", unpack "C*", shift; 
    $result =~ s/&/&amp;/g;
    $result =~ s/</&lt;/g;
    $result =~ s/>/&gt;/g;
    return $result;
}

