package VDR;

our $VERSION = '0.01';

use strict;
use warnings;
use base qw[ Exporter ];

use IO::Handle;

our @KEYS = qw[ kUp kDown kMenu kOk kBack kLeft kRight kRed kGreen kYellow kBlue
                k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 kPlay kPause kStop kRecord 
                kFastFwd kFastRew kPower kChanUp kChanDn kVolUp kVolDn kMute
                kAudio kSchedule kChannels kTimers kRecordings kSetup kCommands
                kUser1 kUser2 kUser3 kUser4 kUser5 kUser6 kUser7 kUser8 kUser9
                kNone kKbd ];

our @STATES = qw[ osUnknown osContinue osSchedule osChannels osTimers
                  osRecordings osPlugin osSetup osCommands osPause osRecord
                  osReplay osStopRecord osStopReplay osCancelEdit osSwitchDvb 
                  osBack osEnd os_User osUser1 osUser2 osUser3 osUser4 osUser5
                  osUser6 osUser7 osUser8 osUser9 osUser10 ];

our @EXPORT_OK = ( @KEYS, @STATES );
our %EXPORT_TAGS = ( keys => [ @KEYS ], states => [ @STATES ] );

no strict 'refs';
foreach my $k (0 ... $#KEYS) { *{"VDR::$KEYS[$k]"} = sub() { $k; }; }
foreach my $s (0 ... $#STATES) { *{"VDR::$STATES[$s]"} = sub() { $s; }; }
use strict 'refs';

sub new {
	if (!defined($VDR::_comm_socket)) {
		if (!defined($VDR::_comm_fileno)) {
			print STDERR "ERROR: Scripts using this module should be started by"
			           . " a scripting host!\n";
			exit(1);
		}
		open($VDR::_comm_socket, "+<&$VDR::_comm_fileno") or do {
			print STDERR "ERROR: Couldn't establish communications: $!\n";
			return undef;
		};
		$VDR::_comm_socket->autoflush(1);
	} 

	my $self = shift;
	my $ref  = ref($self) || $self;

	my $this = bless {}, $ref;
	$this->{_socket} = $VDR::_comm_socket;
	$this->{_callbacks} = {};

	return $this;
}

sub register_callback
{
	my $this = shift;
	my $action = shift;
	my $subref = shift;

	print STDERR "REGISTER CALLBACK $this $action $subref\n";

	$this->{_callbacks}{$action} = $subref;
}

sub unregister_callback
{
	my $this = shift;
	my $action = shift;

	$this->{_callbacks}{$action} = undef;
}

sub send_msg
{
	my $this = shift;
	my $mesg = shift;

	my @args = ();
	ARGS: foreach (@_) {
		my $value;

		if (!defined($_)) {
			push @args, '(nil)';
			next ARGS;
		}
		elsif (ref($_) =~ /^VDR::/) {
			push @args, $_->{_id};
			next ARGS;
		}
		elsif (ref($_) eq 'SCALAR') {
			$value = $$_;
		}
		else {
			$value = $_;
		}

		$value =~ s/\015//g;
		$value =~ s/\n/\\n/gs;
		$value =~ s/'/\\'/g;
		push @args, "'$value'";
	}

	print STDERR "sent: " . join(' ', $mesg, @args) . "\n";
	$this->{_socket}->print(join(' ', $mesg, @args) . "\n");
}

sub recv_msg
{
	my $this = shift;
	my $char = shift;
	my $mesg = readline($this->{_socket});

	print STDERR "received: $mesg";

	return 1 if (!defined($char));
	return $1 if $mesg =~ /^$char ?(.*)$/;
	return undef;
}

"this value intentionally left true";
