package XXV::MODULES::EPG;
use strict;

use Tools;
use Event::File;
use Date::Manip;
use Locale::gettext;
use Time::Local;


# This module method must exist for XXV
# ------------------
sub module {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $args = {
        Name => 'EPG',
        Description => gettext('This module want read new EPG Data and save this in the Database.'),
        Version => '0.45',
        Date => '21.09.2005',
        Author => 'xpix',
        Status => sub{ $obj->status(@_) },
        Preferences => {
            epgfile => {
                description => gettext('Location of epg.data on your system.'),
                default     => '/video/epg.data',
                type        => 'file',
                required    => gettext('This is required!'),
            },
            epgimages => {
                description => gettext('Location of additional EPG images.'),
                default     => '/var/cache/vdrdevel/epgimages',
                type        => 'dir',
            },
            interval => {
                description => gettext('The interval to parse new EPG to DB in sec'),
                default     => 300,
                type        => 'integer',
                required    => gettext('This is required!'),
            },
            restart => {
                description => gettext('The interval in hours (!) between full EPG data reparsing.'),
                default     => 3,
                type        => 'integer',
                required    => gettext('This is required!'),
            },
            periods => {
                description => gettext("Pre-defined list for the 'Running Now' view (comma separated list)"),
                default     => '12:00,18:00,20:15,22:00',
                type        => 'string',
                required    => gettext('This is required!'),
            },
            timeframe => {
                description => gettext("How much hours to display in schema"),
                default     => 2,
                type        => 'integer',
                required    => gettext('This is required!'),
            },
        },
        Commands => {
            search => {
                description => gettext('Search in EPG Data'),
                short       => 's',
                callback    => sub{ $obj->search(@_) },
            },
            program => {
                description => gettext("List program for channel 'channel name'"),
                short       => 'p',
                callback    => sub{ $obj->program(@_) },
            },
            display => {
                description => gettext("Show program event 'eventid'"),
                short       => 'd',
                callback    => sub{ $obj->display(@_) },
            },
            estatus => {
                description => gettext('Status from EPG Data'),
                short       => 'et',
                callback    => sub{ $obj->status(@_) },
            },
            now => {
                description => gettext('Display events is running now'),
                short       => 'n',
                callback    => sub{ $obj->runningNow(@_) },
            },
            next => {
                description => gettext('Display events is running next'),
                short       => 'nx',
                callback    => sub{ $obj->runningNext(@_) },
            },
            schema => {
                description => gettext('Display events in a schematic way'),
                short       => 'sch',
                callback    => sub{ $obj->schema(@_) },
            },
            epurge => {
                description => gettext('Delete all EPG Events and restart the Scan process'),
                short       => 'ep',
                callback    => sub{ $obj->epurge(@_) },
                Level       => 'admin',
            },
            erestart => {
                description => gettext('Restart the EPG scan process'),
                short       => 'er',
                callback    => sub{
                    my $watcher = shift || return error ('No Watcher!');
                    my $console = shift || return error ('No Console');
                    delete $obj->{attr};
                    $obj->{EventTail}->start;

                    lg sprintf('EPG Scan is restartet from User: %s',
                        $console->{USER}->{Name}
                        );

                    $console->redirect({url => $console->{browser}->{Referer}, wait => 2})
                        if($console->typ eq 'HTML');
                    return $console->message(gettext('EPG Scan restartet!'));
                },
                Level       => 'admin',
            },
            conflict => {
                hidden      => 'yes',
                callback    => sub{ return $obj->checkOnTimer(@_) },
            },
        },
    };
    return $args;
}

# ------------------
sub status {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $watcher = shift;
    my $console = shift;
    my $lastReportTime = shift || 0;

    my $sql = "select count(*) from EPG";
    my $gesamt = $obj->{dbh}->selectall_arrayref($sql)->[0][0];

    $sql = "select count(*) from EPG where UNIX_TIMESTAMP(addtime) > $lastReportTime";
    my $newEntrys = $obj->{dbh}->selectall_arrayref($sql)->[0][0];

    return {
        message => sprintf(gettext('EPG table contains %d entries and since the last login at %s %d new entries'),
            $gesamt, scalar localtime($lastReportTime), $newEntrys),
    };
}

# ------------------
sub new {
# ------------------
	my($class, %attr) = @_;
	my $self = {};
	bless($self, $class);

    # paths
    $self->{paths} = delete $attr{'-paths'};

	# who am I
    $self->{MOD} = $self->module;

    # all configvalues to $self without parents (important for ConfigModule)
    map {
        $self->{$_} = $attr{'-config'}->{$self->{MOD}->{Name}}->{$_} || $self->{MOD}->{Preferences}->{$_}->{default}
    } keys %{$self->{MOD}->{Preferences}};

    # read the DB Handle
    $self->{dbh} = delete $attr{'-dbh'};

    # The Initprocess
    $self->init or return error('Problem to initialze Module');

	return $self;
}

# ------------------
sub init {
# ------------------
    my $obj = shift || return error ('No Object!' );

    # Old Version
    if(tableExists($obj->{dbh}, 'EPG')) {
        my $fields = fields($obj->{dbh}, 'select * from EPG');
        unless(scalar @$fields == 10) {
            $obj->{dbh}->do('drop table EPG');
            $obj->{dbh}->do('drop table OLDEPG');
        }
    }

    # Look for table or create this table
    foreach my $table (qw/EPG OLDEPG/) {
        my $version = main::getVersion;
        $obj->{dbh}->do(qq|
          CREATE TABLE IF NOT EXISTS $table (
              eventid int(16) unsigned NOT NULL default '0',
              title varchar(100) NOT NULL default '',
              subtitle varchar(100) default '',
              description longtext,
              channel_id varchar(100) NOT NULL default '',
              starttime datetime NOT NULL default '0000-00-00 00:00:00',
              duration int(11) NOT NULL default '0',
              tableid varchar(100) default '',
              image text default '',
              addtime datetime NOT NULL default '0000-00-00 00:00:00',
              PRIMARY KEY (eventid),
              INDEX (starttime),
              INDEX (channel_id)
            ) COMMENT = '$version'
        |);
    }

    return 1, warn ('No EPG File found') if( ! -e  $obj->{epgfile});

    # Restart epurge every 6 hours
    Event->timer(
        interval => 6*3600,
        prio => 6,  # -1 very hard ... 6 very low
        cb => sub{
            lg sprintf('Automatic epurge is startet!');
            $obj->epurge;
        },
    );

    # Delete the old EPG Entrys in Interval
    Event->timer(
        interval => $obj->{interval},
        prio => 6,  # -1 very hard ... 6 very low
        cb => sub{
            lg sprintf('Automatic repair data is startet!');
            $obj->repairData
        },
    );

    # Repair later Data ...
    main::after(sub{
        $obj->{EventTail} = $obj->startTail( $obj->{epgfile} );

        # Restart watcher every x hours
        Event->timer(
            interval => $obj->{restart}*3600,
            prio => 6,  # -1 very hard ... 6 very low
            cb => sub{
                delete $obj->{attr};
                lg sprintf('The tail on epg file is restartet!');
                $obj->{EventTail}->start;
            },
        );
        $obj->repairData;
    }, "EPG: Start tail epg data and repair ...");

    return 1;
}

# ------------------
sub epurge {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $watcher = shift;
    my $console = shift;
    $obj->{EventTail}->cancel;
    $obj->{EventTail} = undef;
    $obj->{dbh}->do('delete from EPG');
    $obj->{EventTail} = $obj->startTail( $obj->{epgfile} );
    return $console->message(gettext('EPG Scan completely restartet!'))
        if(ref $console);
}

# ------------------
sub startTail {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $file = shift || return error('No File');

    $obj->{OLDPOS} = 0;

    # Read new EPG Data if epg.data touched
    my $event = Event::File->tail(
        cb => sub {
            $obj->readData(@_);
        },
        file => $file,
        postion => 0,
    );

    return $event;
}

# ------------------
sub repairData {
# ------------------
    my $obj = shift || return error ('No Object!' );

    # Copy and delete old EPG Entrys
    $obj->{dbh}->do('REPLACE INTO OLDEPG SELECT * FROM EPG WHERE (UNIX_TIMESTAMP(EPG.starttime) + EPG.duration) < UNIX_TIMESTAMP()');
    $obj->{dbh}->do('DELETE FROM EPG WHERE (UNIX_TIMESTAMP(EPG.starttime) + EPG.duration) < UNIX_TIMESTAMP()');

    # Delete double EPG Entrys
    my $erg = $obj->{dbh}->selectall_arrayref('SELECT eventid FROM EPG GROUP BY starttime, channel_id having count(*) > 1');
    lg sprintf('Repair data found %d wrong events!', scalar @$erg);

    foreach my $row (@$erg) {
        $obj->{dbh}->do(sprintf("DELETE FROM EPG WHERE eventid = '%lu'", $row->[0]));
    }
}

# ------------------
sub insert {
# ------------------
    my $obj = shift || return error ('No Object!');
    my $attr = shift || return error ('No Data for insert!');

    $attr->{title} = gettext("No Title")
        unless($attr->{title});
    $attr->{description} = ""
        unless($attr->{description});

    # look for NID-TID-SID for unique eventids (SID 0-30000 / TID 0 - 1000 / NID 0 - 10000
    my @id = split('-', $attr->{channel});

    # Sanity check, a eventid has on etsi only 16bit
    warn "something wrong, eventid to big : ",$attr->{eventid}
        if($attr->{eventid} > 0xFFFF);
    # Make a fix format 0xCCCCEEEE : C-Channelid (high-word), E-Eventid(low-word) => real-eventid = uniqueid & FFFF
    my $eventid = ((($id[-3] + $id[-2] + $id[-1]) & 0x3FFF) << 16) | ($attr->{eventid} & 0xFFFF);

    my $sth = $obj->{dbh}->prepare('REPLACE INTO EPG(eventid, title, subtitle, description, channel_id, duration, tableid, image, starttime, addtime) VALUES (?,?,?,?,?,?,?,?,FROM_UNIXTIME(?),FROM_UNIXTIME(?))');
    $sth->execute(
        $eventid,
        $attr->{title},
        $attr->{subtitle},
        $attr->{description},
        $attr->{channel},
        $attr->{duration},
        $attr->{tableid},
        $attr->{image} || '',
        $attr->{starttime},
        time,
    ) if($attr->{channel});
}

# ------------------
sub readData {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $watcher = shift || return error ('No Watcher!' );
    my $line = shift || return;

    # !!! OldPosition: %s is higher as actual position: %d
    if($watcher->position < $obj->{OLDPOS}) {
        return undef;
    }

    # Ok, save ...
    if($line eq 'e' and $obj->{attr}->{eventid}) {
        $obj->insert($obj->{attr});
        my $channel = $obj->{attr}->{channel};
        $obj->{attr} = undef;
        $obj->{attr}->{channel} = $channel;
    }
    my ($mark, $data) = $line =~ /^(\S)\s+(.+)/g;
    return unless($mark and $data);

    # New Channelname
    if($mark eq 'C') {
        $obj->{attr}->{channel} = (split(/\s+/, $data))[0];
    } elsif($mark eq 'E') {
        ($obj->{attr}->{eventid}, $obj->{attr}->{starttime}, $obj->{attr}->{duration}, $obj->{attr}->{tableid}) = split(/\s+/, $data);
        my $image = sprintf('%s/%d.png', $obj->{epgimages}, $obj->{attr}->{eventid});
        $obj->{attr}->{image} = sprintf('%d.png', $obj->{attr}->{eventid})
            if(-e $image);
    } elsif($mark eq 'T') {
        $obj->{attr}->{title} = $data;
    } elsif($mark eq 'S') {
        $obj->{attr}->{subtitle} = $data;
    } elsif($mark eq 'D') {
        $obj->{attr}->{description} = $data;
    }
    $obj->{OLDPOS} = $watcher->position;
}

# ------------------
sub search {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $watcher = shift || return error ('No Watcher!');
    my $console = shift || return error ('No Console');
    my $text = shift || return $console->message(gettext("No Text to search! Please use search 'text'"));
    my $params = shift;

    my $tim = main::getModule('TIMERS');
    my $search = buildsearch("e.title,e.subtitle,e.description",$text);

    $search .= sprintf(' AND c.POS = %lu ', $params->{channel})
        if(exists $params->{channel});

    my $sql = qq|
select
    e.eventid as Service,
    e.title as Title,
    e.subtitle as __Subtitle,
    c.Name as Channel,
    c.POS as __Pos,
    DATE_FORMAT(e.starttime, '%H:%i') as Start,
    DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(e.starttime) + e.duration), '%H:%i') as Stop,
    UNIX_TIMESTAMP(e.starttime) as Day,
    e.description
from
    EPG as e,
    CHANNELS as c
where
    e.channel_id = c.Id
    AND ( $search )
order by
    starttime
|;
#dumper($sql);
    my $fields = fields($obj->{dbh}, $sql);

    my $erg = $obj->{dbh}->selectall_arrayref($sql);
    unshift(@$erg, $fields);

    $console->table($erg, {timers => $tim->getEpgIds});
}

# ------------------
sub program {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $watcher = shift || return error ('No Watcher!');
    my $console = shift || return error ('No Console');
    my $channel = shift || $obj->{dbh}->selectall_arrayref("select POS from CHANNELS limit 1")->[0][0];

    my $mod = main::getModule('CHANNELS');
    my $tim = main::getModule('TIMERS');

    my $cid;
    if($channel =~ /^\d+$/sig) {
        $cid = $mod->PosToChannel($channel)
            or return $console->message(sprintf(gettext("This channel '%s' is not exist in Database!"),$channel));
    } else {
        $cid = $mod->NameToChannel($channel)
            or return $console->message(sprintf(gettext("This channel '%s' is not exist in Database!"),$channel));
    }

    my $sql = qq|
select
    e.eventid as Service,
    e.title as Title,
    e.subtitle as __Subtitle,
    DATE_FORMAT(e.starttime, '%H:%i') as Start,
    DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(e.starttime) + e.duration), '%H:%i') as Stop,
    UNIX_TIMESTAMP(e.starttime) as Day,
    e.description as __Description
from
    EPG as e, CHANNELS as c
where
    e.channel_id = c.Id and
    e.channel_id = '$cid'
order by
    starttime
|;
    my $fields = fields($obj->{dbh}, $sql);

    my $erg = $obj->{dbh}->selectall_arrayref($sql);
    unshift(@$erg, $fields);

    $console->table($erg, {
                            channels => $mod->ChannelArray('Name'),
                            current => $mod->ChannelToPos($cid),
                            timers => $tim->getEpgIds
                           }
                    );
}

# ------------------
sub display {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $watcher = shift || return error ('No Watcher!');
    my $console = shift || return error ('No Console');
    my $eventid = shift || return $console->message(gettext("No EventID to display the Event Programm! Please use display 'eventid'"));

    my $sql = qq|
select
    e.eventid as Id,
    e.title as Title,
    e.subtitle as Subtitle,
    DATE_FORMAT(e.starttime, '%W: %H:%i %e.%c.%Y') as Start,
    DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(e.starttime) + e.duration), '%W: %H:%i %e.%c.%Y') as Stop,
    c.Name as Channel,
    e.description as Description,
    e.image as __Image,
    (unix_timestamp(e.starttime) + e.duration - unix_timestamp())/duration*100 as Percent
from
    EPG as e,CHANNELS as c
where
    e.channel_id = c.Id
    and eventid = '$eventid'
|;

    my $fields = fields($obj->{dbh}, $sql);

    my $erg = $obj->{dbh}->selectall_arrayref($sql);
    ######################
    # Lookup failed, so we look at oldepg
    if(scalar @{$erg} == 0 ) {
    $sql = qq|
select
    e.eventid as Id,
    e.title as Title,
    e.subtitle as Subtitle,
    DATE_FORMAT(e.starttime, '%W: %H:%i %e.%c.%Y') as Start,
    DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(e.starttime) + e.duration), '%W: %H:%i %e.%c.%Y') as Stop,
    c.Name as Channel,
    e.description as Description,
    e.image as __Image,
    999 as Percent
from
    OLDEPG as e,CHANNELS as c
where
    e.channel_id = c.Id
    and eventid = '$eventid'
|;
    $erg = $obj->{dbh}->selectall_arrayref($sql);
}
    # Translate weekday for field start and stop
    if(scalar @{$erg} != 0 ) {
        my @wdays = (
             'Monday', gettext("Monday") ,
             'Tuesday', gettext("Tuesday") ,
             'Wednesday', gettext("Wednesday") ,
             'Thursday', gettext("Thursday") ,
             'Friday', gettext("Friday") ,
             'Saturday', gettext("Saturday") ,
             'Sunday', gettext("Sunday")
        );

        for (my $n = 0;$n < ((scalar @wdays)/2); ++$n ) {

            my $fday = $wdays[($n*2)];
            my $tday = $wdays[($n*2)+1];

            # halt here if'nt translation present
            last
                if($fday eq $tday);

            # Translate field start
            @$erg[0]->[3] =~ s/$fday/$tday/g;
            # Translate field stop
            @$erg[0]->[4] =~ s/$fday/$tday/g;
        }
    }
    ######################
    unshift(@$erg, $fields);

    my $tim = main::getModule('TIMERS');
    $console->table($erg,{timers => $tim->getEpgIds});
}

# ------------------
sub runningNext {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $watcher = shift || return error ('No Watcher!');
    my $console = shift || return error ('No Console');

    # Create temporary table
    $obj->{dbh}->do(qq|
CREATE TEMPORARY TABLE IF NOT EXISTS NEXTEPG (
    channel_id varchar(100) NOT NULL default '',
    nexttime datetime NOT NULL default '0000-00-00 00:00:00'
    )
|);
    # Remove old data
    $obj->{dbh}->do('delete from NEXTEPG');

    # Get channelid and starttime of next broadcasting
    $obj->{dbh}->do(qq|
INSERT INTO NEXTEPG select
    c.Id as channel_id,
    MIN(e.starttime) as nexttime
    FROM EPG as e, CHANNELS as c
    WHERE e.channel_id = c.Id
AND UNIX_TIMESTAMP(e.starttime) > UNIX_TIMESTAMP(NOW())
GROUP BY c.Id
|);

    my $sql =
qq|
select
    e.eventid as Service,
    e.title as Title,
    e.subtitle as __Subtitle,
    c.Name as Channel,
    c.POS as __POS,
    g.Name as __Channelgroup,
    DATE_FORMAT(e.starttime, "%H:%i") as Start,
    DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(starttime) + e.duration), "%H:%i") as Stop,
    999 as Percent,
    e.description as __Description
FROM
    EPG as e, CHANNELS as c, NEXTEPG as n, CHANNELGROUPS as g
WHERE
    e.channel_id = c.Id
    AND n.channel_id = c.Id
    AND c.GRP = g.Id
    AND e.starttime = n.nexttime
ORDER BY
    c.POS|;
    my $fields = fields($obj->{dbh}, $sql);

    my $erg = $obj->{dbh}->selectall_arrayref($sql);
    unshift(@$erg, $fields);

    my $tim = main::getModule('TIMERS');

    $console->table($erg,
        {
            timers => $tim->getEpgIds,
            periods => $obj->{periods},
        }
    );
}

# ------------------
sub runningNow {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $watcher = shift || return error ('No Watcher!');
    my $console = shift || return error ('No Console');
    my $zeit = shift || '';

    if(int($zeit) < 24) {
        $zeit   = UnixDate(ParseDate($zeit),"%s") || time;
    }

    $zeit += 86400 if($zeit < time);
    $zeit++;

    my $sql =
qq|
select
    e.eventid as Service,
    e.title as Title,
    e.subtitle as __Subtitle,
    c.Name as Channel,
    c.POS as __POS,
    g.Name as __Channelgroup,
    DATE_FORMAT(e.starttime, "%H:%i") as Start,
    DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(starttime) + e.duration), "%H:%i") as Stop,
    (unix_timestamp(e.starttime) + e.duration - unix_timestamp())/e.duration*100 as Percent,
    e.description as __Description
FROM
    EPG as e, CHANNELS as c, CHANNELGROUPS as g
WHERE
    e.channel_id = c.Id
    AND c.GRP = g.Id
    AND $zeit BETWEEN UNIX_TIMESTAMP(e.starttime)
    AND (UNIX_TIMESTAMP(e.starttime) + e.duration)
ORDER BY
    c.POS|;
#dumper($sql);
    my $fields = fields($obj->{dbh}, $sql);

    my $erg = $obj->{dbh}->selectall_arrayref($sql);
    unshift(@$erg, $fields);

    my $tim = main::getModule('TIMERS');
    $console->table($erg,
        {
            timers => $tim->getEpgIds,
            zeit => $zeit,
            periods => $obj->{periods},
        }
    );
}

# ------------------
sub NowOnChannel {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $channel = shift || return error('No Channel!');
    my $zeit = time;

    my $sql =
qq|
select
    e.eventid as Service,
    e.title as Title,
    e.subtitle as Subtitle,
    c.Name as Channel,
    c.POS as POS,
    e.description as Description
FROM
    EPG as e, CHANNELS as c
WHERE
    e.channel_id = c.Id
    AND $zeit BETWEEN UNIX_TIMESTAMP(e.starttime)
    AND (UNIX_TIMESTAMP(e.starttime) + e.duration)
    AND c.POS = $channel
ORDER BY
    starttime
LIMIT 1
|;
#dumper($sql);
    my $erg = $obj->{dbh}->selectrow_hashref($sql);

    return $erg;
}

# ------------------
sub schema {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $watcher = shift || return error ('No Watcher!');
    my $console = shift || return error ('No Console');
    my $zeitvon = $obj->toFullHour(shift || time);
    my $param   = shift || {};
    my $zeitbis = $zeitvon + ($obj->{timeframe}*3600);
    my $cgroups = main::getModule('CHANNELS')->ChannelGroupsArray('Name');
    my $cgrp    = $param->{cgrp} || $cgroups->[0][1]; # Erster GroupEintrag

    my $sql =
qq|
select
    e.eventid as Service,
    e.title as Title,
    e.subtitle as __Subtitle,
    c.Name as Channel,
    c.POS as __POS,
    DATE_FORMAT(e.starttime, "%H:%i") as Start,
    DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(starttime) + e.duration), "%H:%i") as Stop,
    (unix_timestamp(e.starttime) + e.duration - unix_timestamp())/e.duration*100 as Percent,
    e.description as __Description,
    UNIX_TIMESTAMP(starttime) as second_start,
    UNIX_TIMESTAMP(starttime) + e.duration as second_stop
FROM
    EPG as e, CHANNELS as c
WHERE
    e.channel_id = c.Id
    AND
    (
        ( UNIX_TIMESTAMP(e.starttime) >= $zeitvon AND UNIX_TIMESTAMP(e.starttime) <= $zeitbis )
        OR
        ( UNIX_TIMESTAMP(e.starttime) + e.duration >= $zeitvon AND UNIX_TIMESTAMP(e.starttime) + e.duration <= $zeitbis )
        OR
        ( UNIX_TIMESTAMP(e.starttime) <= $zeitvon AND UNIX_TIMESTAMP(e.starttime) + e.duration >= $zeitbis )
    )
    AND
    c.GRP = $cgrp
ORDER BY
    c.POS,e.starttime
|;

    my $fields = fields($obj->{dbh}, $sql);

    my $erg = $obj->{dbh}->selectall_arrayref($sql);

    my $data = {};
    foreach my $c (@$erg) {
        push(@{$data->{$c->[4]}}, $c);
    }

    my $tim = main::getModule('TIMERS');
    $console->table($data,
        {
            timers => $tim->getEpgIds,
            runningTimer => $tim->getRunningTimer,
            zeitvon => $zeitvon,
            zeitbis => $zeitbis,
            periods => $obj->{periods},
            cgroups => $cgroups,
            channelgroup => $cgrp,
        }
    );
}

# ------------------
sub checkOnTimer {
# ------------------
    my $obj = shift  || return error ('No Object!' );
    my $watcher = shift || return error ('No Watcher!');
    my $console = shift || return error ('No Console');
    my $eid = shift  || return error('No Id');
    my $tim = main::getModule('TIMERS');

    my $sql = qq|
SELECT
    e.starttime as NextStartTime,
    ADDDATE(e.starttime, INTERVAL e.duration SECOND) as NextStopTime,
    LEFT(c.Source,1) as source,
    c.TID as transponderid
FROM
    EPG as e, CHANNELS as c
WHERE
    e.eventid = $eid
    and
    e.channel_id = c.Id
|;
    my $data = $obj->{dbh}->selectrow_hashref($sql)
        or return error('fehler:'.$obj->{dbh}->err);
    my $erg = $tim->checkOverlapping($data) || ['ok'];
    $console->message(join(',',@$erg))
        if(ref $console);

}

# ------------------
sub toFullHour {
# ------------------
    my $obj = shift  || return error ('No Object!' );
    my $zeit = shift || return error ('No Time to convert!' );

    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
                                             localtime($zeit);
    my $retzeit = timelocal(0, 0, $hour, $mday, $mon, $year);
    return $retzeit;
}


# ------------------
sub getId {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $id = shift || return error ('No Id!' );
    my $erg = $obj->{dbh}->selectrow_hashref(sprintf('select * from EPG WHERE eventid = %lu', $id), 'eventid')
        or return error("No Event to load");
    return $erg;
}

1;
