set doc_section Notify
set doc_type Server

# VARIABLES

doc add "Scripts ($doc_type)/$doc_section" "~/.quirc/notify.tcl

This file contains the notify system.  It's not the greatest, but it works."

doc add "Variables (Config)/$doc_section/notify_list" "The list of nicks that you want to monitor for coming online or going offline."
config default notify_list ""
if { [info vars ::dynamic::notify_list]=="" } { set ::dynamic::notify_list "" }

doc add "Variables (Config)/$doc_section/notify_time" "The time in milliseconds between notify checks.  I wouldn't set this too low or you could lag or flood yourself off IRC."
config default notify_time 30000
if { [info vars ::dynamic::notify_time]=="" } { set ::dynamic::notify_time 30000 }

doc add "Variables (Config)/$doc_section/notify_nicks" "The max number of nicks to send in a single ison request."
config default notify_nicks 15
if { [info vars ::dynamic::notify_nicks]=="" } { set ::dynamic::notify_nicks 15 }


set ::[index]::onnow ""
set ::[index]::checking ""
set ::[index]::checkingtag ""

# When people are removed from the notify list, make sure to remove them from
# the online list too.  How do I do this now?

# See about auto-store variable so that store is called every time an option
# is changed.  Right now, would affect /alias, /set, /unset, /append, /remove.

# DAL watch

# Append on some server specific notify list perhaps

# Call NOTIFY_SIGNON and NOTIFY_SIGNOFF when events occur
# Add generic proc to call events with certain arguments

proc event_connect {} {
    set ::[index]::onnow ""
}


proc event_unload {} {
    after cancel "if { \[info commands ::[index]::notify::checknotify]!=\"\" } { ::[index]::notify::checknotify }"
    doc remove Variables/notify_list
    doc remove Variables/notify_time
    doc remove Variables/notify_nicks
}

proc event_pong { prefix args } {
    if { [string match "NOTIFY_TAG_*" [lindex $args 1]] } {
	set ::[index]::checkingtag [lindex $args 1]
	return 3
    }
    return 0
}

proc event_quit { prefix args } {
    set oldnick [lindex [split $prefix "!"] 0]
    if { [lsearch -exact [set ::[index]::onnow] $oldnick]!=-1 } {
	set index [lsearch -exact [set ::[index]::onnow] $oldnick]
	set ::[index]::onnow [lreplace [set ::[index]::onnow] $index $index]
	fdisplay NOTIFY_OFF $oldnick
    }
    return 0
}

proc event_join { prefix args } {
    set newnick [lindex [split $prefix "!"] 0]
    if { [lsearch -exact $::dynamic::notify_list $newnick]!=-1 && [lsearch -exact [set ::[index]::onnow] $newnick]==-1 } {
	lappend ::[index]::onnow $newnick
	fdisplay NOTIFY_ON $newnick
    }
    return 0
}

proc event_nick { prefix newnick } {
    set oldnick [lindex [split $prefix "!"] 0]
    if { [lsearch -exact [set ::[index]::onnow] $oldnick]!=-1 } {
	set index [lsearch -exact [set ::[index]::onnow] $oldnick]
	set ::[index]::onnow [lreplace [set ::[index]::onnow] $index $index]
	fdisplay NOTIFY_OFF $oldnick
    }
    if { [lsearch -exact $::dynamic::notify_list $newnick]!=-1 && [lsearch -exact [set ::[index]::onnow] $newnick]==-1 } {
	lappend ::[index]::onnow $newnick
	fdisplay NOTIFY_ON $newnick
    }
    return 0
}

proc event_303 { prefix args } {
    if { [set ::[index]::checkingtag]!="" } {
	set newnicks [split [string trim [lindex $args 1]]]
	foreach nick $newnicks {
	    if { [lsearch -exact [set ::[index]::onnow] $nick]==-1 } {
		lappend ::[index]::onnow $nick
		fdisplay NOTIFY_ON $nick
	    }
	}
	set index [lsearch -exact [set ::[index]::checking] [set ::[index]::checkingtag]]
	set oldnicks [lindex [set ::[index]::checking] [expr $index+1]]
	set ::[index]::checking [lreplace [set ::[index]::checking] $index [expr $index+1]]
	foreach nick $oldnicks {
	    if { [lsearch -exact $newnicks $nick]==-1 && [lsearch -exact [set ::[index]::onnow] $nick]!=-1 } {
		set index [lsearch -exact [set ::[index]::onnow] $nick]
		set ::[index]::onnow [lreplace [set ::[index]::onnow] $index $index]
		fdisplay NOTIFY_OFF $nick
	    }
	}
	set ::[index]::checkingtag ""
	return 3
    }
    return 0
}

proc checknotify {} {
    set checksection 0
    while { [llength [set nicks [lrange [set ::dynamic::notify_list] $checksection [expr $checksection+$::dynamic::notify_nicks-1]]]] } {
	incr checksection $::dynamic::notify_nicks
	set tag "NOTIFY_TAG_[microtime]"
	lappend ::[index]::checking $tag
	lappend ::[index]::checking $nicks
	quote "PING $tag"
	quote "ISON [join $nicks]"
    }
    after $::dynamic::notify_time "if { \[info commands ::[index]::notify::checknotify]!=\"\" } { ::[index]::notify::checknotify }"
}

::[index]::notify::checknotify

# If userhosts are desired (make config option) then send them in bunches
# of 5 as the isons come in.  There is some posibility of "nick not found"
# junk if the nicks go ofline.

#Usage: NOTIFY [[-]<nickname> [[-]<nickname> ...]]
#   Use of this command lets you mark certain nicknames such that
#   you will be warned when they signon or off of IRC.  When
#   someone on your notify-list signs on, you will see a message
#     *** Signon by <nickname> detected
#   Likewise, when they signoff, you will see
#     *** Signoff by <nickname> detected
#   Someone will be shown as signed off if they change nicknames as well,
#   so keep this in mind.
# 
#   You can modify how the signon and signoff messages are
#   displayed using the ON NOTIFY_SIGNON and ON NOTIFY_SIGNOFF
#   commands.
# 
#   Specifying a - before a nickname will remove notification
#   checking for that nickname.  If no parameters are specified,
#   the current status of each user on your notify list is
#   displayed.  If you specify a + without any additional
#   parameters:
#     NOTIFY +
#   you will be shown a list of only those people on your
#   notification list who are currently on irc.  If you specify
#   a - with no additional parameters, all nicks will be removed.
