# OpenVerse Text Chat Module
# 
# This module contains all the functions needed for the
# text chat window.
#
# Module Name		- Text Chat Module
# Sourced By		- InitMainWindow
#
# Copyright (C) 1999 David Gale <cruise@openverse.com>
# For more information visit http://www.openverse.com/
#
# Updated: 2/24/2000  Jack <jack@openverse.com>
#	   Command (no push) and Quit buttons were added.
#	   Thanks in part to John Doe.
#	   
# Updated: 2/25/2000 Jack <jack@openverse.com>
#	   Added Bubbles to the buttons.	
#
# 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.

# Turns the text chat window on or off.
# When turning on, it fills it with the last bunch of lines.
proc ToggleText {} {
	global MV

	if $MV(textwindow) {
		set MV(panel_event) [ldifference $MV(panel_event)\
				"textchat_panel_event"]
		PanelEvent textchat-close

		if $MV(swallowchat) {
			eval destroy [winfo children $MV(chatframe)]
		} else {
			destroy $MV(chatframe)
		}
		set MV(textwindow) 0
	} else {
		PanelEvent textchat-open
		set MV(panel_event) [lunion $MV(panel_event)\
				"textchat_panel_event"]

		if !$MV(swallowchat) {
			toplevel .chat
			wm geometry .chat "640x149"
			wm title .chat [Trns openverse_text_chat]
			set MV(chatframe) ".chat"
		}
		set MV(chatwindow) [winfo toplevel $MV(chatframe)]
		set MV(textwindow) 1

		frame $MV(chatframe).chat
		frame $MV(chatframe).bottom -relief sunken -bd 1
		text $MV(chatframe).chat.text -height 0 -width 0\
				-relief sunken -bd 1 -wrap word\
				-state disabled -yscrollcommand\
				"$MV(chatframe).chat.scrolly set"
		scrollbar $MV(chatframe).chat.scrolly -bd 1\
				-command "$MV(chatframe).chat.text yview"

		frame $MV(chatframe).bottom.buttons
		label $MV(chatframe).bottom.buttons.handle -relief raised\
				-image img::chat::vhandle -bd 1
		update idletasks
		frame $MV(chatframe).bottom.buttons.frame -relief flat\
				-bd 0
		foreach name {emotes effects info windows net empty death} {
			frame $MV(chatframe).$name -bd 1 -relief raised
		}
		frame $MV(chatframe).bottom.buttons.dummy -relief raised\
				-bd 1
                pack propagate $MV(chatframe).bottom.buttons.frame 0
		pack $MV(chatframe).bottom.buttons.handle -side left -fill y
		pack $MV(chatframe).bottom.buttons.frame\
				$MV(chatframe).bottom.buttons -fill both\
				-expand 1
		bind $MV(chatframe).bottom.buttons.handle <ButtonRelease-1>\
				"ChtButShowHide"
		set MV(ChtButState) show
		
		frame $MV(chatframe).bottom.l -bd 1 -relief raised
		frame $MV(chatframe).bottom.r -bd 1 -relief raised
		entry $MV(chatframe).entry -bd 0 -relief flat\
				-highlightthickness 0
		button $MV(chatframe).send -image img::chat::send\
				-command {SendText $MV(chatframe).entry}\
				-bd 1 -relief flat -width 21 -height 21
		button $MV(chatframe).log -relief flat -bd 1 -width 21\
				-height 21 -command LogTog -image img::chat::log
                button $MV(chatframe).erase -image img::chat::erase -width 21\
				-height 21 -bd 1 -command EraseChat -relief flat
                if $MV(log) {$MV(chatframe).log configure -relief sunken}
		button $MV(chatframe).scrlk -relief flat -bd 1\
				-command ToggleChatLock -width 21 -height 21
                if $MV(textwindow.lock) {
			$MV(chatframe).scrlk configure -image img::chat::lock
                } else {
			$MV(chatframe).scrlk configure -image img::chat::unlock
                }
		if $MV(tooltips) {
			Bubble::initBubble $MV(chatframe).send\
					[Trns "send_help"]
			Bubble::initBubble $MV(chatframe).log\
					[Trns "toggle_log"]
			Bubble::initBubble $MV(chatframe).erase\
					[Trns "clear_log"]
			Bubble::initBubble $MV(chatframe).scrlk\
					[Trns "scroll_lock"]
		}

                ###############################################################
		# Added command buttons; moved bottom ones to $bframe. -JACK-
		# cleaned up buttons: Unununium and djaman
		
		set num 1
		foreach emote "wink smile frown idea love sing steam hug kiss" {
			button $MV(chatframe).$num -command "SetSCHATcmd $num"\
					-width 21 -height 21 -bd 1\
					-image "img::chat::$emote"
			if {$num == $MV(TCCommand)} {
				$MV(chatframe).$num configure -relief sunken
				set MV(tc.emote) $num
			} else {
				$MV(chatframe).$num configure -relief flat
			}
			incr num
		}

		# push, whois, aved, setup, text, and connect buttons by djaman
		foreach {name action} {push "SendToServer \"PUSH 100\""
				whois "SendToServer \"WHOIS *\""
				aved "AvEd" setup "Setup"
				jump "SendToServer \"EFFECT jump\""
				shiver "SendToServer \"EFFECT shiver\""
				quit {if ![tk_dialog\
						$MV(chatframe).quitQuestion\
						[Trns really_quit]\
						[Trns quit_question] ""\
						1 [Trns quit] [Trns cancel]]\
						exit}
				} {
			button $MV(chatframe).$name -command $action -width 21\
					-height 21 -relief flat -bd 1\
					-image "img::chat::$name"
		}

		# Connect button
		button $MV(chatframe).connect -width 21 -height 21 -bd 1\
				-relief flat
		if {$MV(sock) == -1} {
			$MV(chatframe).connect configure -command Connect\
					-image img::chat::connect_no
		} else {
			$MV(chatframe).connect configure -command Disconnect\
					-image img::chat::connect_yes
		}

		# Pack the buttons
		foreach {names cont} {{1 2 3 4 5 6 7 8 9} emotes
				{jump shiver push} effects
				{whois} info
				{aved setup} windows
				{connect} net
				{quit} death} {
			foreach name $names {
				pack $MV(chatframe).$name -side left\
						-fill both\
						-in $MV(chatframe).$cont
			}
		}
		# Pack the button frames
		foreach name {emotes effects info windows net} {
			pack $MV(chatframe).$name -side left -fill y -in\
					$MV(chatframe).bottom.buttons.frame
		}
		pack $MV(chatframe).empty -side left -fill both -expand 1\
				-in $MV(chatframe).bottom.buttons.frame
		pack $MV(chatframe).death -side right -fill y\
				-in $MV(chatframe).bottom.buttons.frame
		###############################################################
		# 2/25/2000 -JACK- 
		# Added Bubbles to the command buttons
		if $MV(tooltips) {
			foreach {name msg} {quit "quit" aved "aved" setup
					"setup" whois "whois" connect "connect"
					push "push" jump "jump" shiver "shiver"
					1 "wink" 2 "smile" 3 "frown" 4 "idea" 5
					"love" 6 "sing" 7 "steam" 8 "hug" 9
					"kiss"} {
				Bubble::initBubble $MV(chatframe).$name\
						[Trns "cht_${msg}_bubble"]
			}
			Bubble::initBubble $MV(chatframe).$name\
					[Trns "cht_${msg}_bubble"]
		}	
		pack $MV(chatframe).chat -fill both -expand 1 -in $MV(chatframe)
		pack $MV(chatframe).chat.text -side left -fill both -expand 1
		pack $MV(chatframe).chat.scrolly -side right -fill y -expand 0
		pack $MV(chatframe).bottom -fill x -expand 0
		pack $MV(chatframe).bottom.buttons -side top
		pack $MV(chatframe).entry -side left -fill x -expand 1\
				-in $MV(chatframe).bottom.l
		pack $MV(chatframe).send $MV(chatframe).log\
				$MV(chatframe).erase $MV(chatframe).scrlk\
				-side left -expand 0 -in $MV(chatframe).bottom.r
		pack $MV(chatframe).bottom.l -side left -expand 1 -fill both
		pack $MV(chatframe).bottom.r -side right -expand 0

		focus $MV(chatframe).entry
		QuickKeys $MV(chatwindow)
		bind $MV(chatframe).entry <Return> {
			SendText $MV(chatframe).entry
		}
		bind $MV(chatframe) <Destroy> {
			set MV(textwindow) 0
			set MV(panel_event) [ldifference $MV(panel_event)\
					"textchat_panel_event"]
			PanelEvent textchat-close
		}
		bind $MV(chatframe).entry <Up> {ShowPrev $MV(chatframe).entry}
		bind $MV(chatframe).entry <Down> {ShowNext $MV(chatframe).entry}
		bind $MV(chatframe).entry <Control-k> {
                        $MV(chatframe).entry insert end "\003"
                }
		# These next binds enable cut and 
		# paste for Windows users. (BUG FIX, DG)
		bind $MV(chatwindow) <Control-c> ""
		bind $MV(chatwindow) <Control-v> ""
		bind $MV(chatwindow) <Control-x> ""
		bind $MV(chatframe).chat.text <ButtonPress> {
			$MV(chatframe).chat.text configure -state normal
		}
		bind $MV(chatframe).chat.text <ButtonRelease> {
			$MV(chatframe).chat.text configure -state disabled
		}
		set hp [llength $MV(chats)]
		for {set c 0} {$c < $hp} {incr c} {
			InsertIntoChat 0 [lindex $MV(chats) $c]
		}
		# Colors (damn, why did I do this)
		#	1=Black
		#	2=Navy Blue
		#	3=Dark Green 
		#	4=Bright Red 
		#	5=Brown
		#	6=Magenta 
		#	7=Orange 
		#	8=Yellow 
		#	9=Bright Green
		#	10=Bluish-Green 
		#	11=Cyan 
		#	12=Blue
		#	13=Hot Pink 
		#	14=Dark Grey 
		#	15=Light Gray 
		#	0,16=White
		#	99=normal
		#
		set w $MV(chatframe).chat.text
		$w tag configure B
		$w tag configure F
		$w tag configure B99
		$w tag configure F99
		$w tag configure F0 -foreground "white"
		$w tag configure F1 -foreground "black"
		$w tag configure F2 -foreground "navy blue"
		$w tag configure F3 -foreground "dark green"
		$w tag configure F4 -foreground "red"
		$w tag configure F5 -foreground "brown"
		$w tag configure F6 -foreground "magenta"
		$w tag configure F7 -foreground "orange"
		$w tag configure F8 -foreground "yellow"
		$w tag configure F9 -foreground "green"
		$w tag configure F00 -foreground "white"
		$w tag configure F01 -foreground "black"
		$w tag configure F02 -foreground "navy blue"
		$w tag configure F03 -foreground "dark green"
		$w tag configure F04 -foreground "red"
		$w tag configure F05 -foreground "brown"
		$w tag configure F06 -foreground "magenta"
		$w tag configure F07 -foreground "orange"
		$w tag configure F08 -foreground "yellow"
		$w tag configure F09 -foreground "green"
		$w tag configure F10 -foreground "#008080"
		$w tag configure F11 -foreground "cyan"
		$w tag configure F12 -foreground "blue"
		$w tag configure F13 -foreground "hot pink"
		$w tag configure F14 -foreground "grey66"
		$w tag configure F15 -foreground "light grey"
		$w tag configure F16 -foreground "white"
		$w tag configure B0 -background "white"
		$w tag configure B1 -background "black"
		$w tag configure B2 -background "navy blue"
		$w tag configure B3 -background "dark green"
		$w tag configure B4 -background "red"
		$w tag configure B5 -background "brown"
		$w tag configure B6 -background "magenta"
		$w tag configure B7 -background "orange"
		$w tag configure B8 -background "yellow"
		$w tag configure B9 -background "green"
		$w tag configure B00 -background "white"
		$w tag configure B01 -background "black"
		$w tag configure B02 -background "navy blue"
		$w tag configure B03 -background "dark green"
		$w tag configure B04 -background "red"
		$w tag configure B05 -background "brown"
		$w tag configure B06 -background "magenta"
		$w tag configure B07 -background "orange"
		$w tag configure B08 -background "yellow"
		$w tag configure B09 -background "green"
		$w tag configure B10 -background "#008080"
		$w tag configure B11 -background "cyan"
		$w tag configure B12 -background "blue"
		$w tag configure B13 -background "hot pink"
		$w tag configure B14 -background "grey66"
		$w tag configure B15 -background "light grey"
		$w tag configure B16 -background "white"
	}
}

proc LogTog {} {
	global MV

	if $MV(log) {
		StopLog
		PanelEvent log-off
	} else {
		StartLog
		PanelEvent log-on
	}
}

proc ChtButShowHide {} {
	global MV
	switch $MV(ChtButState) {
	show {
		pack forget $MV(chatframe).bottom.buttons.frame
		pack $MV(chatframe).bottom.buttons.dummy -fill both -expand 1\
				-after $MV(chatframe).bottom.buttons.handle\
				-side right
		$MV(chatframe).bottom.buttons.handle configure\
				-image img::chat::hhandle
		set MV(ChtButState) hide
	} hide {
		pack forget $MV(chatframe).bottom.buttons.dummy
		$MV(chatframe).bottom.buttons.handle configure\
				-image img::chat::vhandle
		update idletasks
		pack $MV(chatframe).bottom.buttons.frame -fill both -expand 1
		set MV(ChtButState) show
	}}
}

#
# Toggles the background color on emotion buttons.
#
# 11/05/2001 -Unununium- Fixed button background colors
#
# djaman and Unununium: Added 2 more buttons and cleaned up code
#
proc SetSCHATcmd {idx} {
	global MV

	if {$idx == $MV(TCCommand)} {set idx 0}

	set MV(TCCommand) $idx

	switch -- $idx {
	1 {set emote "wink"}
	2 {set emote "smile"}
	3 {set emote "frown"}
	4 {set emote "idea"}
	5 {set emote "love"}
	6 {set emote "sing"}
	7 {set emote "steam"}
	8 {set emote "hug"}
	9 {set emote "kiss"}
	default {set emote "none"}
	}

	PanelEvent emote -emote $emote
}

#
# Toggles the scroll lock on the text chat window
#
proc ToggleChatLock {} {
	global MV

	if $MV(textwindow.lock) {
		set MV(textwindow.lock) 0
		PanelEvent lock-off
	} else {
		set MV(textwindow.lock) 1
		PanelEvent lock-on
	}
}


# A short little InsertIntoChat
proc put {msg} {
	global MV

	set loc1 0
	while {$loc1 != "end"} {
		set loc2 [string_first "\n" $msg $loc1]
		if {$loc2 != -1} {
			set line [string range $msg $loc1 [expr $loc2 - 1]]
			set loc1 [expr $loc2 + 1]
		} else {
			set line [string range $msg $loc1 end]
			set loc1 "end"
		}
		$MV(chatframe).chat.text configure -state normal
		$MV(chatframe).chat.text insert end "$line\n" "F02"
		$MV(chatframe).chat.text configure -state disabled
	}
	if !$MV(textwindow.lock) {$MV(chatframe).chat.text see end}
}

#
# CRUISE - 11/04/2001 - Fixed a problem which would display multiple lines when
# users had color codes with no numbers. EW
#
proc InsertIntoChat {log what} {
	global MV

	set text $what
	set color 0
	set newtext ""
	set FG ""
	set BG ""
	if {$MV(timestamp) && $MV(textwindow)} {
		$MV(chatframe).chat.text conf -state normal
		$MV(chatframe).chat.text insert end\
		"\[[clock format [clock seconds] -format "%T"]\] "
	}
	while {[set tb [string first \x03 $text]] != -1} {
		#
		# Fixes problem with color code without a numeric.
		#
		if {[TestPosNum [string range $text [expr $tb +1] [expr $tb\
				+1]]]} {
			# We need to ignore this color code because it has not
			# number to go with it
			set string [string range $text 0 [expr $tb -1]]
			set text [string range $text [expr $tb +1] end]
			if $MV(textwindow) {
				$MV(chatframe).chat.text conf -state normal
				$MV(chatframe).chat.text insert end $string
				if !$MV(textwindow.lock) {
					$MV(chatframe).chat.text see end
				}
			}
			continue
		}
		set string [string range $text 0 [expr $tb -1]]
		set text [string range $text [expr $tb +1] end]
		if $MV(textwindow) {
			if {[regexp {^([0-9][0-9]?)(,([0-9][0-9]?))?(.*)}\
					$text m fg bl bg text]} {
				$MV(chatframe).chat.text conf -state normal
				$MV(chatframe).chat.text insert end $string\
						"$FG $BG"
				set FG "F$fg"
				set BG "B$bg"
				if !$MV(textwindow.lock) {
					$MV(chatframe).chat.text see end
				}
				set color 1
			} else {
				$MV(chatframe).chat.text conf -state normal
				$MV(chatframe).chat.text insert end $string\
						"$FG $BG"
				if !$MV(textwindow.lock) {
					$MV(chatframe).chat.text see end
				}
			}
		}
		append newtext $text
	}
	if {$color && $MV(textwindow)} {
		set parms [split $text \n]
		$MV(chatframe).chat.text conf -state normal
		$MV(chatframe).chat.text insert end [lindex $parms 0] "$FG $BG"
		$MV(chatframe).chat.text insert end "\n"
		if !$MV(textwindow.lock) {$MV(chatframe).chat.text see end}
	}
	if {$newtext == ""} {set newtext $text}
	if {$MV(textwindow) && !$color} {
		$MV(chatframe).chat.text conf -state normal
		$MV(chatframe).chat.text insert end $newtext
		if !$MV(textwindow.lock) {$MV(chatframe).chat.text see end}
	}
	if $MV(textwindow) {
		$MV(chatframe).chat.text conf -state disabled
	}
	if $log {
		lappend MV(chats) "$what"
		if {[llength $MV(chats)] > $MV(chatsave)} {
			set MV(chats) [lreplace $MV(chats) 0 0]
		}
	}
        #
	# Timestamp Patch
	#
  	if $MV(log) {
 		if {$MV(timestamp) && $MV(textwindow)} {
 			set StampedText\
			"[clock format [clock seconds] -format "%T"] $newtext"
 			LogThis "$StampedText"
 		} else {
  			LogThis "$newtext"
 		}
	}
}

proc RotTextChat {} {
	global MV
	EraseChat
	set hp [llength $MV(chats)]
	for {set c 0} {$c < $hp} {incr c} {
		set stuff [lindex $MV(chats) $c]
		set chat [string range $stuff 0 [expr [string first " "\
				$stuff] - 1]]
		append chat [Rot13 [string range $stuff [string first " "\
				$stuff] end]]
		InsertIntoChat 0 $chat
	}
}

#
# Modified by PJ7 to work correctly not that the state of the window is
# disabled to prevent it from taking focus during cut-n-paste.
#
proc EraseChat {} {
	global MV

	if $MV(textwindow) {
		$MV(chatframe).chat.text conf -state normal
		$MV(chatframe).chat.text delete 0.0 end
		$MV(chatframe).chat.text see end
		$MV(chatframe).chat.text conf -state disabled
	}
}

# An event handler, as if text chat was a panel
proc textchat_panel_event {event args} {
	global MV

	set emote ""

	# Collect arguments
	while 1 {
		if ![arg_pop arg args] break
		switch -- $arg {
		"-emote" {if ![arg_pop emote args] return}
		}
	}

	# Handle events
	switch -- $event {
	"aved-open" {$MV(chatframe).aved configure -relief sunken}
	"aved-close" {$MV(chatframe).aved configure -relief flat}
	"setup-open" {$MV(chatframe).setup configure -relief sunken}
	"setup-close" {$MV(chatframe).setup configure -relief flat}
	"emote" {
		if {$MV(tc.emote) != 0} {
			$MV(chatframe).$MV(tc.emote) configure -relief flat
		}
		switch -- $emote {
		"none" {set MV(tc.emote) 0}
		"wink" {set MV(tc.emote) 1}
		"smile" {set MV(tc.emote) 2}
		"frown" {set MV(tc.emote) 3}
		"idea" {set MV(tc.emote) 4}
		"love" {set MV(tc.emote) 5}
		"sing" {set MV(tc.emote) 6}
		"steam" {set MV(tc.emote) 7}
		"hug" {set MV(tc.emote) 8}
		"kiss" {set MV(tc.emote) 9}
		}
		if {$MV(tc.emote) != 0} {
			$MV(chatframe).$MV(tc.emote) configure -relief sunken
		}
	} "connecting" {
		$MV(chatframe).connect configure\
				-image img::chat::connect_create
	} "connect" {
		$MV(chatframe).connect configure -command Disconnect\
				-image img::chat::connect_yes
	} "disconnect" {
		$MV(chatframe).connect configure -command Connect\
					-image img::chat::connect_no
	} "lock-on" {
		$MV(chatframe).scrlk configure -image img::chat::lock
	} "lock-off" {
		$MV(chatframe).scrlk configure -image img::chat::unlock
	} "log-on" {
		$MV(chatframe).log configure -relief sunken
	} "log-off" {
		$MV(chatframe).log configure -relief flat
	}}
}

