#########
#
# MootBot - Core 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			       #
################################################################################

# Load the config file
source scripts/mootbot_config.tcl

# Load required files
source scripts/mootbot_template.tcl
source scripts/mootbot_chan.tcl
source scripts/mootbot_vote.tcl

# Version Information
set mootbot_core_version 16

# Meeting Details
array set aInProgress {}
array set aChair {}
array set aChanTopic {}

# Files & Logging Info
array set aMinutesFile {}
array set aChanLog {}
array set aChanLogName {}
array set aAnchorCount {}
array set aPresent {}

# Public Channel Command Bindings
bind pub - "#startmeeting"  pub:startmeeting
bind pub - "#endmeeting"  pub:endmeeting
bind pubm - "% #IDEA*" pubm:idea
bind pubm - "% #INFO*" pubm:info
bind pubm - "% #ACTION*" pubm:action
bind pubm - "% #TOPIC*" pubm:topic
bind pubm - "% #AGREED*" pubm:agreed
bind pubm - "% #LINK*" pubm:link
bind pubm - * pubm:log
bind ctcp - "ACTION" ctcp:log

# Privmsg Command Bindings
bind msg - "help" msg:help
bind msg - "topic" msg:topic

# Add nick onto the present list
proc addPresent {chan nick} {
	global aPresent

	foreach person $aPresent($chan) {
		if { [string equal $nick $person] } {
			return
		}
	} 
		
	# Not in the present list, add them in
	lappend aPresent($chan) $nick
}

#Checks if a meting is in progress. If it is, return true, else return false.
proc meetingInProgress {chan} {
	global aInProgress

	if {[info exists aInProgress($chan)]} { 
           return $aInProgress($chan)
        } else {
           return false
        }
}

# Outputs the IDEA, AGREED and ACTION tags
#   - Type, Originating Nick, Channel, Text to output, Text to display
proc outputTag {type nick chan text display} {
	global aChair aChanLogName aAnchorCount VerboseCommands AddToBotLog

	#Output to channel and PM
        if {$VerboseCommands} {
		putquick "PRIVMSG $chan :$type received: $display "
		putquick "PRIVMSG $aChair($chan) :$type received: $display"
	}

	if {$AddToBotLog} {
		putlog "$chan issued $type command"
	}

	#Output to summary
	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>$type</td>\n<td>$nick</td>\n<td>$text</td>\n</tr>"

	#Output anchor link to text log.
	logWrite 1 $chan "<a name='$aAnchorCount($chan)'></a>"
	set aAnchorCount($chan) [expr $aAnchorCount($chan) + 1]
}

######### Public Message Functions

#Function to log /me actions
proc ctcp:log {nick host hand dest keyword text} {
	#First, ensure message was sent to channel, not the bot
	if {[string index $dest 0] != "#"} {
		return 0
	}
	global aChanLog
	#Only if a meeting is progress
	if {[meetingInProgress $dest]} {
		logWrite 1 $dest "\[[clock format [clock seconds] -format %H:%M:%S]\] * $nick $text<br />"
		addPresent $dest $nick
	}
}
	

#Function to log all channel text
proc pubm:log {nick host hand chan text} {
	global aChanLog aPresent ScrapeURLs
	if {[meetingInProgress $chan]} {

		if {$ScrapeURLs && ![string compare [string range $text 0 [expr [string first ":" $text] - 1]] "http"]} {
			pubm:link $nick $host $hand $chan "\[LINK\] $text"
		}	

		logWrite 1 $chan "\[[clock format [clock seconds] -format %H:%M:%S]\] &lt;$nick\&gt; $text<br />"
		addPresent $chan $nick
	}
}

#Starts a meeting. Assigns person that issued the command as chair.
proc pub:startmeeting {nick host hand chan text} {
	global aInProgress aChair aMinutesFile aChanLog aPresent 
        global aChanLogName aAnchorCount outputPath aChanTopic

	if {![meetingInProgress $chan]} {
		set datetimeprefix [clock format [clock seconds] -format %Y%m%d_%H%M]
		set channame  [string range $chan 1 end]

		set aMinutesFile($chan) [open [file join $outputPath $channame.$datetimeprefix.html] "w"]
		set aChanLog($chan) [open [file join $outputPath $channame.log.$datetimeprefix.html]  "w"]
		set aChanLogName($chan) $channame.log.$datetimeprefix.html		

		logWrite 1 $chan "Started logging meeting in $chan, times are UTC.<br />"
	
		#Initialise variables for that channel
		set aInProgress($chan) true
		set aChair($chan) $nick
		set aAnchorCount($chan) 0
		set aPresent($chan) {}
                set aChanTopic($chan) ""

		cleanVoting $chan

		set start_time [clock format [clock seconds] -format %H:%M]

		#Output to channel and PM chair
		putquick "PRIVMSG $chan :Meeting started at $start_time UTC. The chair is $aChair($chan)."
		putquick "PRIVMSG $chan :Commands Available: #TOPIC, #IDEA, #ACTION, #AGREED, #LINK"
		#putquick "PRIVMSG $aChair($chan) :Meeting started at $start_time. The chair is $aChair($chan)." 

		#Write to log file
		logWrite 2 $chan "<html>\n<body>\nMeeting started by $aChair($chan) at $start_time UTC\n<table border=1>"
	} else {
		putquick "PRIVMSG $chan :$nick, There is already a meeting in progress."
	}
}

#Ends the meeting. Can only be used by chair.
proc pub:endmeeting {nick host hand chan text} {
	global aInProgress aChair aMinutesFile aChanLog aChanLogName 
        global aAnchorCount aPresent LeaveChannelAfter aChanTopic

	#Check meeting is currently in progress, and that user is chair.
	if {[meetingInProgress $chan] && [string equal $nick $aChair($chan)]} {
		if {[isVoting $chan]} {
			putquick "PRIVMSG $chan :Vote is in progress. Finishing now."
			pub:endvote $nick $host $hand $chan $text
		}

		set chair "None"

		putquick "PRIVMSG $chan :Meeting finished at [clock format [clock seconds] -format %H:%M]." 
		putquick "PRIVMSG $chan :Logs available at http://meetbot.debian.net/meetbot/"
		#putquick "PRIVMSG $aChair($chan) :Meeting finished at [clock format [clock seconds] -format %H:%M]." 
		#putquick "PRIVMSG $aChair($chan) :Logs available at http://meetbot.debian.net/meetbot/"
		
		if {$LeaveChannelAfter} {
			killChannel $chan
		}
	
		logWrite 2 $chan "</table>\nMeeting ended at [clock format [clock seconds] -format %H:%M].\n"
		logWrite 2 $chan "<br/>\n<br/>\nPeople Present:<br/>\n<ol>"

		foreach person $aPresent($chan) {
			logWrite 2 $chan "<li>$person</li>\n"
		} 
		set aPresent($chan) {}

		logWrite 2 $chan "</ol><hr><p>Information on meetbot is available at <a href='http://meetbot.debian.net'>meetbot.debian.net</a></p></body></html>"
		close $aMinutesFile($chan)

		logWrite 1 $chan "<hr>Meeting ended.<br /><hr><p>Information on meetbot is available at <a href='http://meetbot.debian.net'>meetbot.debian.net</a></p>"
		close $aChanLog($chan)

		#Write changes to variables
		set aInProgress($chan) false
		set aChair($chan) ""
		set aChanLog($chan) {}
		set aChanLogName($chan) {}
                set aChanTopic($chan) ""
	}

}

#Records IDEA tag
proc pubm:idea {nick host hand chan text} {
	if {[meetingInProgress $chan]} {
		set message_text [string range $text [expr [string first " " $text] + 1] end]
		outputTag "IDEA" $nick $chan $message_text $message_text
	}

}

#Records INFO tag
proc pubm:info {nick host hand chan text} {
	if {[meetingInProgress $chan]} {
		set message_text [string range $text [expr [string first " " $text] + 1] end]
		outputTag "INFO" $nick $chan $message_text $message_text
	}

}

#Record ACTION tag. Can only be used by chair.
proc pubm:action {nick host hand chan text} {
	global aChair
	if {[meetingInProgress $chan] && [string equal $nick $aChair($chan)]} {
		set message_text [string range $text [expr [string first " " $text] + 1] end]
		outputTag "ACTION" $nick $chan $message_text $message_text
	}
}

#Recrods AGREED tag. Can only be used by chair.
proc pubm:agreed {nick host hand chan text} {
	global aChair
	if {[meetingInProgress $chan] && [string equal $nick $aChair($chan)]} {
		set message_text [string range $text [expr [string first " " $text] + 1] end]
		outputTag "AGREED" $nick $chan $message_text $message_text
	}
}

# Records LINK tag
proc pubm:link {nick host hand chan text} {
        if {[meetingInProgress $chan]} {
                set message_text [string range $text [expr [string first " " $text] + 1] end]
		
		if {![string compare [string range $message_text 1 [expr [string first ":" $message_text] - 1]] "wiki"]} {
		    set rurl "http://wiki.debian.org/[string range $message_text [expr [string first ":" $message_text] + 1] end]"
                } else {
		    set rurl $message_text
                }

		set url "<a href=\"$rurl\">$message_text</a>" 
                outputTag "LINK" $nick $chan $url $message_text
        }

}

#Records TOPIC tag. Can only be used by chair.
proc pubm:topic {nick host hand chan text} {
	global aChair aChanLogName aAnchorCount VerboseCommands AddToBotLog aChanTopic
    
  	if {[meetingInProgress $chan] && [string equal $nick $aChair($chan)]} {
		set message_text [string range $text [expr [string first " " $text] + 1] end]

		if {[isVoting $chan]} {
                        putquick "PRIVMSG $chan :Vote is in progress. Finishing now."
                        pub:endvote $nick $host $hand $chan $text
		}

                if {$VerboseCommands} {
			putquick "PRIVMSG $chan :New Topic: $message_text "
			putquick "PRIVMSG $aChair($chan) :New Topic: $message_text"
		}

		if {$AddToBotLog} {
			putlog "$chan issued TOPIC command"
		}

		set aChanTopic($chan) $message_text
		putquick "TOPIC $chan :$message_text"

		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 "<th colspan=3>Topic: $message_text</th>\n</tr>"
		
		logWrite 1 $chan "<a name='$aAnchorCount($chan)'></a>"
		set aAnchorCount($chan) [expr $aAnchorCount($chan) + 1]
	}
}


######### Privmsg Commands

#Privmsgs the user some basic help
proc msg:help {nick host hand text} {
	puthelp "PRIVMSG $nick :Commands Available: #TOPIC, #IDEA, #ACTION, #AGREED, #LINK"
}

proc msg:topic {nick host hand text} {
   global aChanTopic
   set chan [lindex [split $text] 0]

   if {[string index $chan 0] == "#"} {
        if {[meetingInProgress $chan]} {
            putquick "PRIVMSG $nick :Current Topic for $chan: $aChanTopic($chan)"
        } else {
	    putquick "PRIVMSG $nick :Theres no current meeting in $chan"
        }
   } else {
 	putquick "PRIVMSG $nick :Please specify a valid channel"
   }
}

putlog "MootBot - r$mootbot_core_version - Loaded"
