# OpenVerse Base Functions
# 
# This file contains some basic functions for 
# OpenVerse
#
# Module Name		- Main Module
# Current Maintainter 	- Cruise <cruise@openverse.org>
# Sourced By		- Main Module
#
# Copyright (C) 1999 David Gale <cruise@openverse.org>
# For more information visit http://OpenVerse.org/
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
# USA.

# NOTES: 
# Now using string compare for increased performance
# Now using curleybraces around functions for speed

#
# Images which we use with our chat balloons.
#
image create photo OpenVerse_Image_CHAT_notes -file "$MV(icondir)/notes.gif"
image create photo OpenVerse_Image_CHAT_love -file "$MV(icondir)/hearts.gif"
image create photo OpenVerse_Image_CHAT_steam -file "$MV(icondir)/steam.gif"
image create photo OpenVerse_Image_CHAT_idea -file "$MV(icondir)/bulb.gif"
image create photo OpenVerse_Image_CHAT_smile -file "$MV(icondir)/smile.gif"
image create photo OpenVerse_Image_CHAT_frown -file "$MV(icondir)/frown.gif"
image create photo OpenVerse_Image_CHAT_wink -file "$MV(icondir)/wink.gif"
image create photo OpenVerse_Image_CHAT_jump -file "$MV(icondir)/jump.gif"
image create photo OpenVerse_Image_CHAT_shiver -file "$MV(icondir)/shiver.gif"
image create photo OpenVerse_Image_CHAT_quit -file "$MV(icondir)/shutdown.gif"

#
# Translator - This is an attempt to make a portable translator.
# It used text files to load it's phrases from. If there is no translation
# for the word or phrase, it will just display the english form. If there
# is no english form, it will imporvise.
#

proc Trns {what} {
	global MV

	if {[catch {set MV(words.$what)}]} {
		set str [join [split $what "_"] " "]
		set str "[string toupper [string range $str 0 0]][string range $str 1 end]"
		DebugIt "(Translator) No Translation exists for $what" other
	} else {
		set str $MV(words.$what)
	}
	return $str
}

#
# Will fill the names button with people who are in the channel.
# 
proc DoNames {} {
	global MV

	destroy $MV(names_menu).m
	menu $MV(names_menu).m 

	$MV(names_menu).m add command -label [Trns whois_everyone] \
			-command "SendToServer \"WHOIS *\""
	#
	# Process Plugins!
	#
	foreach plugin $MV(plugin.traps.Names) {
		if ![$MV(plugin.traps.Names.$plugin)] {return}
	}
	$MV(names_menu).m add separator

	set people 0
	foreach person $MV(people) {
		set MV(whois.$people) $person
		$MV(names_menu).m add cascade -menu \
			$MV(names_menu).m.$people -label "$person"
		if !$MV(use_windowmanager_colors) {
			menu $MV(names_menu).m.$people -bg $MV(colors.name.bg) \
				-fg $MV(colors.name.fg) -activebackground $MV(colors.name.abg) \
				-activeforeground $MV(colors.name.afg)
		} else {
			menu $MV(names_menu).m.$people
		}
		NameMenu "$MV(names_menu).m.$people" $people $person
		incr people
	}
	ColorNames
}


#
# CRUISE - 11/06/2001 - Changed the way IgnoreALL works, it will ig/unignore all types
#
proc NameMenu {win people person} {
	global MV MVS

	$win add command -label [Trns whois] \
		-command "WhoisCMD $people"
	$win add command -label [Trns send_message] \
		-command "MessageCMD $people"
	$win add command -label [Trns send_url] \
		-command "URLCMD $people"
	$win add command -label [Trns send_file] \
		-command "SendFileFromMenu $people"
	$win add command -label [Trns call] \
		-command "CallUser $people"
	$win add command -label [Trns request_personal_info] \
		-command "RequestPersonal $people"
	if $MVS(serving) {
		$win add command -label [Trns announce_server] \
			-command "AnnounceServerToUser $people"
	}
	$win add cascade -label [Trns ignore] \
		-menu $win.m
	if !$MV(use_windowmanager_colors) {
		menu $win.m -bg $MV(colors.name.bg) \
			-fg $MV(colors.name.fg) -activebackground $MV(colors.name.abg) \
			-activeforeground $MV(colors.name.afg)
	} else {
		menu $win.m
	}
	if {[lsearch -exact $MV(ignore.avatar) $person] == -1} {
		$win.m add command -label [Trns ignore_avatar] \
			-command "IgnoreUser $people AVATAR"
	} else {
		$win.m add command -label [Trns unignore_avatar] \
			-command "UnIgnoreUser $people AVATAR"
	}
	if {[lsearch -exact $MV(ignore.effect) $person] == -1} {
		$win.m add command -label [Trns ignore_effects] \
			-command "IgnoreUser $people EFFECT"
	} else {
		$win.m add command -label [Trns unignore_effects] \
			-command "UnIgnoreUser $people EFFECT"
	}
	if {[lsearch -exact $MV(ignore.move) $person] == -1} {
		$win.m add command -label [Trns ignore_moves] \
			-command "IgnoreUser $people MOVE"
	} else {
		$win.m add command -label [Trns unignore_moves] \
			-command "UnIgnoreUser $people MOVE"
	}
	if {[lsearch -exact $MV(ignore.speech) $person] == -1} {
		$win.m add command -label [Trns ignore_speech] \
			-command "IgnoreUser $people SPEECH"
	} else {
		$win.m add command -label [Trns unignore_speech] \
			-command "UnIgnoreUser $people SPEECH"
	}
	if {[lsearch -exact $MV(ignore.sub) $person] == -1} {
		$win.m add command -label [Trns ignore_sub] \
			-command "IgnoreUser $people SUB"
	} else {
		$win.m add command -label [Trns unignore_sub] \
			-command "UnIgnoreUser $people SUB"
	}
	if {[lsearch -exact $MV(ignore.url) $person] == -1} {
		$win.m add command -label [Trns ignore_url] \
			-command "IgnoreUser $people URL"
	} else {
		$win.m add command -label [Trns unignore_url] \
			-command "UnIgnoreUser $people URL"
	}
	# All handled differently.
	if {[lsearch -exact $MV(ignore.all) $person] == -1 || \
	[lsearch -exact $MV(ignore.url) $person] == -1 || \
	[lsearch -exact $MV(ignore.sub) $person] == -1 || \
	[lsearch -exact $MV(ignore.move) $person] == -1 || \
	[lsearch -exact $MV(ignore.speech) $person] == -1 || \
	[lsearch -exact $MV(ignore.effect) $person] == -1 || \
	[lsearch -exact $MV(ignore.avatar) $person] == -1} {
		$win.m add command -label [Trns ignore_all] \
			-command "IgnoreUser $people ALL"
	}
	if {[lsearch -exact $MV(ignore.all) $person] != -1 || \
	[lsearch -exact $MV(ignore.url) $person] != -1 || \
	[lsearch -exact $MV(ignore.sub) $person] != -1 || \
	[lsearch -exact $MV(ignore.move) $person] != -1 || \
	[lsearch -exact $MV(ignore.speech) $person] != -1 || \
	[lsearch -exact $MV(ignore.effect) $person] != -1 || \
	[lsearch -exact $MV(ignore.avatar) $person] != -1} {
		$win.m add command -label [Trns unignore_all] \
			-command "UnIgnoreUser $people ALL"
	}
	#
	# Process Plugins!
	#
	foreach plugin $MV(plugin.traps.DoNames) {
		if ![$MV(plugin.traps.DoNames.$plugin) $win $person $people] {return}
	}
}


proc StartLog {} {
	global MV

	set MV(log) 1
	set MV(logfile) [open "$MV(homedir)/LogFile.txt" "a+"]
	puts $MV(logfile) "- Log Started - [clock format [clock seconds]]"
	InsertIntoChat 0 "\0030,4- Log Started - [clock format [clock seconds]] ($MV(homedir)/LogFile.txt)\n"
}

proc LogThis {what} {
	global MV
	puts -nonewline $MV(logfile) "$what"
}

proc StopLog {} {
	global MV

	set MV(log) 0
	puts $MV(logfile) "- Log Stopped - [clock format [clock seconds]]"
	InsertIntoChat 0 "\0030,4- Log Stopped - [clock format [clock seconds]] ($MV(homedir)/LogFile.txt)\n"
	close $MV(logfile)
	set MV(logfile) "-1"
}

proc NickComplete {} {
	global MV

	DebugIt "-- In NickComplete" other
        set stuff [$MV(chat_entry) get]
	if {![string compare $stuff ""]} {return}
	set wrds [split $stuff " "]
	set lastwrd [string tolower [lindex $wrds [expr [llength $wrds] -1]]]
	set len [expr [string length $lastwrd] -1]
	foreach person $MV(people) {
		if {[string range $person 0 $len] == $lastwrd} {
			$MV(chat_entry) insert end [string range $person [expr $len +1] end]
			return
		}
	}
}

proc SetRoom {what size} {
	global MV

	if {[file exists "$MV(roomdir)/$what"]} {
		if {[file size "$MV(roomdir)/$what"] != $size} {
			DebugIt "size mismatch for $what" other
			catch {file delete "$MV(roomdir)/$what"}
			if {[lsearch -exact $MV(roomloads) $what] == -1} {
				image create photo OpenVerse_Image_room -file "$MV(homedir)/icons/loading.gif"
				SendToServer "DCCSENDROOM $what"
			}
		} else {
			image create photo OpenVerse_Image_room -file "$MV(roomdir)/$what"
		}
	} else {
		if {[lsearch -exact $MV(roomloads) $what] == -1} {
			image create photo OpenVerse_Image_room -file "$MV(homedir)/icons/loading.gif"
			SendToServer "DCCSENDROOM $what"
		}
	}
}


proc WhoisCMD {person} {
	global MV

	SendToServer "WHOIS $MV(whois.$person)"
}

proc WHOISUser {who hostmask} {
	global MV
	if {[lsearch -exact $MV(people) $who] == -1} {return}
	ProcChat $who "[Trns host_info] $hostmask" 0 3 $MV(colors.whois.baloon)
}

proc GetChatRows {text} {
	global MV
	set words [split $text]
	set word_ptr 0
	set last_word [llength $words]
	if {$last_word == 1} {return 1}
	set rows 1
	set line ""
	set last_word_ptr -1
	while {$word_ptr <= $last_word} {
		update idletasks
		append line [lindex $words $word_ptr]
		set width [font measure "$MV(font.balloon.$MV(font.balloon).$MV(font.balloon.style)) -size $MV(font.balloon.size)" $line]
		if {$width >= 240} {
			incr rows
			set incremented 1
			set line ""
			if {$word_ptr == $last_word_ptr} {
				incr word_ptr
			} else {
				set last_word_ptr $word_ptr
			}
		} else {
			set incremented 0
			incr word_ptr
		}
	}
	if $incremented {
		return $rows
	} else {
		return [expr $rows + 1]
	}
}

#
# StripColorCodes "Text To Be Stripped"
#
# Takes out all the color codes from some text
# and returns a cleaner string.
#
proc StripColorCodes {text} {
	while {[set tb [string first \x03 $text]] != -1} {
		set string [string range $text 0 [expr $tb -1]]
		set text [string range $text [expr $tb +1] end]
		if {[regexp {^([0-9][0-9]?)(,([0-9][0-9]?))?(.*)} $text m fg bl bg text]} {
			# hehe stripped!
			set color 1
		}
		set text "$string$text"
	}
	return $text
}

#
# CRUISE - 11-06-2001 - Fixed the balloon bug when someone says something jsut as you're leaving?
#
proc ProcChat {who what que system baloon} {
	global MV

	# If this user isn't here, bail.
	if {[lsearch -exact $MV(people) $who] == -1 && $who != $MV(nick)} {return}

	if {![string compare $who $MV(nick)]} {
		set MV($MV(nick).x) $MV(x)
		set MV($MV(nick).y) $MV(y)
		set MV($MV(nick).baloon_x) $MV(anim.baloon_x)
		set MV($MV(nick).baloon_y) $MV(anim.baloon_y)
	}
	set MV($who.chattime) [clock seconds]
	if {$MV($who.haschat) && !$que} {
		lappend MV($who.chatque) "$system$baloon:$what"
		return
	} else {
		set MV($who.lastsaid) "$what"
	}

	#
	# Proces Plugins!
        foreach plugin $MV(plugin.traps.ProcChat.pre) {
                if ![$MV(plugin.traps.ProcChat.pre.$plugin) $who $what $system $baloon] {return}
        }
	
	set MV($who.haschat) 1
	#
	# Types of balloons.
	#
	#	0	Normal Chat
	#	1	System Messages.
	#	2	Private Messages.
	#	3	Whois Messages.
	#	4	Singing Chat
	#	5	Love Chat
	#	6	Angry Chat
	#	7	Idea Chat
	#	8	Smiling Chat
	#	9	Frowning Chat
	#	A	Winking Chat
	#
	switch $system {
		0 {set textcolor $MV(colors.chat.text)}
		1 {set textcolor $MV(colors.system.text)}
		2 {set textcolor $MV(colors.privmsg.text)}
		3 {set textcolor $MV(colors.whois.text)}
		4 {set textcolor $MV(colors.chat.text)}
		5 {set textcolor $MV(colors.chat.text)}
		6 {set textcolor $MV(colors.chat.text)}
		7 {set textcolor $MV(colors.chat.text)}
		8 {set textcolor $MV(colors.chat.text)}
		9 {set textcolor $MV(colors.chat.text)}
		A {set textcolor $MV(colors.chat.text)}
		default {set textcolor "black"}
	}
	set oldwhat $what
	set what [StripColorCodes $what]
	set text $what
	while {[string first "-d" $text] != -1} {
		set str1 [string range $text 0 [expr [string first "-d" $text] -1]]
		set str2 [string range $text [expr [string first "-d" $text] +2] end]
		set text "$str1$str2"
	}
	set rows [GetChatRows $text]
	set font_height [lindex [font metrics "$MV(font.balloon.$MV(font.balloon).$MV(font.balloon.style)) -size $MV(font.balloon.size)"] 5]
	if {![string compare [string range $text 0 0] "-"]} {
		set text [string range $text 1 end]
	}
	set fwidth [font measure "$MV(font.balloon.$MV(font.balloon).$MV(font.balloon.style)) -size $MV(font.balloon.size)" $text]
	if {$fwidth > 260} {
		set width 260
		if {$rows == 1} {set rows [expr int($fwidth / 260) + 1]}
		if {$rows < 3} {set rows 2}
		set height [expr $rows * $font_height]
		set hoff [expr int($rows * 1.5)]
	} else {
		set width [expr $fwidth + 15]
		set height 30
		set rows 2
		set hoff 2
	}
	if {$system >= 4} {incr width 30}
	if {$width > 300} {set width 300}
	if {$height < 30} {set height 30}
	if {[expr $MV($who.x) + $width + $MV($who.baloon_x)] > 620} {
		set xoff [expr $MV($who.baloon_x) - 35]
		set yoff -1
	} else {
		set xoff $MV($who.baloon_x)
		set yoff 1
	}
	set MV($who.baloon) [.top.c create polygon \
		[expr $MV($who.x) + ($xoff - (20 * $yoff))] [expr $MV($who.y) + $MV($who.baloon_y)] \
		[expr $MV($who.x) + $xoff] [expr $MV($who.y) + $MV($who.baloon_y) - 5] \
		[expr $MV($who.x) + $xoff] [expr $MV($who.y) + $MV($who.baloon_y) - ($height / 2)] \
		[expr $MV($who.x) + $xoff + ($yoff * 10)] [expr $MV($who.y) + $MV($who.baloon_y) - ($height / 2) -  $hoff] \
		[expr $MV($who.x) + $xoff + (($width - 10) * $yoff)] [expr $MV($who.y) + $MV($who.baloon_y) - ($height / 2) - $hoff] \
		[expr $MV($who.x) + $xoff + ($width * $yoff)] [expr $MV($who.y) + $MV($who.baloon_y) - ($height / 2)] \
		[expr $MV($who.x) + $xoff + ($width * $yoff)] [expr $MV($who.y) + $MV($who.baloon_y) + ($height / 2)] \
		[expr $MV($who.x) + $xoff + (($width - 10) * $yoff)] [expr $MV($who.y) + $MV($who.baloon_y) + ($height / 2) + $hoff] \
		[expr $MV($who.x) + $xoff + ($yoff * 10)] [expr $MV($who.y) + $MV($who.baloon_y) + ($height / 2) + $hoff] \
		[expr $MV($who.x) + $xoff] [expr $MV($who.y) + $MV($who.baloon_y) + ($height / 2)] \
		[expr $MV($who.x) + $xoff] [expr $MV($who.y) + $MV($who.baloon_y) + 5] \
		[expr $MV($who.x) + ($xoff - (20 * $yoff))] [expr $MV($who.y) + $MV($who.baloon_y)] \
		-fill $baloon -outline black -smooth 1]
	set MV($who.text) [.top.c create text \
		[expr $MV($who.x) + ($xoff - (20 * $yoff)) + ($yoff * ($width / 2)) + ($yoff * 20)] \
		[expr $MV($who.y) + $MV($who.baloon_y) - ($height / 2) + ($height / 2)] \
		-width 240 -text $what -fill $textcolor \
		-font "$MV(font.balloon.$MV(font.balloon).$MV(font.balloon.style)) -size $MV(font.balloon.size)"]
	set what $oldwhat
	switch $system {
		0 {set log 1;set SendToChat "<$who> $what\n"}
		1 {set log 0;set SendToChat "\0030,4[Trns system]\00399,99 $what\n"}
		2 {set log 1;set SendToChat "<!>$who<!> $what\n"}
		3 {set log 1;set SendToChat "<!>$who<!> $what\n"}
		4 {
			set log 1
			set SendToChat "<§>$who<§> $what\n"
			incr MV(killnotes)
			set MV(NotesKill.$MV(killnotes)) "$who"
			set MV($who.notes) [.top.c create image \
				[expr $MV($who.x) + $xoff + ($yoff * 10)] \
				[expr $MV($who.y) + $MV($who.baloon_y)] \
				-image OpenVerse_Image_CHAT_notes]
			after [expr $MV(staytime) * 1000] "KillNotes $MV(killnotes)"
		}
		5 {
			set log 1
			set SendToChat "<¤>$who<¤> $what\n"
			incr MV(killlove)
			set MV(LoveKill.$MV(killlove)) "$who"
			set MV($who.love) [.top.c create image \
				[expr $MV($who.x) + $xoff + ($yoff * 10)] \
				[expr $MV($who.y) + $MV($who.baloon_y)] \
				-image OpenVerse_Image_CHAT_love]
			after [expr $MV(staytime) * 1000] "KillLove $MV(killlove)"
		}
		6 {
			set log 1
			set SendToChat "<¥>$who<¥> $what\n"
			incr MV(killsteam)
			set MV(SteamKill.$MV(killsteam)) "$who"
			set MV($who.steam) [.top.c create image \
				[expr $MV($who.x) + $xoff + ($yoff * 10)] \
				[expr $MV($who.y) + $MV($who.baloon_y)] \
				-image OpenVerse_Image_CHAT_steam]
			after [expr $MV(staytime) * 1000] "KillSteam $MV(killsteam)"
		}
		7 {
			set log 1
			set SendToChat "<¿>$who<¿> $what\n"
			incr MV(killidea)
			set MV(IdeaKill.$MV(killidea)) "$who"
			set MV($who.idea) [.top.c create image \
				[expr $MV($who.x) + $xoff + ($yoff * 10)] \
				[expr $MV($who.y) + $MV($who.baloon_y)] \
				-image OpenVerse_Image_CHAT_idea]
			after [expr $MV(staytime) * 1000] "KillIdea $MV(killidea)"
		}
		8 {
			set log 1
			set SendToChat "<:)>$who<(:> $what\n"
			incr MV(killsmile)
			set MV(SmileKill.$MV(killsmile)) "$who"
			set MV($who.smile) [.top.c create image \
				[expr $MV($who.x) + $xoff + ($yoff * 10)] \
				[expr $MV($who.y) + $MV($who.baloon_y)] \
				-image OpenVerse_Image_CHAT_smile]
			after [expr $MV(staytime) * 1000] "KillSmile $MV(killsmile)"
		}
		9 {
			set log 1
			set SendToChat "<:(>$who<):> $what\n"
			incr MV(killfrown)
			set MV(FrownKill.$MV(killfrown)) "$who"
			set MV($who.frown) [.top.c create image \
				[expr $MV($who.x) + $xoff + ($yoff * 10)] \
				[expr $MV($who.y) + $MV($who.baloon_y)] \
				-image OpenVerse_Image_CHAT_frown]
			after [expr $MV(staytime) * 1000] "KillFrown $MV(killfrown)"
		}
		A {
			set log 1
			set SendToChat "<;)>$who<(;> $what\n"
			incr MV(killwink)
			set MV(WinkKill.$MV(killwink)) "$who"
			set MV($who.wink) [.top.c create image \
				[expr $MV($who.x) + $xoff + ($yoff * 10)] \
				[expr $MV($who.y) + $MV($who.baloon_y)] \
				-image OpenVerse_Image_CHAT_wink]
			after [expr $MV(staytime) * 1000] "KillWink $MV(killwink)"
		}
		default {set log 1;set SendToChat "<$who> $what\n"}
	}
	InsertIntoChat $log "$SendToChat"
	if $MV(bell) {bell}
	incr MV(killhigh)
	set MV(BaloonKill.$MV(killhigh)) "$who"
	after [expr $MV(staytime) * 1000] "KillBaloon $MV(killhigh)"
	#
	# Proces Plugins!
        foreach plugin $MV(plugin.traps.ProcChat.post) {
                if ![$MV(plugin.traps.ProcChat.post.$plugin) $who $what $system $baloon] {return}
        }
	update idletasks
}

proc KillNotes {which} {
	global MV

	set who "$MV(NotesKill.$which)"
	.top.c delete $MV($who.notes)
	#
	# Clean up the memory which this user was using.
	#
	catch {unset MV(NotesKill.$which)}
	catch {unset MV($who.notes)}
}

proc KillLove {which} {
	global MV

	DebugIt "Killing Little Hearts (poor things)!" other
	set who "$MV(LoveKill.$which)"
	.top.c delete $MV($who.love)
	#
	# Clean up the memory which this user was using.
	#
	catch {unset MV(LoveKill.$which)}
	catch {unset MV($who.love)}
}

proc KillSteam {which} {
	global MV

	DebugIt "Killing Steam!" other
	set who "$MV(SteamKill.$which)"
	.top.c delete $MV($who.steam)
	#
	# Clean up the memory which this user was using.
	#
	catch {unset MV(SteamKill.$which)}
	catch {unset MV($who.steam)}
}

proc KillIdea {which} {
	global MV

	DebugIt "Killing Idea (they are a threat to free speach and must be silenced!!" other
	set who "$MV(IdeaKill.$which)"
	.top.c delete $MV($who.idea)
	#
	# Clean up the memory which this user was using.
	#
	catch {unset MV(IdeaKill.$which)}
	catch {unset MV($who.idea)}
}

proc KillSmile {which} {
	global MV

	DebugIt "Killing Smile" other
	set who "$MV(SmileKill.$which)"
	.top.c delete $MV($who.smile)
	#
	# Clean up the memory which this user was using.
	#
	catch {unset MV(SmileKill.$which)}
	catch {unset MV($who.smile)}
}
proc KillFrown {which} {
	global MV

	DebugIt "Killing Frown" other
	set who "$MV(FrownKill.$which)"
	.top.c delete $MV($who.frown)
	#
	# Clean up the memory which this user was using.
	#
	catch {unset MV(FrownKill.$which)}
	catch {unset MV($who.frowm)}
}
proc KillWink {which} {
	global MV

	DebugIt "Killing Wink" other
	set who "$MV(WinkKill.$which)"
	.top.c delete $MV($who.wink)
	#
	# Clean up the memory which this user was using.
	#
	catch {unset MV(WinkKill.$which)}
	catch {unset MV($who.wink)}
}

proc KillBaloon {which} {
	global MV

	set who "$MV(BaloonKill.$which)"
	if {[lsearch -exact $MV(people) $who] == -1 && $who != $MV(nick)} {
		DebugIt "KillBaloon: Called KillBaloon for user which is no longer logged on." other
		set MV($who.chatque) {}
		set MV($who.haschat) 0
	}
	.top.c delete $MV($who.text)
	.top.c delete $MV($who.baloon)
	#
	# Clean up the memory this was using.
	#
	catch {unset MV($who.text)}
	catch {unset MV($who.baloon)}
	catch {unset MV(BaloonKill.$which)}

	if {[llength $MV($who.chatque)]} {
		set stuff [lindex $MV($who.chatque) 0]
		set system [string range $stuff 0 0]
		set what [string range $stuff 1 end]
		set color [string range $stuff 1 [expr [string first ":" $stuff] -1]]
		set what [string range $stuff [expr [string first ":" $stuff] +1] end]
		set MV($who.chatque) [lreplace $MV($who.chatque) 0 0]
		ProcChat $who $what 1 $system $color
	} else {
		if {[lsearch -exact $MV(people) $who] != -1 || $who == $MV(nick)} {
			set MV($who.haschat) 0
		} else {
			catch {unset MV($who.haschat)}
			catch {unset MV($who.chatque)}
		}
	}
}

proc NewPerson {who x y image xx yy size bx by} {
	global MV

	if {![string compare $who $MV(nick)]} {return}
	if {[lsearch -exact $MV(people) $who] != -1} {
		DebugIt "New User $who is already logged on" other
		return
	}
	if {[TestPosNum $x] || [TestPosNum $y] || [TestNum $xx] || \
	[TestNum $yy] || [TestPosNum $size] || [TestNum $bx] || \
	[TestNum $by]} {
		DebugIt "New User $who has invalid numerics (ignoring)" other
		return
	}
	lappend MV(people) $who
	set MV($who.name) $who
	set MV($who.downloading) 0
	set MV($who.moving) 0
	set MV($who.avatar) $image
	set MV($who.x) $x
	set MV($who.y) $y
	set MV($who.lastsaid) ""
	set MV($who.name_x_offset) $xx
	set MV($who.name_y_offset) $yy
	set MV($who.baloon_x) $bx
	set MV($who.baloon_y) $by
	set MV($who.haschat) 0
	set MV($who.nomoremove) 0
	set MV($who.chatque) {}
	set MV($who.moves) {}

	#
	# Proces Plugins!
        foreach plugin $MV(plugin.traps.NewPerson) {
                if ![$MV(plugin.traps.NewPerson.$plugin) $who $x $y $image $xx $yy $size $bx $by] {return}
        }
	
	InsertIntoChat 1 "<*>$who<*> [Trns entered_the_room]\n"
	if {![string compare $image "default.gif"]} {
		image create photo OpenVerse_User_Image_$who -file "$MV(images)/default.gif"
		set MV($who.icon) [.top.c create image $x $y -image OpenVerse_User_Image_$who]
		if $MV(names) {ShowName $who}
		DoNames
		return
	}
	if ![file exists "$MV(rem_images)/$image"] {
		image create photo OpenVerse_User_Image_$who -file "$MV(images)/default.gif"
		set MV($who.icon) [.top.c create image $x $y -image OpenVerse_User_Image_$who]
		if {[lsearch -exact $MV(downloads) $image] == -1} {
			DebugIt "I do not have $image" other
			if $MV(download_avatars) {
				SendToServer "DCCSENDAV $image"
				set MV($who.downloading) 1
			}
		}
	} else {
		if {[file size "$MV(rem_images)/$image"] != $size} {
			image create photo OpenVerse_User_Image_$who -file "$MV(images)/default.gif"
			set MV($who.icon) [.top.c create image $x $y -image OpenVerse_User_Image_$who]
			if {[lsearch -exact $MV(downloads) $image] == -1} {
				DebugIt "size mismatch for $image" other
				if $MV(download_avatars) {
					SendToServer "DCCSENDAV $image"
					set MV($who.downloading) 1
				}
			}
		} else {
			catch {image create photo OpenVerse_User_Image_$who -file "$MV(rem_images)/$image"} err
			if {[string compare $err "OpenVerse_User_Image_$who"]} {
				image create photo OpenVerse_User_Image_$who -file "$MV(images)/default.gif"
			}
			set MV($who.icon) [.top.c create image $x $y -image OpenVerse_User_Image_$who]
		}
	}
	if $MV(names) {
		ShowName $who
	}
	DoNames
}

#
# CRUISE - 11/06/2001 - Now, will not clear ignore list when user logs off.
#
proc PersonLeft {who} {
	global MV

	if {[lsearch -exact $MV(people) $who] == -1} {return}
	set idx [lsearch -exact $MV(people) $who]
	set MV(people) [lreplace $MV(people) $idx $idx]
	#
	# Proces Plugins!
        foreach plugin $MV(plugin.traps.PersonLeft) {
                if ![$MV(plugin.traps.PersonLeft.$plugin) $who] {return}
        }
	

	set MV($who.nomoremove) 1
	.top.c delete $MV($who.icon)
	InsertIntoChat 1 "<*>$who<*> [Trns left_the_room]\n"
	if $MV(names) {
		KillName $who
	}
	# 
	# Clean up the memory this user was using!
	#
	image delete OpenVerse_User_Image_$who
	catch {unset MV($who.name)}  
	catch {unset MV($who.avatar)}
	catch {unset MV($who.x)}
	catch {unset MV($who.y)}
	catch {unset MV($who.lastsaid)}
	catch {unset MV($who.name_x_offset)}
	catch {unset MV($who.name_y_offset)}
	catch {unset MV($who.baloon_x)}
	catch {unset MV($who.baloon_y)}
	catch {unset MV($who.nomoremove)}
	catch {unset MV($who.downloading)}
	catch {unset MV($who.icon)}  
	catch {unset MV($who.moves)}
	catch {unset MV($who.moving)}
	catch {unset MV($who.name_br_x)}
	catch {unset MV($who.name_br_y)}
	catch {unset MV($who.name_tl_x)}
	catch {unset MV($who.name_tl_y)}
	catch {unset MV($who.nameplate)}
	catch {unset MV($who.nametext)}
	catch {unset MV($who.chattime)}   
	catch {unset MV($who.current_x)}   
	catch {unset MV($who.current_y)}   
	catch {unset MV($who.haschat)}
	catch {unset MV($who.chatque)}
	DoNames
}

proc SanityCheck {what} {
        if {[string first "../" $what] != -1} { return 0}
        if {[string first "//" $what] != -1} { return 0}
        if {[string first "~/" $what] != -1} { return 0}
        if {[string range $what 0 0] == "/"} { return 0}
	return 1
}

#
# checks the length of stuff typped into the chat windows.
#
proc CheckLen {win} {
        if {[string length [$win get]] > 256} {
                $win delete 256 end
                bell
        }
}

#
# Sends text to the server.
#
proc SendText {} {
        global MV
        
        set stuff [$MV(chat_entry) get]
        $MV(chat_entry) delete 0 end
        lappend MV(prev) $stuff
        if {[llength $MV(prev)] > $MV(prevsave)} {
                set MV(prev) [lreplace $MV(prev) 0 0]
        }
        set MV(curprev) -1

        #
        # Process Plugins!
        #
        foreach plugin $MV(plugin.traps.SendText) {
                if ![$MV(plugin.traps.SendText.$plugin) $stuff] {return}
        }

        if {[string range $stuff 0 0] == "/"} {
                ProcessCommand $stuff
        } else {
		if $MV(rot13) {set stuff [Rot13 $stuff]}
                SendToServer "CHAT $stuff"
        }
}

#
# Checks to be sure a nick is within preset limits.
# The maximum nick length is currently 12 characters.
#
proc CheckThatNick {nick} {
        global MV
        
        set max 0
        set newnck {}
        set nck [split $nick ""]
        foreach letter $nck {
                incr max
                if {$max <= 12} {
                        switch -- $letter {
                                " " {
                                        # No spaces allowed :)
                                }
                                default {
                                        lappend newnck $letter
                                }
                        }
                }
        }
        if {[lsearch -exact $MV(people) [join $newnck ""]] != -1} {
                tk_dialog .nickInUse [Trns openverse_error] \
			[Trns nick_in_use] "" 0 [Trns ok]
                return ""
        }
        return [join $newnck ""]
}

#
proc ShowPrev {win} {
        global MV

        if ![llength $MV(prev)] {return}
        set top [expr [llength $MV(prev)] -1]
        if {$MV(curprev) <= 0} {
                set MV(curprev) $top
        } else {
                incr MV(curprev) -1
        }
        $win delete 0 end
        $win insert end [lindex $MV(prev) $MV(curprev)]
}

proc ShowNext {win} {
        global MV

        if ![llength $MV(prev)] {return}
        set top [expr [llength $MV(prev)] -1]
        if {$MV(curprev) >= $top} {
                set MV(curprev) 0
        } else {
                incr MV(curprev)
        }
        $win delete 0 end
        $win insert end [lindex $MV(prev) $MV(curprev)]
}

proc CheckNick {} {
        global MV
        
        set max 0
        set newnck {}
        set nck [split [.setup.na.l.t.nick.entry get] ""]
        foreach letter $nck {
                incr max
                if {$max <= 12} {
                        switch -- $letter {
                                " " {
                                        bell
                                        # No spaces allowed :)
                                }
                                default {
                                        lappend newnck $letter
                                }
                        }
                } else {
                        bell
                }
        }
        .setup.na.l.t.nick.entry delete 0 end
        .setup.na.l.t.nick.entry insert end [join $newnck ""]
}

proc MessageCMD {which} {
	global MV

	if {[winfo exists .msg]} {destroy .msg}
	toplevel .msg
	wm title .msg "[Trns messaging] $MV(whois.$which)"
	button .msg.send -text [Trns send] -command "SendPrivMsg $which"
	entry .msg.entry -width 60
	pack .msg.send .msg.entry -side left -fill both -expand y
	bind .msg <Return> "SendPrivMsg $which"
}

proc SendPrivMsg {which} {
	global MV

	SendToServer "PRIVMSG $MV(whois.$which) [.msg.entry get]"
	ProcChat $MV(nick) "[.msg.entry get]" 0 2 $MV(colors.privmsg.baloon)
	destroy .msg
}

proc URLCMD {which} {
	global MV

	if {[winfo exists .url]} {destroy .url}
	toplevel .url
	wm title .url "[Trns send_url] $MV(whois.$which)"

	button .url.send -text [Trns send] -command "SendPrivURL $which"
	entry .url.entry -width 60
	pack .url.send .url.entry -side left -fill both -expand y
	bind .url <Return> "SendPrivURL $which"
}

proc SendPrivURL {which} {
	global MV

	SendToServer "URL $MV(whois.$which) [.url.entry get]"
	ProcURL $MV(nick) "[.url.entry get]"
	destroy .url
}

#
# Test a variable to see if it is a number. It will return 0 if it passes
# the test, it will return 1 if it fails the test. Negative numbers are
# considered to be valid numbers in this test.
#
proc TestNum {number} {
        if {[string length [string trim $number -0123456789]]} {
                return 1
        } else {
                return 0                  
        }
}

#
# Test a variable to see if it is a number. It will return 0 if it passes
# the test, it will return 1 if it fails the test. Negative numbers are
# considered invalid numbers in this test.
#
proc TestPosNum {number} {
        if {[string length [string trim $number 0123456789]]} {
                return 1
        } else {
                return 0                  
        }
}

#
# Change the user's nick and provide a place for plugin's to link to.
#
proc ChangeNick {newnick} {
	global MV

	set MV($MV(nick).moves) {}
	set MV($MV(nick).moving) 0

	set MV(nick) "$newnick"

	set MV($MV(nick).moving) 0
	set MV($MV(nick).moves) {}

        #
        # Process Plugins!
        #
        foreach plugin $MV(plugin.traps.ChangeNick) {
                if ![$MV(plugin.traps.ChangeNick.$plugin) $newnick] {return}
        }
}

proc ColorNames {} {
	global MV

	if $MV(use_windowmanager_colors) {return}

	$MV(names_menu).m configure -bg $MV(colors.name.bg) \
		-fg $MV(colors.name.fg) -activebackground $MV(colors.name.abg) \
		-activeforeground $MV(colors.name.afg)

}

#
# CRUISE - 11/06/2001 - Will now tell the server to not send info for this user.
#
proc IgnoreUser {who how} {
	global MV
	
	set who $MV(whois.$who)
	DebugIt "Ignoring $who ($how)" other

	switch -exact -- [string tolower $how] {
		"avatar" {
			if {[lsearch -exact $MV(ignore.avatar) $who] == -1} {
				lappend MV(ignore.avatar) $who
				ChangeUserAvatar $who default.gif -4 36 0 12 -14
				SendToServer "IGNORE AVATAR $who"
			}
		}
		"effect" {
			if {[lsearch -exact $MV(ignore.effect) $who] == -1} {
				lappend MV(ignore.effect) $who
				SendToServer "IGNORE EFFECT $who"
			}
		}
		"move" {
			if {[lsearch -exact $MV(ignore.move) $who] == -1} {
				lappend MV(ignore.move) $who
				SendToServer "IGNORE MOVE $who"
			}
		}
		"speech" {
			if {[lsearch -exact $MV(ignore.speech) $who] == -1} {
				lappend MV(ignore.speech) $who
				SendToServer "IGNORE CHAT $who"
			}
		}
		"sub" {
			if {[lsearch -exact $MV(ignore.sub) $who] == -1} {
				lappend MV(ignore.sub) $who
				SendToServer "IGNORE SUB $who"
			}
		}
		"url" {
			if {[lsearch -exact $MV(ignore.url) $who] == -1} {
				lappend MV(ignore.url) $who
				SendToServer "IGNORE URL $who"
			}
		}
		"all" {
			SendToServer "IGNORE ALL $who"
			# AVATAR
			if {[lsearch -exact $MV(ignore.avatar) $who] == -1} {
				lappend MV(ignore.avatar) $who
			}
			# EFFECT
			if {[lsearch -exact $MV(ignore.effect) $who] == -1} {
				lappend MV(ignore.effect) $who
			}
			# MOVE
			if {[lsearch -exact $MV(ignore.move) $who] == -1} {
				lappend MV(ignore.move) $who
			}
			# CHAT
			if {[lsearch -exact $MV(ignore.speech) $who] == -1} {
				lappend MV(ignore.speech) $who
			}
			# SUB
			if {[lsearch -exact $MV(ignore.sub) $who] == -1} {
				lappend MV(ignore.sub) $who
			}
			# URL
			if {[lsearch -exact $MV(ignore.url) $who] == -1} {
				lappend MV(ignore.url) $who
			}
		}
	}
	DoNames
}

#
# CRUISE - 11/06/2001 - Will now tell the server to not send info for this user.
#
proc UnIgnoreUser {who how} {
	global MV
	
	set who $MV(whois.$who)
	DebugIt "UnIgnoring $who ($how)" other

	switch -exact -- [string tolower $how] {
		"avatar" {
			if {[lsearch -exact $MV(ignore.avatar) $who] != -1} {
				set idx [lsearch -exact $MV(ignore.avatar) $who]
				set MV(ignore.avatar) [lreplace $MV(ignore.avatar) $idx $idx]
				SendToServer "UNIGNORE AVATAR $who"
			}
		}
		"effect" {
			if {[lsearch -exact $MV(ignore.effect) $who] != -1} {
				set idx [lsearch -exact $MV(ignore.effect) $who]
				set MV(ignore.effect) [lreplace $MV(ignore.effect) $idx $idx]
				SendToServer "UNIGNORE EFFECT $who"
			}
		}
		"move" {
			if {[lsearch -exact $MV(ignore.move) $who] != -1} {
				set idx [lsearch -exact $MV(ignore.move) $who]
				set MV(ignore.move) [lreplace $MV(ignore.move) $idx $idx]
				SendToServer "UNIGNORE MOVE $who"
			}
		}
		"speech" {
			if {[lsearch -exact $MV(ignore.speech) $who] != -1} {
				set idx [lsearch -exact $MV(ignore.speech) $who]
				set MV(ignore.speech) [lreplace $MV(ignore.speech) $idx $idx]
				SendToServer "UNIGNORE CHAT $who"
			}
		}
		"sub" {
			if {[lsearch -exact $MV(ignore.sub) $who] != -1} {
				set idx [lsearch -exact $MV(ignore.sub) $who]
				set MV(ignore.sub) [lreplace $MV(ignore.sub) $idx $idx]
				SendToServer "UNIGNORE SUB $who"
			}
		}
		"url" {
			if {[lsearch -exact $MV(ignore.url) $who] != -1} {
				set idx [lsearch -exact $MV(ignore.url) $who]
				set MV(ignore.url) [lreplace $MV(ignore.url) $idx $idx]
				SendToServer "UNIGNORE URL $who"
			}
		}
		"all" {
			SendToServer "UNIGNORE ALL $who"
			# AVATAR
			if {[lsearch -exact $MV(ignore.avatar) $who] != -1} {
				set idx [lsearch -exact $MV(ignore.avatar) $who]
				set MV(ignore.avatar) [lreplace $MV(ignore.avatar) $idx $idx]
			}
			# EFFECT
			if {[lsearch -exact $MV(ignore.effect) $who] != -1} {
				set idx [lsearch -exact $MV(ignore.effect) $who]
				set MV(ignore.effect) [lreplace $MV(ignore.effect) $idx $idx]
			}
			# MOVE
			if {[lsearch -exact $MV(ignore.move) $who] != -1} {
				set idx [lsearch -exact $MV(ignore.move) $who]
				set MV(ignore.move) [lreplace $MV(ignore.move) $idx $idx]
			}
			# CHAT
			if {[lsearch -exact $MV(ignore.speech) $who] != -1} {
				set idx [lsearch -exact $MV(ignore.speech) $who]
				set MV(ignore.speech) [lreplace $MV(ignore.speech) $idx $idx]
			}
			# SUB
			if {[lsearch -exact $MV(ignore.sub) $who] != -1} {
				set idx [lsearch -exact $MV(ignore.sub) $who]
				set MV(ignore.sub) [lreplace $MV(ignore.sub) $idx $idx]
			}
			# URL
			if {[lsearch -exact $MV(ignore.url) $who] != -1} {
				set idx [lsearch -exact $MV(ignore.url) $who]
				set MV(ignore.url) [lreplace $MV(ignore.url) $idx $idx]
			}
		}
	}
	DoNames
}

proc RightClick {x y xx yy} {
	global MV

	# Process Plugins!
	#
	foreach plugin $MV(plugin.traps.RightClick) {
		if ![$MV(plugin.traps.RightClick.$plugin) $x $y] {return}
	}
	if $MV(names) {
		set people 0
		foreach who $MV(people) {
			if {$x >= $MV($who.name_tl_x) &&
				$x <= $MV($who.name_br_x) &&
				$y >= $MV($who.name_tl_y) &&
				$y <= $MV($who.name_br_y)} {
					if {$x < 320 && $y < 240} {set where nw;set dir left}
					if {$x < 320 && $y > 240} {set where sw;set dir left}
					if {$x < 320 && $y == 240} {set where w;set dir left}
					if {$x > 320 && $y == 240} {set where e;set dir right}
					if {$x > 320 && $y < 240} {set where ne;set dir right}
					if {$x > 320 && $y > 240} {set where se;set dir right}
					if {$x == 320 && $y > 240} {set where s;set dir left}
					if {$x == 320 && $y < 240} {set where n;set dir left}
					if {$x == 320 && $y == 240} {set where center;set dir left}
					if {[winfo exists .top.c.name]} {destroy .top.c.name}
					if $MV(use_windowmanager_colors) {
						menu .top.c.name
					} else {
						menu .top.c.name \
							-bg $MV(colors.buttons.names.bg) \
							-fg $MV(colors.buttons.names.fg) \
							-activebackground $MV(colors.buttons.names.abg) \
							-activeforeground $MV(colors.buttons.names.afg)
					}
					NameMenu .top.c.name $people $who
					tk_popup .top.c.name $xx $yy
					return
			}
			incr people
		}
	}

}

proc SendFileFromMenu {person} {
	global MV

	set file [tk_getOpenFile]
	if {[string compare $file ""]} {
		DCCSend	$MV(whois.$person) "$file"
	}
}

proc CallUser {person} {
	global MV

	SendToServer "SUB $MV(whois.$person) CALL [Trns call_msg]"
}


#
# CRUISE - 11/03/2001 - Fixed a bug here. It will  add this uer to the list
# of people we requested info from. This prevents them sending
# it to us without us wanting it.
#
proc RequestPersonal {person} {
	global MV

	#
	# We only allow one copy here.
	#
	if {[lsearch -exact $MV(personals.wanted) $MV(whois.$person)] == -1} {
		lappend MV(personals.wanted) $MV(whois.$person)
	}
	SendToServer "SUB $MV(whois.$person) GIVEPERSONAL"
}


#
# CRUISE - 10/24/2001 - Madede this work on the honor call
#
proc ProcCall {who} {
	global MV

	if $MV(honor_call) {
		InsertIntoChat 0 "\00300,04[Trns system]\00399,99 $who [Trns call_notice]"
		ProcChat $who [Trns call_msg] 0 2 $MV(colors.privmsg.baloon)
		update idletasks
		for {set d 0} {$d < 75} {incr d} {
			bell
			after 2
		}
	}
}

#
# This function will "encrypt" text using the self inversing rot13
# encryption technique. While not secure, it is still useful.
#
proc Rot13 {what} {
	set rot_what ""
	foreach letter [split $what ""] {
		switch -regexp -- $letter {
			[a-m] {set dir "+"}
			[A-M] {set dir "+"}
			[n-z] {set dir "-"}
			[N-Z] {set dir "-"}
			default {set dir 0}
		}
		if {$dir != 0} {
			binary scan $letter c* int_let
			append rot_what [format "%c" [expr $int_let $dir 13]]
		} else {append rot_what $letter}
	}
	return $rot_what
}

proc GivePersonal {who} {
	global MV
	switch -exact -- $MV(personal.availability) {
		Never {set go 0}
		Ask {
			incr MV(popup_window)
			set go [tk_dialog .personal_ask_$MV(popup_window) \
				"[Trns send_personal_info_to] $who?" \
				"$who [Trns personal_info_question]" \
				"" 0 [Trns cancel] [Trns send]]
		}
		Always {set go 1}
		default {set go 0}
	}
	if $go {
		SendToServer "SUB $who PERSONAL 1 $MV(personal.realname)"
		SendToServer "SUB $who PERSONAL 2 $MV(personal.email)"
		SendToServer "SUB $who PERSONAL 3 $MV(personal.homepage)"
		SendToServer "SUB $who PERSONAL 4 $MV(personal.sex)"
		SendToServer "SUB $who PERSONAL 5 $MV(personal.image)"
		SendToServer "SUB $who PERSONAL 6 [clock format [clock seconds] -format \"%T\"]"
		SendToServer "SUB $who PERSONAL 7 [clock format [clock seconds] -format \"%D\"]"
		set c 99
		foreach chunk [split $MV(personal.info) "\n"] {
			SendToServer "SUB $who PERSONAL $c $chunk"
			incr c
		}
		SendToServer "SUB $who PERSONAL 999 END OF INFO"
		InsertIntoChat 1 "\0030,4[Trns system]\00399,99 \00300,04$who\00399,99 [Trns personal_info_sent]\n"
	}
}


#
# CRUISE 10/24/2001 - Added a scrollbar for sketch.
# CRUISE 11/03/2001 - will only build windows for people we requested information from.
#
proc BuildPersonalInfo {who} {
	global MV


	if {[lsearch -exact $MV(personals.wanted) $MV($who.name)] == -1} {
		DebugIt "Unwanted personals information!" other
		return
	}
	set idx [lsearch -exact $MV(personals.wanted) $MV($who.name)]
	set MV(personals.wanted) [lreplace $MV(personals.wanted) $idx $idx]


	incr MV(popup_window)
	set win ".pu$MV(popup_window)"
	toplevel $win
	wm title $win "[Trns personal_info_for] $who"
	
	image create photo PERSONAL_IMAGE -file [file nativename "$MV(personal.image)"]

	frame $win.info -relief sunken -borderwidth 2
	label $win.info.txt -relief raised -text "[Trns personal_info_for] $who" \
		-borderwidth 2
	frame $win.info.meat
	frame $win.info.meat.img
	label $win.info.meat.img.img -image PERSONAL_IMAGE \
		-relief raised -borderwidth 2
	
	frame $win.info.meat.inf
	frame $win.info.meat.inf.a
	frame $win.info.meat.inf.b
	frame $win.info.meat.inf.c
	frame $win.info.meat.inf.d
	frame $win.info.meat.inf.e
	label $win.info.meat.inf.a.l -text [Trns real_name] -width 15
	label $win.info.meat.inf.b.l -text [Trns email_address] -width 15
	label $win.info.meat.inf.c.l -text [Trns home_page] -width 15
	label $win.info.meat.inf.d.l -text [Trns sex] -width 15
	label $win.info.meat.inf.e.l -text [Trns local_time]
	label $win.info.meat.inf.e.ll -text [Trns date]

	entry $win.info.meat.inf.a.e -textvariable MV($who.personal.name)
	entry $win.info.meat.inf.b.e -textvariable MV($who.personal.email)
	entry $win.info.meat.inf.c.e -textvariable MV($who.personal.webpage)
	entry $win.info.meat.inf.e.e -textvariable MV($who.personal.time)
	entry $win.info.meat.inf.e.ee -textvariable MV($who.personal.date)

	radiobutton $win.info.meat.inf.d.oa -text [Trns male] \
		-variable MV($who.personal.sex) -value [Trns male]
	radiobutton $win.info.meat.inf.d.ob -text [Trns female] \
		-variable MV($who.personal.sex) -value [Trns female]
	radiobutton $win.info.meat.inf.d.oc -text [Trns other] \
		-variable MV($who.personal.sex) -value [Trns other]
	DebugIt "(PersonalSex) - |$MV($who.personal.sex)|" other

	frame $win.info.meat.txt
	text $win.info.meat.txt.t -height 10 -width 65 -wrap word -yscrollcommand "$win.info.meat.txt.scrolly set"
	scrollbar $win.info.meat.txt.scrolly -command "$win.info.meat.txt.t yview"


	pack $win.info -side left -fill both -expand y
	pack $win.info.txt -side top -fill x -expand y
	pack $win.info.meat -side bottom -fill both -expand y
	pack $win.info.meat.txt -fill both -expand y -side bottom
	pack $win.info.meat.img -side left
	pack $win.info.meat.inf -side right -fill both -expand y
	pack $win.info.meat.img.img -side top
	pack $win.info.meat.inf.a -fill x -expand y
	pack $win.info.meat.inf.b -fill x -expand y
	pack $win.info.meat.inf.c -fill x -expand y
	pack $win.info.meat.inf.d -fill x -expand y
	pack $win.info.meat.inf.e -fill x -expand y
	pack $win.info.meat.inf.a.l -side left
	pack $win.info.meat.inf.a.e -side left -fill x -expand y
	pack $win.info.meat.inf.b.l -side left
	pack $win.info.meat.inf.b.e -side left -fill x -expand y
	pack $win.info.meat.inf.c.l -side left
	pack $win.info.meat.inf.c.e -side left -fill x -expand y
	pack $win.info.meat.inf.d.l -side left
	pack $win.info.meat.inf.d.oa $win.info.meat.inf.d.ob \
		$win.info.meat.inf.d.oc -side left -fill x -expand y
	pack $win.info.meat.inf.e.l -side left
	pack $win.info.meat.inf.e.e -side left -fill x -expand y
	pack $win.info.meat.inf.e.ll -side left
	pack $win.info.meat.inf.e.ee -side left -fill x -expand y
	pack $win.info.meat.txt.t -side left -fill both -expand y
	pack $win.info.meat.txt.scrolly -side left -fill y
	$win.info.meat.txt.t insert end $MV($who.personal.text)	
}


#
# ThrowError
#
# Usage: ThrowError "stuff"
#
# Will pop up a dialog window with an error in it giving the user only ONE
# button.... "OK" as an option, which will close the window.
#
proc ThrowError {stuff} {
	global MV
	incr MV(popup_window)
	tk_dialog .openverse_error_$MV(popup_window) \
		[Trns openverse_error] \
		"$stuff" "" 0 [Trns ok]
}
