# VoteBot 0.1 for SILC
# Copyright (c) 2002 by Shahbaz Javeed
# License: GPL
#
use GDBM_File;
use Text::DoubleMetaphone qw( double_metaphone );
use Irssi;

######## User configuration section #######
$voteDBM = '/home/sjaveed/.silc/voteDefinitions.dbm';
$voteOptionsDBM = '/home/sjaveed/.silc/voteOptionsDefinitions.dbm';
$adminNicks = 'Phobix BlackAdr';
###########################################

use vars qw($VERSION %IRSSI);

$VERSION = "0.2.5";
%IRSSI = (
        authors     => "Shahbaz Javeed",
        contact     => "sjaveed\@adderpit.com",
        name        => "VoteBot",
	description => "Allows a channel to setup and cast votes on a SILC channel",
        license     => "GPLv2",
        url         => "http://www.adderpit.com/~sjaveed",
    );

######## Global Hash to store voting in ####
%votesHash = ();
%voteOptHash = ();
$voteBotVersion = "$IRSSI{name} $VERSION";
###########################################

######## Prep the database ################
my $failure = 0;
tie %voteHash, 'GDBM_File', $voteDBM, &GDBM_File::GDBM_WRCREAT, 0640;
tie %voteOptHash, 'GDBM_File', $voteOptionsDBM, &GDBM_File::GDBM_WRCREAT, 0640;

Irssi::print ("WARNING! $voteDBM could NOT be opened!  All calcs in this session will be TEMPORARY!") if ($failure);
###########################################

sub cmd_commandDispatcher {
	my ($server, $data, $nick, $mask, $target) = @_;

	if ($data =~ /^\s*!vote\s+(cast|close|create|createuserballot|delete|open|option|reset|test) / || $data =~ /^\s*vote\s+(count|match|show|tally) / || $data =~ /^\s*&vote\s+(showvotes) / || $data =~ /^\s*vote\s+(help|faq)\s*/ || $data =~ /^\s*vote\s+(list)$/) {
		my $command = $1;
		my @results;

		if ($command eq 'cast') {
			@results = handleVoteCast ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'close') {
			@results = handleVoteClose ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'count') {
			@results = handleVoteTally ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'create') {
			@results = handleVoteCreate ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'createuserballot') {
			@results = handleVoteCreateUser ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'delete') {
			@results = handleVoteDelete ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'faq') {
			@results = handleVoteFAQ ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'help') {
			@results = handleVoteHelp ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'list') {
			@results = handleVoteList ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'match') {
			@results = handleVoteMatch ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'open') {
			@results = handleVoteOpen ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'option') {
			@results = handleVoteOption ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'reset') {
			@results = handleVoteReset ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'show') {
			@results = handleVoteShow ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'showvotes') {
			@results = handleVoteShowVotes ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'tally') {
			@results = handleVoteTally ($server, $data, $nick, $mask, $target);
		} elsif ($command eq 'test') {
			@results = handleVoteTest ($server, $data, $nick, $mask, $target);
		}

		foreach my $result (@results) {
			if ($result ne '') {
				if ($target ne '') {
					$result = 'MSG -channel '."$target $result";
				} else {
					$result = 'MSG -nick '."$nick $result";
				}
		
				$server -> command ($result);
			}
		}
	}
}
   

sub cmd_selfVote {
	my ($server, $data, $target) = @_;
	return cmd_commandDispatcher($server, $data, $server->{nick}, "", $target);
}


sub handleVoteCast {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*!vote\s+cast +//;
	my ($voteName, $optionName) = split / /, $msg, 2;
	$voteName = lc $voteName;

	my $result;

	if (exists $voteHash {$voteName}) {
		$voteHash {$voteName} =~ /^([^ ]+) (0|1) (.*)$/;
		my ($author, $status, $description) = ($1, $2, $3);

		if ($status) {
			if (exists $voteOptHash {$voteName.'_option_'.$optionName}) {
				if ($voteOptHash {$voteName.'_votes'} =~ /$nick/) {
					$result = "You have already cast a vote in this ballot";
				} else {
					$voteOptHash {$voteName.'_votes'} .= ' ' if (exists $voteOptHash {$voteName.'_votes'});
					$voteOptHash {$voteName.'_votes'} .= $nick;
					$voteOptHash {$voteName.'_vote_'.$optionName} .= ' ' if (exists $voteOptHash {$voteName.'_vote_'.$optionName});
					$voteOptHash {$voteName.'_vote_'.$optionName} .= $nick;

					$result = "Vote cast for Option $optionName";
				}
			} else {
				$result = "Option $optionName does not exist in Ballot $voteName.  Please choose from among the following options: ";
				my @validOptions = split / /, $voteOptHash {$voteName.'_options'};
				my $validOptList = join ', ', $validOptions;
				$result .= $validOptList;
			}
		} else {
			$result = "Ballot $voteName is currently closed.  You may only cast a vote on open ballots";
		}
	} else {
		$result = "Ballot $voteName not found";
	}
	
	return $result;
}


sub handleVoteClose {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*!vote\s+close +//;
	my ($voteName) = $msg;
	$voteName = lc $voteName;

	my $result;

	if (exists $voteHash {$voteName}) {
		$voteHash {$voteName} =~ /^([^ ]+) (0|1) (.*)$/;
		my ($author, $status, $description) = ($1, $2, $3);

		if ($author eq $nick || $adminNicks =~ /\b$nick\b/i) {
			if ($status) {
				$voteHash {$voteName} = "$author 0 $description";
				$result = "Ballot $voteName is now closed for public voting";
			} else {
				$result = "Ballot $voteName is already closed for public voting";
			}
		} else {
			$result = "Only $author can close this ballot";
		}
	} else {
		$result = "Ballot $voteName not found";
	}

	return $result;
}


sub handleVoteCreate {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*!vote\s+create +//;
	my ($voteName, $voteDesc) = split / /, $msg, 2;
	$voteName = lc $voteName;

	my $result = "Created Vote: $voteName ($voteDesc)";

	if ($voteName) {
		if (exists $voteHash {$voteName}) {
			$result = "A ballot by that name ($voteName) already exists.  Please use another name";
		} else {
			# Format: Creator <space> Status <space> Description
			$voteHash {$voteName} = "$nick 0 $voteDesc";
		}
	} else {
		$result = "Syntax: vote create <vote.name> <vote description>";
	}

	return $result;
}


sub handleVoteCreateUser {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*!vote\s+createuserballot +//;
	my ($voteName, $voteDesc) = split / /, $msg, 2;
	$voteName = lc $voteName;

	my $result = "Created User Vote: $voteName ($voteDesc)";

	if ($voteName) {
		if (exists $voteHash {$voteName}) {
			$result = "A user ballot by that name ($voteName) already exists.  Please use another name";
		} else {
			# Format: Creator <space> Status <space> Description
			$voteHash {$voteName} = "$nick 0 $voteDesc";

			$voteOptHash {$voteName.'_options'} .= "yes no abstain";
			foreach my $opt (qw(yes no abstain)) {
				$voteOptHash {$voteName.'_option_'.$opt} = ucfirst $opt;
			}
		}
	} else {
		$result = "Syntax: vote createuserballot <vote.name> <vote description>";
	}

	return $result;
}


sub handleVoteDelete {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*!vote\s+delete +//;
	my ($voteName) = $msg;
	$voteName = lc $voteName;

	my $result;

	if (exists $voteHash {$voteName}) {
		$voteHash {$voteName} =~ /^([^ ]+) (0|1) (.*)$/;
		my ($author, $status, $description) = ($1, $2, $3);

		if ($author ne $nick && $adminNicks !~ /\b$nick\b/i) {
			$result = "Only $author can delete this ballot";
			return $result;
		}

		delete $voteHash {$voteName};
	
		my @options = split / /, $voteOptHash {$voteName.'_options'};
		delete $voteOptHash {$voteName.'_options'};

		foreach my $opt (@options) {
			delete $voteOptHash {$voteName.'_option_'.$opt} if (exists $voteOptHash {$voteName.'_option_'.$opt});
			delete $voteOptHash {$voteName.'_vote_'.$opt} if (exists $voteOptHash {$voteName.'_vote_'.$opt});
		}

		$result = "Ballot $voteName deleted";
	} else {
		$result = "Ballot $voteName not found";
	}

	return $result;
}


sub handleVoteFAQ {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*vote\s+faq *//;
	my $faqNum = $msg;

	my $result;

	my @helpText = ();

	my $headerString = "VoteBot $VERSION Help - Frequently Asked Questions";
	my $numDashes = length $headerString;

	# All help text headers go here ...
	push @helpText, $headerString;
	push @helpText, '-' x $numDashes;
		
	push @helpText, 'Q1. Why is there a ! before some commands and not before others?';
	push @helpText, 'A1. All commands which modify the database (i.e. cast a vote, create/edit/delete a ballot etc) are prefixed by a ! so they are not accidentally typed within normal channel conversations.  All commands that access the database in a readonly manner dont have such a danger and do not have the ! in front of them.';
	push @helpText, ' ';
	push @helpText, 'Q2. How do I create a ballot so people can vote on whether or not to invite a user to the channel?';
	push @helpText, 'A2. The list of commands you need are: !vote createuserballot <nick> <description>.  Then, !vote open <nick>.';
	push @helpText, 'Q3. How do I cast a vote for a user when a ballot is already created and opened for him/her?';
	push @helpText, 'A3. For the specific case of a ballot created using the createuserballot command, the commands you can use are: !vote cast <nick> yes OR !vote cast <nick> no OR !vote cast <nick> abstain';

	push @helpText, '=' x $numDashes;
	
	foreach my $helpLine (@helpText) {
		$server -> command ('MSG -nick '."$nick $helpLine");
	}

	return $result;
}


sub handleVoteHelp {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*vote\s+help *//;
	$helpCmd = lc $msg;

	my $result;
	my @helpText;

	if ($helpCmd eq '') {
		push @helpText, "VoteBot $VERSION by BlackAdr";
		push @helpText, "VoteBot Command List: cast, close, count, create, createuserballot, delete, faq, help, list, match, open, option, show, tally";
		push @helpText, '-' x 80;
		push @helpText, 'All commands can be issued in public (on the channel) or in private (by messaging the VoteBot)';
		push @helpText, 'Generally, all VoteBot commands follow the structure: vote <command> <parameters>.  Some commands use !vote instead of vote.  These differences are explained in the FAQ';
		push @helpText, 'To get extended help on any one command, use "vote help <command>" without the quotes';
		push @helpText, 'A FAQ for VoteBot is also available by typing "vote faq" without the quotes.  Be warned that this _might_ be long, depending on how many entries exist in it';
	} else {
		my $headerString = "VoteBot $VERSION Help - $helpCmd";
		my $numDashes = length $headerString;

		# All help text headers go here ...
		push @helpText, $headerString;
		push @helpText, '-' x $numDashes;
		
		if ($helpCmd =~ /^cast/) {
			push @helpText, 'Syntax: !vote cast <ballot.name> <optionNum>';
			push @helpText, 'Summary: Used to cast a vote in the ballot ballot.name.  This only works if the ballot has been opened by the ballot creator using vote open.';
		} elsif ($helpCmd =~ /^close/) {
			push @helpText, 'Syntax: !vote close <ballot.name>';
			push @helpText, 'Summary: Used to close a ballot for public voting.  After this, no more votes may be cast in that ballot.';
		} elsif ($helpCmd =~ /^count/) {
			push @helpText, 'Syntax: vote count <ballot.name> ]';
			push @helpText, 'Summary: See vote tally';
		} elsif ($helpCmd =~ /^create/) {
			push @helpText, 'Syntax: !vote create <ballot.name> [<ballot description>]';
			push @helpText, 'Summary: Used to create a ballot.  A ballot description is optional.  A ballot is created with no options initially.  Use vote option to add options and vote open to open it to the public.';
		} elsif ($helpCmd =~ /^createuserballot/) {
			push @helpText, 'Syntax: !vote createuserballot <user.name> [<ballot description>]';
			push @helpText, 'Summary: This option is used specifically to create a ballot for voting on a user.  When used like so: "vote createuserballot test", it will create a ballot called test that automatically contains the options for Yes, No and Abstain.  You must still use vote open to open the ballot for public voting.';
		} elsif ($helpCmd =~ /^delete/) {
			push @helpText, 'Syntax: !vote delete <ballot.name>';
			push @helpText, 'Summary: Used to permanently delete a ballot and all associated options and votes from the bot.  Use with care.';
		} elsif ($helpCmd =~ /^faq/) {
			push @helpText, 'Syntax: vote faq';
			push @helpText, 'Summary: Gives a list of frequently asked questions (FAQ) with answers.';
		} elsif ($helpCmd =~ /^help/) {
			push @helpText, 'Syntax: vote help [<command>]';
			push @helpText, 'Summary: Gives a summary help screen if called without an optional command.  Otherwise, gives extended help for the command asked for.  E.g. vote help createuserballot';
		} elsif ($helpCmd =~ /^list/) {
			push @helpText, 'Syntax: vote list';
			push @helpText, 'Summary: Shows all currently open ballots.  These are ballots that can be voted in.  To list all ballots, use vote match instead.';
		} elsif ($helpCmd =~ /^match/) {
			push @helpText, 'Syntax: vote match <regex>';
			push @helpText, 'Summary: Shows all ballots (open or closed) that match the given regex.  vote match * will list all ballots in the database';
		} elsif ($helpCmd =~ /^open/) {
			push @helpText, 'Syntax: !vote open <ballot.name>';
			push @helpText, 'Summary: Used by the creator of a ballot to open it to the public for voting.';
		} elsif ($helpCmd =~ /^option/) {
			push @helpText, 'Syntax: !vote option <ballot.name> <optionNum> <optionDesc>';
			push @helpText, 'Summary: Used by the ballot creator to add/replace an option in the ballot.  E.g. vote option testing 1 Yes';
		} elsif ($helpCmd =~ /^show/) {
			push @helpText, 'Syntax: vote show <ballot.name>';
			push @helpText, 'Summary: Used to show details of the named ballot';
		} elsif ($helpCmd =~ /^tally/) {
			push @helpText, 'Syntax: vote tally <ballot.name>';
			push @helpText, 'Summary: Used to show a count of all votes broken down by option in the named ballot';
		} else {
			push @helpText, "No Help Available for $helpCmd";
		}

		push @helpText, '=' x $numDashes;
	}

	foreach my $helpLine (@helpText) {
		$server -> command ('MSG -nick '."$nick $helpLine");
	}

	return $result;
}


sub handleVoteList {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*vote\s+list +//;
	$voteName = lc $voteName;

	my $result;

	my @openVotes;
	foreach my $voteName (sort keys %voteHash) {
		push @openVotes, $voteName if ($voteHash {$voteName} =~ /^[^ ]* 1 /);
	}

	$result = "Voting is currently open for: ";
	if ($#openVotes < 0) {
		$result .= 'None';
	} else {
		$result .= (join ', ', @openVotes);
	}
	
	return $result;
}


sub handleVoteMatch {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*vote\s+match +//;
	my ($voteKey) = $msg;
	$voteKey = lc $voteKey;

	my $result;

	$voteKey =~ s/\*/.*/g;
	my @voteList = sort keys %voteHash;
	my @matchingVoteList = grep {/^$voteKey$/} @voteList;

	$result = "Ballots found: ";
	
	if ($#matchingVoteList < 0) {
		$result .= 'None';
	} else {
		$result .= (join ', ', @matchingVoteList);
	}

	return $result;
}


sub handleVoteOpen {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*!vote\s+open +//;
	my $voteName = $msg;
	$voteName = lc $voteName;

	my $result;

	if (exists $voteHash {$voteName}) {
		$voteHash {$voteName} =~ /^([^ ]+) (0|1) (.*)$/;
		my ($author, $status, $description) = ($1, $2, $3);

		if ($author eq $nick || $adminNicks =~ /\b$nick\b/i) {
			if ($status) {
				$result = "Ballot $voteName is already open for public voting";
			} else {
				$voteHash {$voteName} = "$author 1 $description";
				$result = "Ballot $voteName is now open for public voting";
			}
		} else {
			$result = "Only $author can open this ballot for public voting";
		}
	} else {
		$result = "Ballot $voteName not found";
	}
	
	return $result;
}


sub handleVoteOption {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*!vote\s+option +//;
	my ($voteName, $optionNum, $optionDesc) = split / /, $msg, 3;
	$voteName = lc $voteName;

	my $result = "%s option $optionNum (Total now: %d): $optionDesc";
	
	if (exists $voteHash {$voteName}) {
		$voteHash {$voteName} =~ /^([^ ]+) (0|1) (.*)$/;
		my ($author, $status, $description) = ($1, $2, $3);

		# Check whether this is the author of the vote.
		# If not, deny access to this functionality.
		return "Only $author is allowed to add options to this ballot." unless ($author eq $nick || $adminNicks =~ /\b$nick\b/i);

		my $optionUpdate = 'Added';
		if (exists $voteOptHash {$voteName.'_option_'.$optionNum}) {
			$optionUpdate = 'Updated';
		} else {
			if (exists $voteOptHash {$voteName.'_options'}) {
				$voteOptHash {$voteName.'_options'} .= " $optionNum";
			} else {
				$voteOptHash {$voteName.'_options'} = $optionNum;
			}
		}

		$voteOptHash {$voteName.'_option_'.$optionNum} = $optionDesc;

		my @options = split / /, $voteOptHash {$voteName.'_options'};
		my $optionCount = $#options + 1;

		my $resultTemplate = $result;
		$result = sprintf $resultTemplate, $optionUpdate, $optionCount;
	} else {
		$result = "Ballot $voteName not found";
	}

	return $result;
}


sub handleVoteReset {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*!vote\s+reset +//;
	my ($voteName) = $msg;
	$voteName = lc $voteName;

	my $result;

	if (exists $voteHash {$voteName}) {
		$voteHash {$voteName} =~ /^([^ ]+) (0|1) (.*)$/;
		my ($author, $status, $description) = ($1, $2, $3);

		if ($author ne $nick && $adminNicks !~ /\b$nick\b/i) {
			$result = "Only $author can reset this ballot";
			return $result;
		}

		my @options = split / /, $voteOptHash {$voteName.'_options'};

		foreach my $opt (@options) {
			delete $voteOptHash {$voteName.'_vote_'.$opt} if (exists $voteOptHash {$voteName.'_vote_'.$opt});
		}

		$result = "Ballot $voteName reset";
	} else {
		$result = "Ballot $voteName not found";
	}

	return $result;
}


sub handleVoteShow {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*vote\s+show +//;
	my $voteName = $msg;
	$voteName = lc $voteName;

	my $result;

	if (exists $voteHash {$voteName}) {
		$voteHash {$voteName} =~ /^([^ ]+) (0|1) (.*)$/;
		my ($author, $status, $description) = ($1, $2, $3);

		my @options = split / /, $voteOptHash {$voteName.'_options'};
		my $optionCount = $#options + 1;
		
		$result = "Ballot: $voteName (";
		$result .= $description;

		if ($optionCount > 0) {
			$result .= ") Options: ";

			foreach my $opt (@options) {
				$result .= "($opt) ";
				$result .= $voteOptHash {$voteName.'_option_'.$opt};
				$result .= ", ";
			}
		} else {
			$result .= ") Options: None";
		}
	} else {
		$result = "Ballot $voteName not found";
	}
	
	return $result;
}


sub handleVoteShowVotes {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*&vote\s+showvotes +//;
	my @voteNames = split / /, $msg;
	$voteName = lc $voteName;

	my $result;

	foreach my $voteName (@voteNames) {
		if (exists $voteHash {$voteName}) {
			$voteHash {$voteName} =~ /^([^ ]+) (0|1) (.*)$/;
			my ($author, $status, $description) = ($1, $2, $3);

			my @options = split / /, $voteOptHash {$voteName.'_options'};
			my $optionCount = $#options + 1;
			my @totalVotes = split / /, $voteOptHash {$voteName.'_votes'};
			my $voteCount = $#totalVotes + 1;
			my $voterList = join ', ', @totalVotes;
		
			$result = "Ballot: $voteName (";
			$result .= $description;

			if ($optionCount > 0 || $voteCount > 0) {
				$result .= ") Votes: ";

				foreach my $opt (@options) {
					$result .= $voteOptHash {$voteName.'_option_'.$opt}." ";
					my @votes = split / /, $voteOptHash {$voteName.'_vote_'.$opt};
					$totalVotes += $#votes + 1;
					$result .= "[ ".($#votes + 1)." ]";
					$result .= ", ";
				}

				$result .= " Voter List: $voterList";
			} else {
				$result .= ") Votes: None";
			}
		} else {
			$result = "Ballot $voteName not found";
		}
	}

	return $result;
}


sub handleVoteTally {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*vote\s+(tally|count) +//;

	my @voteNames;

	if ($msg eq '*') {
		foreach my $voteName (sort keys %voteHash) {
			push @voteNames, $voteName if ($voteHash {$voteName} =~ /^[^ ]* 1 /);
		}
	} else {
		@voteNames = split / /, $msg;
	}

	my @results;

	foreach my $voteName (@voteNames) {
		my $result;
		if (exists $voteHash {$voteName}) {
			$voteHash {$voteName} =~ /^([^ ]+) (0|1) (.*)$/;
			my ($author, $status, $description) = ($1, $2, $3);

			my @options = split / /, $voteOptHash {$voteName.'_options'};
			my $optionCount = $#options + 1;
			my @totalVotes = split / /, $voteOptHash {$voteName.'_votes'};
			my $voteCount = $#totalVotes + 1;
		
			$result = "Ballot: $voteName (";
			$result .= $description;

			if ($optionCount > 0 || $voteCount > 0) {
				$result .= ") Votes: ";
	
				foreach my $opt (@options) {
					$result .= $voteOptHash {$voteName.'_option_'.$opt}." ";
					my @votes = split / /, $voteOptHash {$voteName.'_vote_'.$opt};
					$totalVotes += $#votes + 1;
					$result .= "[ ".($#votes + 1)." ]";
				}
			} else {
				$result .= ") Votes: None";
			}
		} else {
			$result = "Ballot $voteName not found";
		}

		push @results, $result;
	}

	return @results;
}


sub handleVoteTest {
	my ($server, $data, $nick, $mask, $target) = @_;

	my ($msg, $result) = ($data, '');
	$msg =~ s/^\s*!vote\s+test +//;

	my $result;

	$result = "Server: $server, Data: $data, Nick: $nick, Mask: $mask, Target: $target";

	my $channels = $server->channels();
	foreach my $channel (sort keys %{$channels}) {
		Irssi::print "    $channel => $channels->{$channel}";
	}
	
	foreach my $key (sort keys %{$server}) {
		Irssi::print "  $key => $server->{$key}";
	}

	return $result;
}


Irssi::signal_add_last('message public', 'cmd_commandDispatcher');
Irssi::signal_add_last('message private', 'cmd_commandDispatcher');
Irssi::signal_add_last('message own_public', 'cmd_selfVote');

Irssi::print("VoteBot $VERSION loaded.");
