#!/usr/bin/perl -w

use Emcast::Handler;
use Net::IRC;


####################

my $debug = 0;

my $handler;
my $irc;
my $conn;

my $irc_server;
my $irc_port;
my $irc_nick;
my $irc_channel;

$SIG{"INT"} = 'on_sigint';

$handler = new Emcast::Handler(\*STDIN, \*STDOUT);
$handler->handle_loopback(1);
$handler->join   (\&on_emcast_join);
$handler->leave  (\&on_emcast_leave);
$handler->send   (\&on_emcast_send);

$irc = new Net::IRC;
$irc->addfh (fileno(STDIN), \&on_stdin, "re");
$irc->start();


########################################

sub on_sigint
{
    $SIG{'INT'} = 'DEFAULT';

    exit 0 if (!defined($conn));

    $conn->quit();
    exit 0;
}

sub on_stdin
{
    my $rv;
    $rv = $handler->loop_once();
    exit 1 if $rv;
}


sub on_emcast_join
{
    my ($url) = @_;

    return 1 if defined($conn);

    if ($url =~ /^irc:([^\@]+)\@([^:]+):(\d+)\/(.*)/) # port
    {
	$irc_port = int($3);
	$irc_channel = $4;
    }
    elsif ($url =~ /^irc:([^\@]+)\@([^\/]+)\/(.*)/) # no port
    {
	$irc_port = 6667;
	$irc_channel = $3;
    }
    else
    {
	return 1;
    }

    $irc_nick = $1;
    $irc_server = $2;
    $irc_channel = '#' . $irc_channel if ($irc_channel !~ /^[\&\#]/);

    print STDERR "emcast_join $irc_nick $irc_channel $irc_server $irc_port\n" if $debug;

    $conn = $irc->newconn(Server   => $irc_server,
			  Port     => $irc_port,
			  Nick     => $irc_nick)
	or return 1;

    $conn->add_handler (376,          \&on_irc_connect);
    $conn->add_handler (433,          \&on_irc_nick_taken);
    $conn->add_handler ('cping',      \&on_irc_cping);
    $conn->add_handler ('cversion',   \&on_irc_cversion);
    $conn->add_handler ('msg',        \&on_irc_msg);
    $conn->add_handler ('public',     \&on_irc_public);
    $conn->add_handler ('disconnect', \&on_irc_disconnect);
    $conn->add_handler ('kill',       \&on_irc_kill);

    return 0;
}


sub on_emcast_leave
{
    print STDERR "emcast_leave\n" if $debug;

    return 0 if !defined($conn);
    $conn->disconnect();
    $conn = undef;

    return 0;
}


sub on_emcast_send
{
    my ($buf, $len) = @_;

    print STDERR "emcast_send\n" if $debug;

    return 1 if !defined($conn);
    $conn->privmsg ($irc_channel, $buf);
    # TODO: Optionally convert buf to ASCII

    return 0;
}



####################

sub on_irc_connect 
{
    my $self = shift;
	
    $self->join($irc_channel);
}


sub on_irc_nick_taken 
{
    my ($self) = shift;

    $nick = $nick . "_";
    $self->nick($nick);
}


sub on_irc_cping 
{
    my ($self, $event) = @_;
    my $nick = $event->nick;

    $self->ctcp_reply($nick, join (' ', ($event->args)));
}


sub on_irc_cversion 
{
    my ($self, $event) = @_;
    my $nick = $event->nick;
  
    $self->ctcp_reply($nick, "emcast irc handler");
}


sub on_irc_msg
{
    my ($self, $event) = @_;
    my ($nick) = $event->nick;
    my ($text) = $event->args;

    my $buf = "($nick) $text\n";
    my $len = length($buf);

    $handler->recv ($buf, length($buf), $nick, length($nick)) == $len 
	or exit 1;
}


sub on_irc_public 
{
    my ($self, $event) = @_;
    my ($nick, $mynick) = ($event->nick, $self->nick);
    my ($text) = $event->args;

    my $buf = "<$nick> $text\n";
    my $len = length($buf);

    $handler->recv ($buf, length($buf), $nick, length($nick)) == $len 
	or exit 1;
}


sub on_irc_disconnect 
{
    my ($self, $event) = @_;

    $self->connect(Server   => $irc_server,
		   Port     => $irc_port,
		   Nick     => $irc_nick);
    while ($self->error())
    {
	sleep 60;
	$self->connect(Server   => $irc_server,
		       Port     => $irc_port,
		       Nick     => $irc_nick);
    }
}


sub on_irc_kill
{
    exit 1;
}

