package XXV::MODULES::REMOTE;

use strict;

use Tools;
use Locale::gettext;
# This module method must exist for XXV
# ------------------
sub module {
# ------------------
    my $obj = shift || return error ('No Object!' );
    my $args = {
        Name => 'REMOTE',
        Description => gettext('This module emulate a remote control.'),
        Version => '0.01',
        Date => '10.10.2004',
        Author => 'xpix',
        Level => 'user',
        Preferences => {
            active => {
                description => gettext('Activate this service'),
                default     => 'y',
                type        => 'confirm',
                required    => gettext('This is required!'),
            },
            commands => {
                description => gettext('The path to the commands.conf'),
                default     => '/video/commands.conf',
                type        => 'file',
                required    => gettext('This is required!'),
            },
        },
        Commands => {
            remote => {
                description => gettext("Display ir remote 'cmd'"),
                short       => 'r',
                callback    => sub{ $obj->remote(@_) },
                DenyClass   => 'remote',
            },
            switch => {
                description => gettext("Switch to channel 'cid'"),
                short       => 'sw',
                callback    => sub{ $obj->switch(@_) },
                DenyClass   => 'remote',
            },
            command => {
                description => gettext("Call the command 'cid'"),
                short       => 'cmd',
                callback    => sub{ $obj->command(@_) },
                DenyClass   => 'remote',
            },
            cmdlist => {
                description => gettext("List the commands"),
                short       => 'cmdl',
                callback    => sub{ $obj->list(@_) },
                DenyClass   => 'remote',
            },
        },
    };
    return $args;
}

# ------------------
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}};

    # i need the svdrp module
    $self->{svdrp} = main::getModule('SVDRP');

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

	return $self;
}

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

    main::after(sub{
        $obj->{CMDS} = $obj->parse()
        }, "REMOTE: Parse Commandfile ...");

    return 1;
}

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

    return 0
        unless (exists $obj->{commands});

    if(! -r $obj->{commands}) {
        warn (sprintf("can't open file '%s' : %s",$obj->{commands},$!));
        return 0;
    }

    my $cmds = load_file($obj->{commands});

    my $c = 0;
    my $ret = {};
    foreach my $zeile (split("\n", $cmds)) {
        next if($zeile =~ /^\#/);
        my ($cmd, $batch) = split('\s*\:\s*', $zeile);

        $ret->{$c++} = {
            cmd => $cmd,
            bat => $batch,
        } if($cmd and $batch);
    }
    return $ret;
}

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

    my @list = (['__Id', 'Name', 'Cmd']);
    foreach my $id (sort {$a <=> $b} keys %$cmds) {
        push(@list, [$id, $cmds->{$id}->{cmd}, $cmds->{$id}->{bat}]);
    }

    return $console->table(\@list);
}

# ------------------
sub command {
# ------------------
    my $obj = shift  || return error ('No Object!' );
    my $watcher = shift || return error ('No Watcher!');
    my $console = shift || return error ('No Console');
    my $command = shift || return error ('No Command!');
    my $cmds = $obj->parse();

    return $console->err(gettext('This cmd id is not exists!'))
        unless(exists $cmds->{$command});

    $console->message(my $msg = sprintf(gettext('Try to start command: %s with cmd: %s'),
        $cmds->{$command}->{cmd}, $cmds->{$command}->{bat}));

    lg $msg;

    my $out;
    $out .= '<pre>' if($console->typ eq 'HTML');
    open(README, "$cmds->{$command}->{bat} 2>&1 |") or return error("Can't run program: $!");
    while(<README>) {
        $out .= $_;
    }
    close(README);
    $out .= '</pre>' if($console->typ eq 'HTML');
    return $console->message($out);
}


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

    lg sprintf('Call remote with command "%s" from User: %s',
        $command,
        $console->{USER}->{Name}
        );

    unless($command) {
        my $mod = main::getModule('GRAB');
        my $params = {
            width => $mod->{xsize},
            height => $mod->{ysize},
        };
        return $console->remote(undef, $params);
    } else {
        # the svdrp module
        my $svdrp = $obj->{svdrp};

        my $translate = {
            '<' => 'Channel-',
            '>' => 'Channel+',
            '+' => 'Volume+',
            '-' => 'Volume-',
            '>>' => 'FastFwd',
            '<<' => 'FastRew',
            'VolumePlus' => 'Volume+',
            'VolumeMinus' => 'Volume-',
            'Null' => '0',
        };

        $command = $translate->{$command}
            if(exists $translate->{$command});

        # the command
        my $cmd = sprintf('hitk %s', $command);
        my $erg = $svdrp->command($cmd);

        $console->msg($erg, $svdrp->err)
            if(ref $console);
    }
    return 1;
}

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

    lg sprintf('Call switch with channel "%s" from User: %s',
        $channel,
        (ref $console ? $console->{USER}->{Name} : 'unknown')
        );

    # the svdrp module
    my $svdrp = $obj->{svdrp};

    # the command
    my $cmd = sprintf('chan %s', $channel);
    my $erg = $svdrp->command($cmd);

    my ($ret) = $erg->[1] =~ /^\d{3}\s*(.+)/s;

    $console->msg($erg, $svdrp->err)
        if(ref $console);
    $console->redirect({url => $console->{browser}->{Referer}, wait => 1})
        if(ref $console and $console->typ eq 'HTML');


    return $ret;
}

1;
