use Net::IRC;
use Finance::Quote;
use strict;

my $botnick = "StockBot_";
my $defaultchannel = "#wipples";
my $channel = $ARGV[1] || "$defaultchannel";

my $version = "16";

my $q = Finance::Quote->new;
$q->timeout(60);

my $irc = new Net::IRC;
my $conn = $irc->newconn(Server   => ($ARGV[0]  ||  'dingo.vic.au.dal.net'),
			 Port     => 6667,
			 Nick     => $botnick,
			 Ircname  => 'Net::IRC.',
			 Username => 'StockBot')
    or die "Can't connect to IRC server.\n";

sub on_ping {
}

sub on_ping_reply {
}

sub on_msg {
    my ($self, $event) = @_;
    my ($nick) = $event->nick;
    my ($arg) = ($event->args);
    if ($nick == "_aa_") {
	my @args = split(/ /, $arg);
	if ($arg =~ /^join/i) {
	    $self->join($args[1]);
	}
	if ($arg =~ /^part/i) {
	    $self->part($args[1]);
	}
	if ($arg =~ /^nick/i) {
	    $self->nick($args[1]);
	}
	if ($arg =~ /^quit/i) {
	    quit();
	}
    }
    if ($arg =~ /^help/i) {
	help($self, $nick);
    }
    if ($arg =~ /^quote/i) {
	my ($exchange, $verbosity, $subarg, $symbol, @symbols);
	my @args = split(/ /, $arg);
	($exchange, $verbosity, @symbols) = process_args(@args);
	foreach $symbol (@symbols) {
	    quote($self, $nick, $nick, $symbol, $exchange, $verbosity);
	}
    }
}

sub on_chat {
}

sub on_public {
    my ($symbol);
    my ($self, $event) = @_;
    my $target = $event->to;
    my ($nick, $mynick) = ($event->nick, $self->nick);
    my ($arg) = ($event->args);
    if ($arg =~ /^quote/i) {
	my @args = split(/ /, $arg);
	my ($exchange, $verbosity, @symbols) = process_args(@args);
	foreach $symbol (@symbols) {
	    quote($self, $nick, $target, $symbol, $exchange, $verbosity);
	}
    }
    if ($arg =~ /^help/i) {
	help($self, $nick);
    }
}

sub on_action {
}

sub on_join {
}

sub on_part {
}

sub on_dcc {
}

sub on_topic {
}

sub on_init {
}

sub on_connect {
    my $self = shift;
    $self->join($channel);
}

sub on_diconnect {
}

sub on_nick_taken {
}

sub on_names {
}

sub quit {
    exit 0;
}

sub help {
    my ($self, $nick) = @_;
    $self->privmsg($nick, "StockBot Version: $version");
    $self->privmsg($nick, "Usage: /msg $botnick quote [-e exchange] [-v verbosity] SYMBOL[,SYMBOL2,...]");
    $self->privmsg($nick, "Exchanges: austrailia, dwsfunds, fidelity, tiaacref, troweprice, europe, canada, usa (default), nyse, nasdaq, uk_unit_trusts, vanguard, vwd");
    $self->privmsg($nick, "Indexes are prefixed with ^. See http://finance.yahoo.com/l?m=US&s=comp&t=I for available indexes");
}

sub usage {
    my ($self, $nick) = @_;
    $self->privmsg($nick, "StockBot Version: $version '/msg $botnick help' for more help");
    $self->privmsg($nick, "Usage: /msg $botnick quote [-e exchange] [-v verosity] SYMBOL[,SYMBOL2,...]");
}

sub quote {
    my ($self, $nick, $target, $symbol, $exchange, $verbosity) = @_;
    my $netcolor;
    $symbol = process_symbol($symbol);
    my %stock = $q->fetch($exchange,$symbol);
    if ($stock{$symbol,'success'} == 1) {
	if ($stock{$symbol,'net'} =~ /^-/i) {
	    $netcolor = 4;
	}
	elsif ($stock{$symbol,'net'} =~ /^\+/i) {
	    $netcolor = 3;
	}
	if ($verbosity >= 1) {
	    $self->privmsg($target, "[$stock{$symbol,'name'}] Price: $stock{$symbol,'price'} Change: \003" . "$netcolor" . "$stock{$symbol,'net'}\003 Volume: $stock{$symbol,'volume'}");
	}
	if ($verbosity >= 2) {
	    $self->privmsg($target, "[$stock{$symbol,'name'}] 52 Week Range: $stock{$symbol,'year_range'} Today's Range: $stock{$symbol,'day_range'} Last Trade: $stock{$symbol,'date'} $stock{$symbol,'time'}");
	}
	if ($verbosity >= 3) {
	    $self->privmsg($target, "[$stock{$symbol,'name'}] P/E Ratio: $stock{$symbol,'pe'} Earnings Per Share: $stock{$symbol,'eps'} Net Asset Value: $stock{$symbol,'nav'}");
	}
	if ($verbosity >= 4) {
	    $self->privmsg($target, "[$stock{$symbol,'name'}] Debug Info: Method: $stock{$symbol,'method'} Exchange: $stock{$symbol,'exchange'}");
	}
    }
    else {
	$self->privmsg($target, "$symbol: $stock{$symbol,'errormsg'}");
	usage($self, $nick);
    }
}

sub process_symbol {
    my $input_symbol = uc($_[0]);
    my $output_symbol;
    if ($input_symbol eq "NASDAQ") {
	$output_symbol = "^IXIC1";
    }
    elsif ($input_symbol eq "DJIA" or $input_symbol eq "DOWJONES") {
	$output_symbol = "^DJI";
    }
    elsif ($input_symbol eq "S&P") {
	$output_symbol = "^SPTSECP3";
    }
    else {
	$output_symbol = $input_symbol;
    }
    return $output_symbol;
}

sub process_args {
    my ($arg, $count, $param, $exchange, $verbosity, @symbols);
    $count = 0;
    foreach $arg (@_) {
	$param = $count + 1;
	if ($arg eq "-e") {
	    $exchange = $_[$param];
	}
	elsif ($arg eq "-v") {
	    $verbosity = $_[$param];
	    }
	$count = $count + 1;
    }
    my $arg_count = scalar(@_) - 1;
    @symbols = split(/,/, $_[$arg_count]);
    if (!$exchange) {
	$exchange = "usa";
    }
    if (!$verbosity) {
	$verbosity = 1;
    }
    return($exchange, $verbosity, @symbols);
}

$conn->add_handler('cping',  \&on_ping);
$conn->add_handler('crping', \&on_ping_reply);
$conn->add_handler('msg',    \&on_msg);
$conn->add_handler('chat',   \&on_chat);
$conn->add_handler('public', \&on_public);
$conn->add_handler('caction', \&on_action);
$conn->add_handler('join',   \&on_join);
$conn->add_handler('part',   \&on_part);
$conn->add_handler('cdcc',   \&on_dcc);
$conn->add_handler('topic',   \&on_topic);
$conn->add_handler('notopic',   \&on_topic);

$conn->add_global_handler([ 251,252,253,254,302,255 ], \&on_init);
$conn->add_global_handler('disconnect', \&on_disconnect);
$conn->add_global_handler(376, \&on_connect);
$conn->add_global_handler(433, \&on_nick_taken);
$conn->add_global_handler(353, \&on_names);

$irc->start;