#########
#
# MootBot - Voting Module
# Copyright 2006,2007 Christopher Oattes, Andrew Williams
#
#########
#
#########
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU Lesser General Public License as published by
#    the Free Software Foundation; either version 2.1 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Lesser General Public License for more details.
#
#    You should have received a copy of the GNU Lesser General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
#########

################################################################################
# DO NOT EDIT DO NOT EDIT DO NOT EDIT  DO NOT EDIT DO NOT EDIT DO NOT EDIT     #
#                         EDIT MOOTBOT_CONFIG.TCL			       #
################################################################################

array set aCountFor {}
array set aCountAgainst {}
array set aVoting {}
array set aVoted {}

bind pub - "+1" pub:plus
bind pub - "-1" pub:minus
bind msg - "+1" msg:plus
bind msg - "-1" msg:minus
bind pubm - "% \[VOTE\]*" pub:vote
bind pubm - "% \[ENDVOTE\]" pub:endvote

proc cleanVoting {chan} {
	global aCountAgainst aCountFor aVoting aVoted
	set aCountAgainst($chan) 0
	set aCountFor($chan) 0
	set aVoting($chan) no
	set aVoted($chan) {}
}

proc isVoting {chan} {
	global aVoting
	if {[info exists aVoting($chan)] && $aVoting($chan)} {
		return 1
	} else { 
		return 0
	}
}

#Used in voting. Adds 1 to FOR
proc pub:plus {nick host hand chan text} {
	global aVoting aCountFor aCountAgainst aVoted

  	if {[meetingInProgress $chan] && $aVoting($chan)} {
		foreach person $aVoted($chan) {
			if { [string equal $nick $person] } {
				return
			}
		} 
		set aCountFor($chan) [expr $aCountFor($chan) + 1]
		lappend aVoted($chan) $nick	
		set count [expr $aCountFor($chan) - $aCountAgainst($chan)]
		putquick "PRIVMSG $chan :+1 received from $nick. $aCountFor($chan) for, $aCountAgainst($chan) against. Count is now $count"
	}
}

#Used in Voting. Subtracts 1 from FOR
proc pub:minus {nick host hand chan text} {
	global aVoting aCountFor aCountAgainst aVoted

  	if {[meetingInProgress $chan] && $aVoting($chan)} {
		foreach person $aVoted($chan) {
			if { [string equal $nick $person] } {
				return
			}
		} 
		set aCountAgainst($chan) [expr $aCountAgainst($chan) + 1]
		lappend aVoted($chan) $nick	
		set count [expr $aCountFor($chan) - $aCountAgainst($chan)]
		putquick "PRIVMSG $chan :-1 received from $nick. $aCountFor($chan) for, $aCountAgainst($chan) against. Count is now $count"
	}
}

#Starts a vote. Can only be used by chair.
proc pub:vote {nick host hand chan text} {
	global aChair aMinutesFile aVoting aCountAgainst aCountFor aVoted aChanLog aChanLogName aAnchorCount

	#Can only be used when not already voting.
  	if {[meetingInProgress $chan] && [string equal $nick $aChair($chan)] && !$aVoting($chan)} {

		set aCountAgainst($chan) 0
		set aCountFor($chan) 0
		set aVoting($chan) yes
		set aVoted($chan) {}

		putquick "PRIVMSG $chan :Please vote on: [string range $text [expr [string first "]" $text] + 1] end]."
		putquick "PRIVMSG $chan :Public votes can be registered by saying +1/-1 in the channel, private votes by messaging +1/-1 and the channel name to MootBot"
		putquick "PRIVMSG $aChair($chan) :Please vote on: [string range $text [expr [string first "]" $text] + 1] end]."

		logWrite 2 $chan "<tr>\n\t"
		logWrite 2 $chan "<td><a href='$aChanLogName($chan)#$aAnchorCount($chan)'>[clock format [clock seconds] -format %H:%M:%S]</a></td>"
	  	logWrite 2 $chan "<td>VOTE</td>"
		logWrite 2 $chan "<td colspan='2' align='center'>[string range $text [expr [string first "]" $text] + 1] end]</td>"
		logWrite 2 $chan "</tr>"

		logWrite 1 $chan "<a name='$aAnchorCount($chan)'></a>"

		set aAnchorCount($chan) [expr $aAnchorCount($chan) + 1]
	} else {
		if {![string equal $nick $aChair($chan)] && [meetingInProgress $chan] } {
			putquick "PRIVMSG $chan :$nick, Only the meeting chair can do that"
		} else {
			putquick "PRIVMSG $chan :$nick, Either there isn't a meeting in progress, or there is already an active vote."
		}
	}
	

}

#Ends a vote. Can only be used by chair.
proc pub:endvote {nick host hand chan text} {
	global aChair aMinutesFile aVoting aCountAgainst aCountFor 
        global voting_time aChanLog aChanLogName aAnchorCount

  	if {[meetingInProgress $chan] && [string equal $nick $aChair($chan)] && [isVoting $chan]} {

		set count [expr $aCountFor($chan) - $aCountAgainst($chan)]

		putquick "PRIVMSG $chan :Final result is $aCountFor($chan) for, $aCountAgainst($chan) against. Total: $count"
		putquick "PRIVMSG $aChair($chan) :Final result is $aCountFor($chan) for, $aCountAgainst($chan) against. Total: $count"

		logWrite 2 $chan "<tr>\n\t"
		logWrite 2 $chan "<td><a href='$aChanLogName($chan)$aAnchorCount($chan)'>[clock format [clock seconds] -format %H:%M:%S]</a></td>"
	  	logWrite 2 $chan "<td>VOTE RESULT</td>"
		logWrite 2 $chan "<td colspan='2' align='center'>$aCountFor($chan) for, $aCountAgainst($chan) against, total: $count</td>"
		logWrite 2 $chan "</tr>"

		logWrite 1 $chan "<a name='$aAnchorCount($chan)'></a>"

		set aAnchorCount($chan) [expr $aAnchorCount($chan) + 1]
		cleanVoting $chan
	}

}

#Used in voting. Adds 1 to FOR
proc msg:plus {nick host hand text} {
	global aVoting aCountFor aCountAgainst aVoted
	set chan [lindex [split $text] 0]

	if {[string index $chan 0] == "#"} {
		if {[onchan $nick $chan]} {
	    		if {[meetingInProgress $chan] && $aVoting($chan)} {
				foreach person $aVoted($chan) {
					if { [string equal $nick $person] } {
						putquick "PRIVMSG $nick :You have already voted on this topic."
						return
					}
				} 
				set aCountFor($chan) [expr $aCountFor($chan) + 1]
				lappend aVoted($chan) $nick	
				set count [expr $aCountFor($chan) - $aCountAgainst($chan)]
				putquick "PRIVMSG $chan :private +1 vote received. $aCountFor($chan) for, $aCountAgainst($chan) against. Count is now $count"	
			}
		} else {
			putquick "PRIVMSG $nick :You are currently not on channel $chan"
		}
	} else {
		putquick "PRIVMSG $nick :Please specify a valid channel
	}
}

#Used in Voting. Subtracts 1 from FOR
proc msg:minus {nick host hand text} {
	global aVoting aCountFor aCountAgainst aVoted
	set chan [lindex [split $text] 0]

	if {[string index $chan 0] == "#"} {
		if {[onchan $nick $chan]} {
	    		if {[meetingInProgress $chan] && $aVoting($chan)} {
				foreach person $aVoted($chan) {
					if { [string equal $nick $person] } {
						putquick "PRIVMSG $nick :You have already voted on this topic."
						return
					}
				} 
				set aCountAgainst($chan) [expr $aCountAgainst($chan) + 1]
				lappend aVoted($chan) $nick	
				set count [expr $aCountFor($chan) - $aCountAgainst($chan)]
				putquick "PRIVMSG $chan :private -1 vote received. $aCountFor($chan) for, $aCountAgainst($chan) against. Count is now $count"	
			}
		} else {
			putquick "PRIVMSG $nick :You are currently not on channel $chan"
		}
	} else {
		putquick "PRIVMSG $nick :Please specify a valid channel
	}
}
