#
# altnick.tcl v1.0 by Ernst <ernst@studbox.uni-stuttgart.de>
#
# Ernst's eggdrop page:  http://www.sodre.net/ernst/eggdrop/
#
# This script allows to configure "alternate" nicknames for each user.  This
# script alone does not use this information directly, but makes this easily
# accessible from other scripts (for example my seen5.tcl).  Just make sure
# you load altnick.tcl before other scripts (which might use this
# functionality).
#
# Commands on dcc (for channel masters only):
#     .+nick <handle> <altnick> - adds an <altnick> to <handle>
#     .-nick <handle> <altnick> - removes an <altnick> from <handle>
#     .altnicks <handle>        - shows current altnicks of <handle>
#     .findnick <nick>          - finds user with handle/altnick <nick>
#
# -----------------------------------------------------------------------------
# Note to script developers:
#
# If you want to use the "altnicks" information in your script you can make so
# very easily and still maintain "backwards" compatibility (so your script
# will also work if the user does not have altnick.tcl installed).
#
# Just add this piece of code at the beginning of your script:
#
#     # If altnick.tcl is loaded, use it
#     if {[info commands findnick] == ""} {
#     	proc findnick {nick} {
#         if {[validuser $nick]} { return $nick } { return "" }
#     	}
#     }
#
# This will make sure there is a "findnick" procedure for you to use in your
# script, and you must worry if it is "altnick.tcl's".
#
# Here is the main proc you will want to use in your scripts.  See seen5.tcl
# and url.tcl for examples on how to use them.
#
# findnick <nick>
#     A tcl procedure which returns the handle of an user that has handle
#     <nick> or alternative nick <nick>.  Returns an empty string if none is
#     found.
#
# Example:  user "Ernst" has altnicks "Ernesto" and "Maracatu"
#     findnick "Ernst"    -> returns "Ernst"
#     findnick "Maracatu" -> returns "Ernst"
#     findnick "Bogus"    -> returns "" (assuming you have neither an user
#                            called "Bogus" nor one with altnick "Bogus")

# Just in case...
if {!$toolkit_loaded} {
	proc user-get {handle key} {
		set xtra [getxtra $handle]
		for {set i 0} {$i < [llength $xtra]} {incr i} {
			set this [lindex $xtra $i]
			if {[string compare [lindex $this 0] $key] == 0} {
				return [lindex $this 1]
			}
		}
		return ""
	}
	proc user-set {handle key data} {
		set xtra [getxtra $handle]
		# is key already there?
		for {set i 0} {$i < [llength $xtra]} {incr i} {
			set this [lindex $xtra $i]
			if {[string compare [lindex $this 0] $key] == 0} {
				set this [list $key $data]
				setxtra $handle [lreplace $xtra $i $i $this]
				return
			}
		}
		lappend xtra [list $key $data]
		setxtra $handle $xtra
	}
}

# findnick proc, returns handle of user with specified handle/altnick
proc findnick { altnick } {
	if {$altnick == ""} { return "" }
	if {[validuser $altnick]} { return $altnick }
	set altnick [string tolower $altnick]
	foreach nick [userlist] {
		set altnicks [string tolower [user-get $nick altnicks]]
		if {[lsearch -exact $altnicks $altnick] != -1} { return $nick }
	}
	return ""
}

bind dcc M findnick dcc_findnick
bind dcc M altnicks dcc_altnicks
bind dcc M +nick dcc_addnick
bind dcc M -nick dcc_delnick

proc dcc_findnick { hand idx nick } {
	if {[llength $nick] != 1} {
		putdcc $idx "Usage: .findnick <nick>"
		return 0
	}
	if {[validuser $nick]} {
		putdcc $idx "There is an user called $nick."
		return 0
	}
	set thisnick [findnick $nick]
	if {$thisnick != ""} {
		putdcc $idx "$thisnick has altnick $nick."
	} {
		putdcc $idx "There is noone with nick/altnick $nick."
	}
	return 0
}

proc dcc_altnicks { hand idx handle } {
	if {[llength $handle] != 1} {
		putdcc $idx "Usage: .altnicks <handle>"
		return 0
	}
	if {![validuser $handle]} {
		putdcc $idx "Error: I don't know user $handle"
		return 0
	}
	set altnicks [user-get $handle altnicks]
	if {[llength $altnicks] == 0} {
		putdcc $idx "$handle does not have altnicks"
	} elseif {[llength $altnicks] == 1} {
		putdcc $idx "${handle}'s altnick: $altnicks"
	} {
		putdcc $idx "${handle}'s altnicks: $altnicks"
	}
	return 0
}


proc dcc_delnick { hand idx arg } {
	if {[llength $arg] != 2} {
		putdcc $idx "Usage: .-nick <handle> <altnick>"
		return 0
	}
	set handle [lindex $arg 0]
	set altnick [lindex $arg 1]
	if {![validuser $handle]} {
		putdcc $idx "Error: I don't know user $handle"
		return 0
	}
	set altnicks [user-get $handle altnicks]
	set pos [lsearch -exact [string tolower $altnicks] [string tolower $altnick]]
	if {$pos != -1} {
		set newnicks [lreplace $altnicks $pos $pos]
		user-set $handle altnicks $newnicks
		putdcc $idx "New altnicks for $handle: $newnicks"
		return 1
	} {
		putdcc $idx "Error: $handle does not have this altnick: $altnick"
		return 0
	}
}

proc dcc_addnick { hand idx arg } {
	if {[llength $arg] != 2} {
		putdcc $idx "Usage: .+nick <handle> <altnick>"
		return 0
	}
	set handle [lindex $arg 0]
	set newnick [lindex $arg 1]
	if {![validuser $handle]} {
		putdcc $idx "Error: I don't know user $handle"
		return 0
	}
	if {[validuser $newnick]} {
		putdcc $idx "Error: $newnick is already a valid user"
		return 0
	}
	if {[findnick $newnick] != ""} {
		putdcc $idx "Error: This nick \($newnick\) already belongs to [findnick $newnick]"
		return 0
	}
	set oldnicks [user-get $handle altnicks]
	set oldnicks [lsort [lappend oldnicks $newnick]]
	user-set $handle altnicks $oldnicks
	putdcc $idx "New altnicks for $handle: $oldnicks"
	return 1
}

