#!/usr/bin/perl

# uses
use Net::AIM;
use DBI;

# setup
my $nick = "menowbot";
my $pass = "menowmenow";
my $aim = new Net::AIM;
my $version = "0.2";
$aim->debug(1);

my $conn = $aim->newconn(Screenname => $nick,
        Password   => $pass);

# variables
my $dbh;

$dsn = "DBI:mysql:test;localhost";
$dbh = DBI->connect($dsn, 'root', 'rand0m');
die "error: no database" unless $dbh;

# do it!
sub on_im {
    my $self = shift;
    my $event = shift;

    my ($from, $flag, $msg) = @{$event->{'args'}};

    $from = lc($from);

    $msg =~ s/\<[^>]+\>//g;

    handle_user_input($from, $msg);
}

my $aconn = $aim->getconn();
$aconn->set_handler('im_in', \&on_im);
my $aconn = $aim->getconn();
$aconn->set_handler('im_in', \&on_im);

print "Starting aim...\n";
$aim->start;

print "Starting aim...\n";
$aim->start;

###############################################################################################################################
sub handle_user_input {
    my ($nick, $text) = @_;
    my $res;
    if ($text =~ m/add\s+(.*?)\s+(.*?)$/) {
        $res = pred_add($nick, $text, $1, $2);
    }
    elsif ($text =~ m/forget\s+(.*?)$/) {
        $res = forget_routine($nick, $text, $1);
    }
    elsif ($text =~ m/(.*?)\s+now\?*$/) {
        $res = other_menow($1);
    }
    elsif ($text =~ m/\s*menow\?*$/) {
        $res = self_menow($nick);
    }
    elsif ($text =~ m/alias (.*?)$/) {
        $res = alias($nick, $1);
    }
    elsif ($text =~ m/recent/) {
        if ($text =~ m/user/) {
            $res = recent_users();
        }
        else {
            $res = recent_pred();
        }
    }
    elsif ($text =~ m/help/) {
        $res = help_routine();
    }
    else {
        $res = else_routine($nick);
    }
    $aim->send_im($nick, $res) if $res;
}

sub pred_add {
    my $ret;
    my %properties = ("iswith" => 2,  "listeningto" => 1,  "located" => 1,  "game" => 1,  "gamingat" => 1,  "gamenick" => 1,  "thinking" => 1,  "mood" => 1,  "moodicon" => 1,  "liking" => 1,  "chatting" => 1,  "browsing" => 1,  "reading" => 1,  "vacation" => 1,  "moblogging" => 1,  "moImage" => 1,  "camimage" => 1,  "status" => 1,  "statusicon" => 1,  "workingOn" => 1,  "writing" => 1,  "planning" => 1,  "watching" => 1);
    my ($nick, $text, $predicate, $object) = @_;
    $nick = $dbh->quote($nick);
    my $type = $dbh->quote($predicate);
    return "$predicate not part of the MeNow Schema, see http://schema.peoplesdns.com/menow/." unless $properties{lc($predicate)};
    $object = $dbh->quote($object);
    $dbh->do("DELETE FROM menow WHERE type=$type AND nick=$nick");
    $dbh->do("INSERT INTO menow (nick, type, object, timestamp) VALUES ($nick, $type, $object, NOW())");
    print "$nick added $object as $type\n";
    $ret = "added $nick menow:$predicate = $object";
    return $ret;

}

sub forget_routine {
    my ($nick, $text, $predicate) = @_;
    my $type = $dbh->quote($predicate);
    my $nick = $dbh->quote($nick);
    $dbh->do("DELETE FROM menow WHERE type=$type AND nick = $nick");
    print "$nick dropped $type\n";
    my $res = "Forgot $nick meNow:$predicate";
    return $res;

}

sub help_routine {
    return "I understand the following commands: add <predicate> " .
        "<object>, forget <predicate>, menow, <nick> now. <nick> is either an " .
        "IRC nickname or an AIM ID. Predicates can be chosen from the MeNow " .
        "schema at http://schema.peoplesdns.com/menow/.";
}
sub else_routine {
    my $nick = shift;
    my $msg = "Hi $nick. I'm a bot which stores 'now' information according " .
        "to the MeNow Schema. This is version $version . Information about " .
        "this bot is available at " .
        "http://crschmidt.net/wordpress/archives/2004/06/01/metadata-the-quick-and-easy-way/ " .
        ". You can contact me at cr5chmidt on AIM or crschmidt on irc.freenode.net if you're " .
        "interested in contributing. For commands, type 'help'.";
    return $msg

}
sub self_menow {
    my $res;
    my $nick = shift;
    my $quotednick = $dbh->quote($nick);
    my $sth = $dbh->prepare("SELECT DISTINCT m.type, m.object, m.timestamp FROM menow m, aliases a WHERE m.nick=$quotednick OR (a.alias = m.nick AND a.nick = $quotednick) ORDER BY timestamp DESC");
    $sth->execute();
    while (($type, $object, $timestamp) = $sth->fetchrow_array()) {
        $res .= "menow:$type = $object at $timestamp  ";
    }
    $res = "$nick : ".$res;
    print "$nick menow printed";
    return $res;

}
sub other_menow {
    my $res;
    my $othernick = shift;
    my $quotednick = $dbh->quote($othernick);
    my $sth = $dbh->prepare("SELECT DISTINCT m.type, m.object, m.timestamp FROM menow m, aliases a WHERE m.nick=$quotednick OR (a.alias = m.nick AND a.nick = $quotednick) ORDER BY timestamp DESC");
    $sth->execute();
    while (($type, $object, $timestamp) = $sth->fetchrow_array()) {
        $res .= "menow:$type = $object at $timestamp  ";
    }
    $res = "$othernick : ".$res;
    print "$othernick menow printed\n";
    return $res;
}
sub recent_users {
   my $res, $nick;
   my $sth = $dbh->prepare("SELECT DISTINCT nick FROM menow ORDER BY timestamp DESC LIMIT 5");
   $sth->execute();
   $res = "Recent participants: ";
   $res .= $nick.", " while ($nick = $sth->fetchrow_array());
   
   return substr($res, 0, length($res)-2);
}

sub recent_pred {
    my $res, $pred;
    my $sth = $dbh->prepare("SELECT DISTINCT type FROM menow ORDER BY timestamp DESC LIMIT 5");
    $sth->execute();
    $res = "Recent predicates: ";
    $res .= $pred.", " while ($pred = $sth->fetchrow_array());

    return substr($res, 0, length($res)-2);

}

sub alias {
    my $res;
    my ($nick, $alias) = @_;
    my $quotedalias = $dbh->quote($alias);
    my $quotednick = $dbh->quote($nick);
    $dbh->do("INSERT INTO aliases (nick, alias, timestamp) VALUES ($quotednick, $quotedalias, NOW())");
    $res = "Aliased $nick to $alias - results for either will be shared on a \"menow\" command.";
    return $res;
    
}

