#! /usr/bin/python
#-*- coding: utf-8 -*-

# Mucous - a curses client for museek 
# Based on Museekchat
# Config-parsing code modified from Nicotine's config.py
##-*- coding: iso-8859-1 -*-
# Copyright (C) 2003-2004 Hyriand <hyriand@thegraveyard.org>
#
# Majority of code by daelstorm (C) 2005-2006
#
# 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

import sys
try:
	import mucipher
except:
	print "WARNING: The Mucipher Module for Python wasn't found. This is absolutely necessary to allow Mucous to connect to the Museek Daemon.\nDownload it here: http://thegraveyard.org/files/pymucipher-0.0.1.tar.gz\nExtract the tarball, and as Root or sudo, run:\npython setup.py install\nYou'll need GCC, Python and SWIG."
	sys.exit()
try:
	import messages, driver
except:
	try:
		from museek import messages, driver
	except:
		print "WARNING: The Museek Message-Parsing modules, messages.py and/or driver.py  were not found. Please install them into your '/usr/lib/python2.X/site-packages/museek' directory, or place them in a 'museek' subdirectory of the directory that contains the mucous python scipt."
		sys.exit()
	
import signal, time, os, commands, getopt, threading, select, string, re, ConfigParser
import curses.wrapper, curses.ascii

from time import sleep

from UserDict import UserDict

subprocess_fail=0
geoip_fail=0

try:
	import subprocess
except ImportError:
	subprocess_fail=1
try:
	import GeoIP
	gi = GeoIP.new(GeoIP.GEOIP_MEMORY_CACHE)
except ImportError:
	geoip_fail=1
	print "Optional Python Module GeoIP not found, you can safely disregard this message."

config_dir = str(os.path.expanduser("~/.mucous/"))
log_dir = None #str(os.path.expanduser("~/.mucous/logs/"))
config_file = config_dir+"config"
try:
	from pymucous.utils import Version
except:
	print "WARNING: can't find pymucous.utils, setting version to be unknown."
	Version = "unknown"
	
def usage():
	print ("""Mucous is a client for Museek, the P2P Soulseek Daemon
Author: Daelstorm
Credit: Hyriand
Version: %s
	Default options: none
	-c,	--config <file>	Use a different config file
	-l,	--log <dir>	Use a different logging directory
	-v,	--version	Display version and quit

	-h,	--help		Display this help and exit
	""" %Version)
	sys.exit(2)
	
try:
	opts, args = getopt.getopt(sys.argv[1:], "hc:vl:p", ["profile", "help", "config=", "version", "log="])
except getopt.GetoptError:
	usage()
	sys.exit(2)
profile = 0
for opts, args in opts:

	if opts in ("-p", "--profile"):
		profile = 1
	elif opts in ("-h", "--help"):
		usage()
		sys.exit()
	if opts in ("-c", "--config"):
		config_file=str(os.path.expanduser(args))
	if opts in ("-l", "--log"):
		log_dir=str(os.path.expanduser(args))
	if opts in ("-v", "--version"):
		print "Mucous version: %s" % Version
		sys.exit(2)
		
parser = ConfigParser.ConfigParser()
# default config
mucous_config = {"connection":{"interface":'localhost:2240', "passw":None}, \
	"mucous":{"autobuddy": "no", "roomlistminsize": 5, "rooms_sort": "size", \
	"roombox": "big", "log_dir": "~/.mucous/logs/", "now-playing": "default", \
	"now-playing-prefix": None, "browse_display_mode": "filesystem", "browse_width": 25, \
	"url reader": "firefox", "url custom prefix": "", "url custom suffix": "", \
	"transbox" : "split", "language": "iso-8859-1", "beep": "yes", "autoaway": "yes", \
	"auto-retry": "yes", "auto-clear": "no", "logging": "yes", "extra_requests": "Yes"}, \
	"tickers":{'tickers_enabled': 'yes', "ticker_cycle": "no", "rooms":{}, "ticker_scroll": "yes", "scrolltime": "0.3", "cycletime": "3.0"}, \
	"aliases": {"mucous":"Mucous is a Curses client for the Museek Soulseek Daemon. Website: http://thegraveyard.org/daelstorm/mucous.php", "museek":"Museek+ is a Soulseek Daemon/Client. The website is http://museek-plus.org/"},\
	"rooms": {"default_room":"museek"}\
	}
		

	
class SortedDict(UserDict):
	def __init__(self):
		self.__keys__ = []
		self.__sorted__ = True
		UserDict.__init__(self)
	def __setitem__(self, key, value):
		if not self.__dict__.has_key(key):
			self.__keys__.append(key) 
			self.__sorted__ = False   
		UserDict.__setitem__(self, key, value)
	def __delitem__(self, key):
		self.__keys__.remove(key)
		UserDict.__delitem__(self, key)
	def keys(self):
		if not self.__sorted__:
			self.__keys__.sort()
			self.__sorted__ = True
		return self.__keys__
	def items(self):
		if not self.__sorted__:
			self.__keys__.sort()     
			self.__sorted__ = True
		for key in self.__keys__:
			yield key, self[key]		
alpha_list  = SortedDict()

def create_config():

	parser.read([config_file])

	mucous_config_file = file(config_file, 'w')
	
	for i in mucous_config.keys():
		if not parser.has_section(i):
			parser.add_section(i)
		for j in mucous_config[i].keys():
			if j not in ["nonexisting", "hated", "options"]:
				parser.set(i,j, mucous_config[i][j])
			else:
				parser.remove_option(i,j)
	parser.write(mucous_config_file)
	mucous_config_file.close()	


def read_config():
	
	parser.read([config_file])
	for i in parser.sections():
		for j in parser.options(i):
			val = parser.get(i,j, raw = 1)

			if j in ['login','passw','interface', 'roombox', 'tickers_enabled', "ticker_cycle", "ticker_scroll", "scrolltime", "cycletime", 'default_room', "autobuddy", "now-playing", "log_dir", "aliases" "now-playing-prefix", "browse_display_mode", "url reader", "url custom prefix", "url custom suffix", "transbox", "autoaway", "rooms_sort", "logging", "beep", "auto-clear", "auto-retry", "extra_requests"] :
				if val != "None":
					mucous_config[i][j] = val
			elif i == 'aliases':
				if val != "None":
					mucous_config[i][j] = val
			else:
				try:
					mucous_config[i][j] = eval(val, {})
				except:
					mucous_config[i][j] = None

def update_config():
	mucous_config_file = file(config_file, 'w')
	for i in mucous_config.keys():
		if not parser.has_section(i):
			parser.add_section(i)
		for j in mucous_config[i].keys():
			if j not in ["somethingwrong"]:
				parser.set(i,j, mucous_config[i][j])
			else:
				parser.remove_option(i,j)
	parser.write(mucous_config_file)
	mucous_config_file.close()
	
def check_path():
	if os.path.exists(config_dir):
		if os.path.exists(config_file) and os.stat(config_file)[6] > 0:
			read_config()
		else:
			create_config()
			
	else:
		os.mkdir(config_dir, 0700)
		create_config()
check_path()

if log_dir != None and log_dir != "":
	mucous_config["mucous"]["log_dir"] = str(os.path.expanduser(log_dir))
	
elif "log_dir" in mucous_config["mucous"]:
	if mucous_config["mucous"]["log_dir"] in ("", None, "None"):
		mucous_config["mucous"]["log_dir"] = str(os.path.expanduser("~/.mucous/logs/"))

if str(mucous_config["mucous"]["logging"]) == "True":
	mucous_config["mucous"]["logging"] = "yes"

		
## This is the input line/bar
class CharacterParse(threading.Thread):
	## Constructor
	# @param self is CharacterParse
	# @param win is mucous.Editwin
	# @param mucous is the mucous class
	def __init__(self, win, mucous):
		threading.Thread.__init__(self)
		self.win = win
		self.mucous = mucous
		self.InputFunctions = mucous.InputFunctions
		self.InputTabCompletion = mucous.InputTabCompletion
		self.InputHistory = mucous.InputHistory
		self.h, self.w = win.getmaxyx()
		self.scroll = 0
		self.line = mucous.line
		self.x = len(self.line)
		self.fixpos()
		self.escape = False
		self.y = None
		self.word = None
		self.listline = mucous.listline
		self.firsttab = 0
		
	## Add normal characters to the line, or respond to escaped characters or mouse presses
	def process(self, c):
		try:
			pos = self.x + self.scroll
			
			# debugging: display keypress
			#self.mucous.Hlog("debug", c )
			
			# Toggle online ONLY if inactivity timeout was met
			if self.mucous.timedout == True:
				self.mucous.ToggleAwayStatus()
				self.mucous.timedout = False
			if self.mucous.Spl["status"] == 0 and mucous_config["mucous"]["autoaway"] == "yes":
				# Restart inactivity timeout for every key or mousepress if not away, currently
				self.mucous.timeout_timer.cancel()
				self.mucous.timeout_timer = threading.Timer(self.mucous.timeout_time, self.mucous.timeout)
				self.mucous.timeout_timer.start()
			else:
				self.mucous.timeout_timer.cancel()

	
			if c != chr(9) and c !="KEY_MOUSE":  # Clear self.word if tab wasn't pressed
				self.word = None
				self.firsttab = 0
				self.listline = []
			elif c not in ("KEY_UP", "KEY_DOWN"):
				self.mucous.Spl["history_count"] = -1

			if c == "KEY_MOUSE":
				error = 'mouse'
				if not self.escape:
					line = self.InputFunctions(c, self.line)
					if line != None:
						self.line = line
						self.x = len(self.line)
			elif c == "KEY_LEFT" or c == chr(2):
				error = 'left'
				if self.escape:
					self.InputFunctions(c, self.line)
				else:
					self.x -= 1
			
			elif c == "KEY_RIGHT" or c == chr(6):
				error = 'right'
				if self.escape:
					self.InputFunctions(c, self.line)
				else:
					self.x += 1
			elif c in ("KEY_F(1)", "KEY_F(2)", "KEY_F(3)", "KEY_F(4)", "KEY_F(5)", "KEY_F(6)", "KEY_F(7)", "KEY_F(8)", "KEY_F(9)", "KEY_F(10)"):
				if not self.escape:
					self.InputFunctions(c, self.line)
				
			elif c in ("KEY_UP", "KEY_DOWN"):
				# Scrolling
				if not self.escape:
					line = self.InputFunctions(c, self.line)
					if line != None:
						self.line = line
						self.x = len(self.line)
					
				elif self.escape:
					# Alt+Up/Down
					line, self.mucous.Spl["history_count"] = self.InputHistory(c, self.line, self.mucous.Spl["history_count"])
					if line is not None:
						self.line = line
						self.x = len(self.line)
			elif c in ("KEY_SELECT", "KEY_FIND", "KEY_PPAGE", "KEY_NPAGE", "KEY_HOME", "KEY_END"): 
				# Scrolling
				if c == "KEY_SELECT":
					c = "KEY_NPAGE"
				elif c == "KEY_FIND":
					c = "KEY_PPAGE"
				if not self.escape:
					line = self.InputFunctions(c, self.line)
					if line != None:
						self.line = line
						self.x = len(self.line)
			elif c == "KEY_IC": # Insert
				self.InputFunctions(c, self.line)
			
			elif c in ("t", "T", "p", "P", "d", "D", "x", "X"):
				if self.escape:
					if c in ("t", "T"):
						self.InputFunctions("switch", self.line)
					elif c in ("d", "D"):
						self.InputFunctions("delete", self.line)
					elif c in ("p", "P"):
						self.InputFunctions("popup", self.line)
					elif c in ("x", "X"):
						self.InputFunctions("collapse", self.line)
				else:
					self.line = self.line[:pos] + c + self.line[pos:]
					self.x += 1
			elif c == chr(1): 
				# Ctrl-A
				self.x = self.scroll = 0
			elif c == chr(5):
				# Ctrl-E
				self.x = len(self.line)
			# elif c == chr(32):
				#self.mucous.Hlog("debug", "space")
			# elif c == chr(13):
				#pass
				#self.mucous.Hlog("debug", "carriage")
			elif c == "KEY_ENTER" or c == chr(10):
				# Keypad Enter, Normal Enter, or Newline pasted from another app
				if self.mucous.Spl["show_menu"] == True:
					self.mucous.MenuEnter()
				else:
					self.escape = False
					self.InputFunctions(c, self.line)
					return True
			
			
			elif c == chr(9): 
				# Tab
				if self.word == None:
					#self.x
					#w = self.line.split(' ')
					#self.word = w[-1]
					w = self.line[:self.x].split(' ')
					
					self.word = w[-1]
					self.listline = self.line.split(" ")
				w = self.line[:self.x].split(' ')
				lw = len(w)
				cpos = lw - 1
				currentword = w[cpos]
				if self.firsttab == None:
					self.firsttab = 0
				# if a space is in currentword, it won't be in the listline, so match it with a multi-space word
				#self.mucous.Hlog("debug", self.word)
				if currentword not in self.listline:
					for word in self.listline:
						if word.upper().endswith(currentword.upper()):
							currentword = word
							cpos = self.listline.index(currentword)
							
				self.listline, self.firsttab, self.word, xpos = self.InputTabCompletion(self.line, self.word, self.firsttab, self.listline, cpos)
				if self.listline == []:
					return False
				self.line = ''
				# position in listline
				posx = 0
				# segments in listline
				ll = len(self.listline) -1
				# put line back together
				for r in self.listline:
					
					if posx != ll:
						self.line += r +' '
						# place cursor at end of current word
						if posx == xpos:
							self.x = len(self.line)-1
					elif posx == ll:
						self.line +=r
						# Place cursor at end of line
						if posx == xpos:
							self.x = len(self.line)
					posx += 1
				
				#self.x = len(self.line)
				#return False
			elif c == chr(11): 
				# Ctrl-K
				# Delete everything after cursor position
				self.line = self.line[:pos]
				self.x = len(self.line)
				self.scroll = 0
			elif c == chr(21): 
				# Ctrl-U
				# Delete line
				self.line = ''
				self.x = 0
			elif c == chr(23): 
				# Ctrl-W
				# Delete word before cursor
				z = self.line.split(' ')
	
				if len(z) >1:
					if z[-1] != ' ' and z[-1] != '':
						self.line = ''
						for s in z:
							if s is not z[-1]:
								self.line = self.line + s +" "
							elif s is z[-1]:
								self.line = self.line
								break
					else:
						self.line = ''
						for s in z:
							if s not in (z[-1], z[-2]):
								self.line = self.line + s +" "
							elif s is z[-2]:
								self.line = self.line
								break
				else:
					self.line = ''
				self.x = len(self.line)
			elif c == chr(27):
				# Escape ^[
				if self.mucous.Spl["show_menu"] == True:
					self.mucous.MenuClear()
				else:
					self.escape = True
					return False
			elif c == chr(93) or c == chr(91) or c == chr(60) or c == chr(62):
				# ], [, <, >
				if self.escape:
					self.InputFunctions(c, self.line)
				else:
					self.line = self.line[:pos] + c + self.line[pos:]
					self.x += 1
			elif c == "KEY_DC"  or c == chr(4):
				# Delete
				# Delete letter after cursor
				self.line = self.line[:pos] + self.line[pos+1:]
			elif c == "KEY_BACKSPACE" or c == chr(8) or c == chr(127):
				# Backspace, Ctrl-H
				# Delete letter before cursor
				if pos > 0:
					self.line = self.line[:pos-1] + self.line[pos:]
					self.x -= 1
	
			elif len(c) == 1 and ord(c[0]) >= 32 and ord(c[0]) < 127:
				# ASCII letters 
				self.line = self.line[:pos] + c + self.line[pos:]
				self.x += 1
			elif len(c) == 1 and ord(c[0]) > 127 and ord(c[0]) < 256:
				# ISO8859-* characters
				self.line = self.line[:pos] + c + self.line[pos:]
				self.x += 1
	
			self.fixpos()
			self.mucous.line = self.line
			self.escape = False
			return False
		except Exception, e:
			self.mucous.Hlog("debug", "CharacterParse process: \""+str(self.line)+"\" "+ str(e))
			
	## Allow for horizontal scrolling of line
	def fixpos(self):
		try:
			self.x1 = self.x
			if self.x1 <= 0:
				self.x1 = 0	
			while self.scroll + self.x > len(self.line):
				self.x -= 1
				
			while self.x >= self.w:
				self.scroll += 1
				
				self.x -= 1
			if self.x < 0:
				self.scroll += self.x
				
				self.x = 0
	
			if self.scroll < 0:
				self.scroll = 0
	
			self.win.erase()
	
			try:
				self.win.addstr(self.line[self.scroll:self.scroll+self.w-1])
			except Exception, e:
				self.mucous.Hlog("debug", "Editwin: "+ str(e))
			self.win.refresh()
		except Exception, e:
			self.mucous.Hlog("debug", "fixpos: \""+str(self.line)+"\" "+ str(e))
			
	## Delete contents of line
	def reset(self):
		try:
			self.x = self.scroll = 0
			self.mucous.line = self.line = ""
	
			self.win.erase()
			self.win.refresh()
		except Exception, e:
			self.mucous.Hlog("debug", "reset: \""+str(self.line)+"\" "+ str(e))

## Main class
class mucous(driver.Driver):
	## Constructor
	def __init__(self):
		
		driver.Driver.__init__(self)
		self.config = {}
		self.usernames = {"username": None, "download": None, "private":None, "info": None, "upload": None, "search": None, "privileges": None, "browse": "default__"}
		self.Spl = {"menunumber": 0, "title": None,  "status": None, "connected": 0, \
		"room": None, "history_count": 0, "current_search": "default__",  "dir_browse": "", \
		"search_method": "globally", "search_order": "num", "show_menu": False, \
		"current_menu": None, "setup_input": "default", "interests_input": "add_likes", \
		"ticker_room": None, "uploads": 0, "downloads": 0 , "search_reverse": False, \
		"recommend_sort": "alpha", "ticker_num":  0, "downloaddir": os.path.expanduser("~/"), \
		"museekconfigfile": ""}
		self.data = {"rooms": {}, "tickers": {}, "shares": {} , "roomlist": {}, "search_tickets": {}, "search_results": {}, "browse_num": {}, "browse_results": {}, "mystats": [], "downloads": {}, "uploads": {}, "recommendations": {}, "similar_users": {}, "collapsed_dirs":{} }
		self.logs = {"buddied": [], "banned": [], "ignored": [], "trusted": [], "uploads": "Up: 0", "downloads": "Down: 0", "tab_completion": [], "search_count": ["Results: ", 0], "history": [], "alert": "", "onlinestatus": "Offline", "info": {}, "private": {}, "rooms": {}, "browse": {}, "search":{} , "roombox": {} , "roomstatus": {} , "recommendations": [], "likes": [], "hates": [], "similar_users":[]    }
		self.activeitems = {"info": [], "search": [], "browse": [], "private": [], "positions": {}}
		self.requests = {"ip":[], "info": [], "statistics": [], "browse": []}
		self.transfers = {"downloads": {}, "uploads": {} }
		self.display = {"mode": "chat", "list": "buddied", "interests": "recommendations", "chatshape": mucous_config["mucous"]["roombox"], "chat": "chatroom", "browse": "directories", "setup": "mucous", "password": "no", "transfers": "downloads", "transfer_sort": "all", "t_speed": True}
		self.modes = {"setup":  ["mucous", "museek", "shares", "userinfo", "logs"], "transfers": ["all","active",  "queued", "finished", "failed"] }
		self.user = { "status": {}, "statistics": {}  }
		self.windows = {"text": {}, "border": {}, "dimensions": {}, "browse": {}, "tab": {} }
		self.scrolling = {"chatroom": -1, "roombox": 0, "roomstatus": -1, "info": 0, "private": 0, "browsefile": 0, "browsedir": 0, "likes": 0, "hates": 0, "recommendations": 0, "similar_users": 0, "help":0, "debug": 0, "search": 0, "uploads": 0, "downloads": 0, "buddied": 0, "banned": 0, "ignored": 0, "trusted": 0, "roomlist":0 }
		self.menus = {}

		self.url = None
		self.bfilter = None

		self.timedout = False
		self.listline = [] # Tab Completion Line (split)

		# transfers
		self.sorted_transfer_list = {}
		self.last_transferscroll = None

		# searches
		self.search_user = None
		self.sfilter= None
		self.search_number = 0

		
		self.sorted_search = []

		# config
		self.invalidpass = 0
		
		self.line = "" # Input Line
		
		# Encodings
		# Recommended: ISO-8859-1
		# UTF-16 AND ISO-8859-12 crash Mucous
		# UTF-8 is bad, since it's usually the original encoding being converted from
		self.encodings  = ['iso-8859-1', 'iso-8859-2', 'iso-8859-3', 'iso-8859-4', 'iso-8859-5', 'iso-8859-6', 'iso-8859-7', 'iso-8859-8', 'iso-8859-9', 'iso-8859-10', 'iso-8859-11', 'iso-8859-13', 'iso-8859-14', 'iso-8859-15', 'utf-8', 'utf-7',  'ascii']
		if "language" in mucous_config["mucous"]:
			if mucous_config["mucous"]["language"] not in self.encodings:
				mucous_config["mucous"]["language"] = "iso-8859-1"
		else:
			mucous_config["mucous"]["language"] = "iso-8859-1"
		self.states = {0: "Finished", 1: "Xferring", 2: "Negotiating", 3:"Waiting", 4: "Establishing", 5: "Initiating", 6: "Connecting",  7: "Queued", 8:"Address", 9:  "Status", 10: "Offline",11: "Closed",12: "Can't Connect", 13: "Aborted",14: "Not Shared"}
		self.alert = { "CHAT": {}, "PRIVATE": [], "TRANSFERS" : [],  "SEARCH": [], "INFO": [], "BROWSE": [],  "HELP": [] }
		
		# Help Logs
		self.HelpPages()
		
		# timers
		self.retry_timer = threading.Timer(30.0, self.ThreadTransfersRetry)
		self.clear_timer = threading.Timer(30.0, self.ThreadTransfersClear)
		self.timer = threading.Timer(10.0, self.ThreadNickCheck)
		self.muscan_timer = threading.Timer(1.0, self.ThreadMuscan)
		self.timeout_time =  900 * 1.0
		self.timeout_timer = threading.Timer(self.timeout_time, self.timeout)
		if mucous_config["tickers"]["ticker_cycle"] == "yes":
			time = float(mucous_config["tickers"]["cycletime"])
		if mucous_config["tickers"]["ticker_scroll"] == "yes":
			time = float(mucous_config["tickers"]["scrolltime"])
		self.ticker_timer = threading.Timer(time, self.DrawTicker)
		
		if "ticker_cycle" in mucous_config["tickers"].keys():
			pass
		else:
			mucous_config["tickers"]["ticker_cycle"] = "yes"
		# Help lists
		self.commandlist =  ["/me", "/j", "/join", "/p", "/part", "/l", "/leave", "/talk", "/say", "/alias", "/list", "/users", \
"/cd",  "/get", "/getdir", "/nick", "/privs", "/privileges", "/giveprivs",\
"/help", "/info",  "/autojoin", "/roombox", "/autoaway", "/transbox", "/roomlist", "/roomlistrefresh", \
"/inrooms", "/pm",  "/msg", "/np", "/npset", "/npcheck", "/browsewidth", \
"/npprefix", "/tickroom", "/tickcycle",  "/listtick", "/tickers", "/interface", "/password",\
"/save", "/connect", "/disconnect", "/autobuddy", "/autoclear", "/autoretry", "/privbuddy", "/onlybuddy",\
"/slots","/buddy", "/unbuddy",  "/ban", "/banlist", "/beep", "/trust", "/distrust", "/unban", "/nuke", "/unnuke",\
"/ignore", "/unignore",  "/unhide",  "/userinfo", "/ip", "/stat", "/away", "/abortup", "/percent", \
"/abortdown",  "/removeup", "/removedown", "/retry", "/retryall", "/clearup", "/cleardown", "/clearroom", "/clearsearchs", "/url", "/urlreader", "/urlcustom",\
"/search", "/searchfor", "/searchbuddy", "/searchroom", "/download", "/downdir", "/browse",\
"/browseuser", "/browsesearch", "/browsedown",  "/downuser",\
"/downpath", "/downpathdir",  "/chat", "/ignorelist", "/banlist", "/transfer", "/transfers", "/private",\
"/buddylist", "/setup", "/quit", "/logging", "/logdir", "/reloadshares", "/rescanshares", "/version", "/extra", \
"/logout", "/login", "/like", "/donotlike", "/donothate", "/hate", "/similar", "/globalrex", "/recommendations", "/rex", "/itemsimilar", "/itemrex", "/uploadto", "/upload", "/ctcpversion", "/defaulttick", "/settemptick", "/settick "]
		
		for alias in mucous_config["aliases"].keys():
			self.commandlist.append("/"+alias)
	
		# Startup Size Check
		self.stdscr = curses.initscr()
		#curses.flushinp()
		#curses.setupterm()
		#self.helplog.append(str(curses.termattrs() ) )
		#self.helplog.append(str(curses.termname() ))
		curses.meta(1)
		h, w = self.stdscr.getmaxyx()
		#h,w = struct.unpack("HHHH", fcntl.ioctl(sys.stdout.fileno(),termios.TIOCGWINSZ, struct.pack("HHHH", 0, 0, 0, 0)))[:2]
		if  h <=7 or w <=37:
			self.stdscr.keypad(1)
			curses.echo()
			curses.endwin()
			print "Console kinda small, resize it, please"
			sys.exit()
		#---------------
		
		curses.start_color()
		curses.mousemask(curses.ALL_MOUSE_EVENTS)
		curses.mouseinterval(110)
		self.colors = {}
		if curses.has_colors() == True:
			try:
				curses.use_default_colors()
				curses.can_change_color()
				curses.init_pair(1, curses.COLOR_RED, -1)
				curses.init_pair(2, curses.COLOR_YELLOW, -1)
				curses.init_pair(3, curses.COLOR_CYAN, -1)
				curses.init_pair(4, curses.COLOR_BLUE, -1)
				curses.init_pair(5, curses.COLOR_GREEN, -1)
				curses.init_pair(6, curses.COLOR_BLACK, -1)
				curses.init_pair(7, curses.COLOR_WHITE, -1)
				curses.init_pair(8, curses.COLOR_MAGENTA, -1)
				curses.init_pair(9, 0, curses.COLOR_CYAN)
				curses.init_pair(10, curses.COLOR_GREEN, curses.COLOR_BLACK )
				curses.init_pair(11, curses.COLOR_YELLOW, curses.COLOR_BLUE)
				curses.init_pair(12, curses.COLOR_BLACK, curses.COLOR_WHITE)
			except AttributeError:
				curses.init_pair(1, curses.COLOR_RED, 0)
				curses.init_pair(2, curses.COLOR_YELLOW, 0)
				curses.init_pair(3, curses.COLOR_CYAN, 0)
				curses.init_pair(4, curses.COLOR_BLUE, 0)
				curses.init_pair(5, curses.COLOR_GREEN, 0)
				curses.init_pair(6, curses.COLOR_BLACK, curses.COLOR_WHITE)
				curses.init_pair(7, curses.COLOR_WHITE, 0)
				curses.init_pair(8, curses.COLOR_MAGENTA, 0)
				curses.init_pair(9, 0, curses.COLOR_CYAN)
				curses.init_pair(10, curses.COLOR_GREEN, curses.COLOR_BLACK )
				curses.init_pair(11, curses.COLOR_YELLOW, curses.COLOR_BLUE)
				curses.init_pair(12, curses.COLOR_BLACK, curses.COLOR_WHITE)
				
			self.colors["red"] = curses.color_pair(1)
			self.colors["yellow"] = curses.color_pair(2)
			self.colors["cyan"] =  curses.color_pair(3)
			self.colors["blue"] = curses.color_pair(4)
			self.colors["green"] =  curses.color_pair(5)
			self.colors["black"] = curses.color_pair(6)
			self.colors["white"] = curses.color_pair(7)
			self.colors["magenta"] = curses.color_pair(8)
			self.colors["cybg"] = curses.color_pair(9)
			self.colors["greenbg"] = curses.color_pair(10)
			self.colors["hotkey"] = curses.color_pair(11)
			self.colors["blafgcyabg"] = curses.color_pair(12)
		else:
			self.colors["blafgcyabg"]  = self.colors["hotkey"] = self.colors["greenbg"] = self.colors["cybg"] = self.colors["magenta"] = self.colors["white"] =self.colors["black"]  = self.colors["cyan"] =  self.colors["yellow"] =self.colors["blue"]  =self.colors["green"] = self.colors["red"] =  curses.color_pair(0)
			#Disable cursor (bad idea)
# 			curses.curs_set(0)
		
		while 1:
			try:
				curses.noecho()
			except:
				pass
			try:
				curses.cbreak()
			except:
				pass
			self.stdscr.keypad(1)
			try:
				 self.line = self.build()
			except Exception, e:
				self.Hlog("debug", str(e) )
				sleep(1)
			if self.socket is None:
				self.connect()
			try:
				self.process()
			except select.error, e:
				self.line = self.build()
				# Terminal resized
				pass
			except Exception, e:
				self.ModeHelp()
				self.Hlog("status", "Shutting Down Mucous.. " +str(e) )
				sleep(1)
				self.shutdown()

	
	## Create curses parent window, get terminal size, draw windows
	def build(self):
# 		h, w = struct.unpack("HHHH", fcntl.ioctl(sys.stdout.fileno(),termios.TIOCGWINSZ, struct.pack("HHHH", 0, 0, 0, 0)))[:2]
# 		os.environ["LINES"] = str(h)
# 		os.environ["COLUMNS"] =str(w)

		try:
			self.stdscr = curses.initscr()
			self.stdscr.erase()
			self.stdscr.refresh()
			self.h, self.w = self.stdscr.getmaxyx()
			# Clean stale windows
			if "input" in self.windows["text"]:
				del self.windows["text"]["input"]
			if "input" in self.windows["border"]:
				del self.windows["border"]["input"]
				
			w = self.windows["dimensions"]["input"] = {"height":1, "width":self.w-2, "top":self.h-3, "left":1}	
			bi = self.windows["border"]["input"] = curses.newwin(w["height"]+2, w["width"]+2, w["top"]-1, w["left"]-1)
			bi.attron(self.colors["blue"])
			bi.border()
			bi.refresh()
			
			self.windows["text"]["input"] = bi.subwin(w["height"], w["width"], w["top"], w["left"])
			self.windows["text"]["input"].attroff(self.colors["blue"])
			self.ModeTopbar()

			self.Spl["show_menu"] = False
		except Exception, e:
			self.Hlog("debug", "Build: " + str(e))
		try:
			if self.display["mode"] == "chat":
				self.ModeChatRooms()

			elif self.display["mode"] == "private":
				self.ModePrivate()

			elif self.display["mode"] == "browse":
				self.ModeBrowse()

			elif self.display["mode"] == "transfer":
				self.ModeTransfers()

			elif self.display["mode"] == "info":
				self.ModeInfo()
				
			elif self.display["mode"] == "search":
				self.ModeSearch()
				
			elif self.display["mode"] == "lists":
				self.ModeLists()
				
			elif self.display["mode"] == "roomlist":
				self.ModeRoomsList()
				
			elif self.display["mode"] == "setup":
				self.ModeSetupDefault()
				
			elif self.display["mode"] in ("debug", "help"):
				self.ModeHelp()
				
		except Exception, e:
			self.Hlog("debug", "Build part 2: " + str(e))
			curses.doupdate()
		try:
			self.edit = CharacterParse(self.windows["text"]["input"], self)

			self.stdscr.nodelay(1)
				
		except Exception, e:
			self.Hlog("debug", "Build: " + str(e))
		return self.line
	
	## Close mucous after disconnecting from museekd
	def shutdown(self):
		try:
			self.disconnect()
			# Quit		
			self.timer.cancel()
			self.ticker_timer.cancel()
			self.muscan_timer.cancel()
			self.retry_timer.cancel()
			self.clear_timer.cancel()
		except Exception, e:
			self.Hlog("debug", "shutdown: " + str(e))
		self.stdscr.keypad(0)
		curses.nocbreak()
		curses.echo()
		curses.endwin()
	
		os._exit(0)
	
	## Disconnect from museekd
	def disconnect(self):
		
		try:
			if self.Spl["connected"] == 1:
				driver.Driver.close(self)
		except Exception,e:
			self.Hlog("debug", "disconnect: " + str(e))
	
	## Connect to museekd, password, a museekd socket need to be set
	#
	# If mucous cannot connect, enter a loop which allows commands to be inputted
	def connect(self):
		try:
			keys = []
			
			while 1:
				
				try:
					if self.invalidpass == 0:
						if mucous_config["connection"]["passw"] != None:
							
							self.timer.cancel()
							self.timer = threading.Timer(10.0, self.ThreadNickCheck)
							self.timer.start()
							driver.Driver.connect(self, mucous_config["connection"]["interface"],  mucous_config["connection"]["passw"], messages.EM_CHAT |  messages.EM_USERINFO| messages.EM_PRIVATE| messages.EM_TRANSFERS  | messages.EM_USERSHARES | messages.EM_CONFIG |  messages.EM_INTERESTS) 
							
							break
						else:
							raise Exception,  "IdASS"
					else:
						raise Exception,  "INVPASS"
						
	
				except Exception, e:
					self.display["mode"] = "debug"
					self.ModeHelp()
					if self.timer != None:
						self.timer.cancel()
					if e == "INVPASS":
						self.Hlog("status", "Incorrect Password, try another.")
					elif e == [111, "Connection refused"]:
						self.Hlog("status", e[1] +", make sure the daemon is running, or change the interface.")
					self.Hlog("debug", "Connection failed, try changing your interface or password")
					for lines in self.help_connect:
						self.Hlog("status", lines)
					q = "42"
					while q == "42":
						# Run Commands while offline
						sleep(0.01)
						try:
							c = self.stdscr.getkey(self.h-3, self.edit.x+1)
							keys.append(c)
						except:
							pass
	
						while keys:
							c, keys = keys[0], keys[1:]
							
							try:
								if self.edit.process(c):
									line = self.edit.line
									yes = self.InputCommands(line)
									
									if yes == 0:
										q = 33
										break
									elif yes == 2:
										return
									else:
										self.edit.reset()
							except:
								pass
					break
		except Exception, e:
			self.Hlog("debug", "Connect "+str( e) )
			
	## Recieve Messages from Museekd and collect new key presses
	def process(self):

		keys = []
		
		while 1:
			try:
				c = self.stdscr.getkey(self.h-3, self.edit.x+1)
				keys.append(c)
			except:
				pass

			if not keys:
				d = 1000
			else:
				d = 0
			if self.socket != None:
				r, w, x = select.select([self.socket, sys.stdin], [], [self.socket], d)
				
			else:
				sleep(0.01)
			if self.socket in r:
				driver.Driver.process(self)

			if sys.stdin in r:
				try:
					c = self.stdscr.getkey(self.h-3, self.edit.x+1)
					keys.append(c)
					
				except Exception, e:
					pass
			while keys:
				
				c, keys = keys[0], keys[1:]
				try:
					
					if self.edit.process(c):
						self.line = self.edit.line
						yes = self.InputCommands(self.line)
						
						if yes == 0:
							break
						elif yes == 2:
							return
						else:
							self.edit.reset()
							
				except Exception, e:
					self.Hlog("debug", "Processing... " + str(e))

		
	# -- v Museek Messages v
	
	## Failsafe Sending of messages to Museekd
	def SendMessage(self, message):
		try:
			if self.Spl["connected"] == 0: return
			self.send(message)
		except Exception, e:
			self.Hlog("debug", "SendMessage: " + str(e))
	
	## Recieved Ping from museekd
	def cb_ping(self):
		self.Hlog("debug", "Recieved ping from daemon...")
		
	## Recieved Login Error from museekd
	# @param self is the mucous class
	# @param reason is a string containing the reason for login failure
	def cb_login_error(self, reason):
		try:
			self.Spl["connected"] = 0
			if reason == "INVPASS":
				self.invalidpass = 1
				self.Hlog("status", "couldn't log in: Invalid Password")
				self.connect()
			else:
				self.invalidpass = 0
				self.Hlog("status", "couldn't log in: " + reason)
		except Exception,e:
			self.Hlog("debug", "cb_login_error: " + str(e))
			
	## Recieved Login Okay from museekd
	def cb_login_ok(self):
		try:
			self.invalidpass = 0
			self.Spl["connected"] = 1
			self.Hlog("status", "Logging into Museek at "+ mucous_config["connection"]["interface"])
			self.timeout_timer = threading.Timer(self.timeout_time, self.timeout)
			self.timeout_timer.start()
		except Exception,e:
			self.Hlog("debug", "cb_login_ok: " + str(e))
		
	## Museekd notified that we are disconnected
	def cb_disconnected(self):
		try:
			if self.Spl["connected"] == 1:
				try:
					driver.Driver.close(self)
				except:
					pass
			self.Spl["connected"] = 0
			self.logs["onlinestatus"]="Closed"
			self.muscan_timer.cancel()
			self.timer.cancel()
			self.ticker_timer.cancel()
			self.retry_timer.cancel()
			self.clear_timer.cancel()
			self.timeout_timer.cancel()
			
			osw = self.windows["border"]["onlinestatus"]
			osw.erase()
			osw.addstr(self.logs["onlinestatus"], self.colors["red"] | curses.A_BOLD |curses.A_REVERSE)
			osw.refresh()

			
			for room in self.data["rooms"].keys():
				msg = ("--- Disconnected from the Museek Daemon ---")
				self.ChatRoomAppend("Status", room, '!!!!', msg)
				self.data["rooms"][room] = {}
				self.data["tickers"][room] = {}
			uploadlist = []
			self.data["uploads"] = {}
			self.data["downloads"] = {}
			self.transfers["downloads"] = {}
			self.transfers["uploads"] = {}
			self.config = {}
			

			if self.display["mode"] == "chat":
				self.ModeChatRooms()
			elif self.display["mode"] == "transfer":
				self.ModeTransfers()
			self.TerminalTitle()
			self.DrawUploadCount("0")
			self.DrawDownloadCount("0")

			self.refresh_windows()
		except Exception,e:
			self.Hlog("debug", "cb_disconnected: " + str(e))
			
	## Museekd sent us a special message
	#
	# @param self is the mucous class
	# @param type is a bool; False if the message relates to the Server / True for Peer
	# @param message is the message string
	def cb_status_message(self, type, message):
		try:
			if type == 1:
				stype = "Peer"
			elif type == 0:
				stype = "Server"
			self.Hlog("status", "%s Message: %s" % (stype, message))
		except Exception,e:
			self.Hlog("debug", "cb_status_message: " +str( e) )
				
	## Museekd sent us the server state and our username
	#
	# @param self is the mucous class
	# @param state is a bool; False if disconnected from the server / True if connected
	# @param username is a string
	def cb_server_state(self, state, username):
		try:
			self.usernames["username"] = username
			un = self.windows["border"]["username"]
			osw = self.windows["border"]["onlinestatus"]
			un.erase()
			un.addstr(self.dlang(self.usernames["username"][:15]), self.colors["blafgcyabg"] )
			un.refresh()
		
			self.DrawUploadCount("0")
			self.DrawDownloadCount("0")
			self.DrawSearchCount(0)
		
			if state:
# 				self.Hlog("status", "Connected to Server, username: " + username)
				
				self.logs["onlinestatus"]="Online"
				
	
				if self.data["rooms"].keys():
					for room in self.data["rooms"].keys():
						msg = ("--- Connected ---")
						self.ChatRoomAppend("Status", room, '!!!!', msg)
				
			else:
				self.Hlog("status", "Museek is not connected to Soulseek")
	
				self.logs["onlinestatus"]="Offline"
				
				
	
				if self.data["rooms"].keys():
					for room in self.data["rooms"].keys():
						msg = ("--- Disconnected from the Server ---")
						self.ChatRoomAppend("Status", room, '!!!!', msg)
				uploadlist = []
				self.data["uploads"] = {}
				self.transfers["downloads"] = {}
				self.transfers["uploads"] = {}
				for room in self.data["rooms"].keys():
					self.data["rooms"][room] = []
				if self.display["mode"] == "chat":
					self.ModeChatRooms()
				elif self.display["mode"] == "transfer":
					self.ModeTransfers()

			osw.erase()
			osw.addstr(self.dlang(self.logs["onlinestatus"]), self.colors["blafgcyabg"] )
			osw.refresh()
			
		except Exception,e:
			self.Hlog("debug", "cb_server_state: " +str( e) )
		self.TerminalTitle()

	def cb_server_privileges(self, time_left):
		try: 
			time = time_left
			hours_i = time/3600
			minutes_i = time/60
			seconds_i = time - (60 * minutes_i)
			if minutes_i > 59:
				minutes_i = time/60 - (60 * hours_i)
				
			days = hours_i/24
			hours = hours_i - (days*24)
			if time:
				stime = 'You have %d Days, %2.2d:%2.2d:%2.2d of privileges left' % (days, hours, minutes_i, seconds_i)
			else:
				stime = 'You have no global privileges.'
			self.Hlog("status", stime)
		except Exception,e:
			self.Hlog("debug", "cb_server_privileges: " +str( e) )
		
	def cb_room_state(self, roomlist, joined, tickers):
		try:
			for rooms1, numbers in roomlist.items():
				self.data["roomlist"][rooms1] = numbers
			
			for room in joined:
	
				if room not in self.logs["rooms"]:
					self.logs["rooms"][room] = []
					self.logs["roomstatus"][room] = []
					self.ChatRoomsOldLogs(room)
						
				
				for users in joined[room]:
					self.user["status"][users] = joined[room][users][0]
					self.user["statistics"][users] = joined[room][users][1], joined[room][users][2 ], joined[room][users][3], joined[room][users][4]
					
				self.data["rooms"][room] = joined[room].keys()
					#avgspeed, numdownloads, numfiles, numdirs
	
				# tickers == (rooms, [(user1: message1), (user2: message2),] )
				# a string and then a dictionary
	
				for rooms, ticks in tickers.items():
					self.data["tickers"][rooms] = ticks

	
			joined = self.data["rooms"].keys()
			joined.sort(key=str.lower)
			if joined == []:
				return
			if mucous_config["rooms"]["default_room"] != None:
				if mucous_config["rooms"]["default_room"] in joined:
					self.Spl["room"] = mucous_config["rooms"]["default_room"]
					self.ChatRoomChange(mucous_config["rooms"]["default_room"])
				else:
					self.doJoin(mucous_config["rooms"]["default_room"])
					self.ChatRoomChange(joined[0])

			else:
				self.Spl["room"] = joined[0]
				self.ChatRoomChange(joined[0])

		except Exception, e:
			self.Hlog("debug", "CB Room state" + str(e))	
		
	def cb_room_list(self, roomlist):
		try:
			for name in  roomlist:
				alpha_list[name] = roomlist[name]
			
			self.data["roomlist"] = {}
			
			for x, y in alpha_list.items():
				self.data["roomlist"][x] = y
				
			if self.display["mode"]=="roomlist":
				self.ModeRoomsList()
		except Exception, e:
			self.Hlog("debug", "CB Room List" + str(e))
			
	def cb_get_global_recommendations(self, recommendations):
		try:
			self.data["recommendations"] = SortedDict()
			for rec, num in recommendations.items():
				self.data["recommendations"] [rec] = num
			if self.display["mode"] == "lists" and self.display["list"] == "interests":
				self.DrawInterests()
		except Exception, e:
			self.Hlog("debug", "CB Get Global Recommendations" + str(e))

	def cb_get_similar_users(self, users):
		try:
			
			self.data["similar_users"] = SortedDict()
			for rec, num in users.items():
				self.data["similar_users"][rec] = num
			if self.display["mode"] == "lists" and self.display["list"] == "interests":
				self.DrawInterests()
		except Exception, e:
			self.Hlog("debug", "CB Similar Users" + str(e))
			
	def cb_get_recommendations(self, recommendations):
		try:
			self.data["recommendations"] = SortedDict()
			for rec, num in recommendations.items():
				self.data["recommendations"] [rec] = num
			if self.display["mode"] == "lists" and self.display["list"] == "interests":
				self.DrawInterests()
		except Exception, e:
			self.Hlog("debug", "CB Get  Recommendations" + str(e))
			
	def cb_get_item_similar_users(self, item, users):
		try:
			self.data["similar_users"] = SortedDict()
			for rec, num in users.items():
				self.data["similar_users"][rec] = num
			if self.display["mode"] == "lists" and self.display["list"] == "interests":
				self.DrawInterests()
		except Exception, e:
			self.Hlog("debug", "CB Item Similar Users" + str(e))
			
	def cb_get_item_recommendations(self, item, recommendations):
		try:

			self.data["recommendations"] = SortedDict()
			for rec, num in recommendations.items():
				self.data["recommendations"] [rec] = num
			if self.display["mode"] == "lists" and self.display["list"] == "interests":
				self.DrawInterests()
		except Exception, e:
			self.Hlog("debug", "CB Get Item Recommendations" + str(e))

				
	def cb_room_said(self, room, user, text):
		try:
			#text = text.replace('\n', " ").replace('\t', "     ")
			text = text.replace('\t', "     ")
			
			
	
			if text[:4] == "/me ":
				self.ChatRoomAppend("Me", room, user, text[4:])
				if self.usernames["username"] in text[4:]:
					if self.display["mode"] != "chat":
						self.AlertStatus(room)
						
						self.alert["CHAT"][room] = "nick"
						self.beep()
					elif self.display["mode"] == "chat" and self.Spl["room"] != room:
						self.AlertStatus(room[:14])
						self.alert["CHAT"][room] = "nick"
						self.beep()
					
				else:
					if self.display["mode"] != "chat":
						self.AlertStatus("%s" % room)
						if room not in self.alert["CHAT"]:
							self.alert["CHAT"][room] = "normal"
					elif self.display["mode"] == "chat" and self.Spl["room"] != room:
						self.AlertStatus(room)
						if room not in self.alert["CHAT"]:
							self.alert["CHAT"][room] = "normal"
			else:
				if self.usernames["username"] in text:
					self.ChatRoomAppend("Mentioned", room, user, text)
					if self.display["mode"] != "chat":
						self.AlertStatus(room)
						self.beep()
						self.alert["CHAT"][room] = "nick"
					elif self.display["mode"] == "chat" and self.Spl["room"] != room:
						self.AlertStatus(room)
						self.beep()
						self.alert["CHAT"][room] = "nick"
	
				else:
					self.ChatRoomAppend("Normal", room, user, text)
					if self.display["mode"] != "chat":
						self.AlertStatus( room)
						if room not in self.alert["CHAT"]:
							self.alert["CHAT"][room] = "normal"
	
					elif self.display["mode"] == "chat" and self.Spl["room"] != room:
						self.AlertStatus(room)
						if room not in self.alert["CHAT"]:
							self.alert["CHAT"][room] = "normal"
			self.HotKeyBar()
						
			if mucous_config["mucous"]["logging"] == "yes":
				message = "[%s]\t%s" % (user, text)
				self.FileLog("rooms", time.strftime("%d %b %Y %H:%M:%S"), room, message )
		except Exception, e:
			self.Hlog("debug", "CB Room Said" + str(e))
			
	
	def cb_room_joined(self, room, list_of_users):
		try:
			self.data["tickers"][room] = {}
			if room not in self.logs["rooms"]:
				self.logs["rooms"][room] = []
				self.logs["roomstatus"][room] = []
				self.ChatRoomsOldLogs(room)
				
			for users, stats in list_of_users.items():
				self.user["statistics"][users] = stats[1], stats[2 ], stats[3], stats[4] #avgspeed, numdownloads, numfiles, numdirs
				self.user["status"][users] = stats[0] # online status
			
			self.data["rooms"][room] = list_of_users.keys()
			if self.Spl["room"] == None or self.Spl["room"] == room:
				self.ChatRoomChange(room)
			curses.doupdate()
		except Exception, e:
			self.Hlog("debug", "CB Room Joined: " + str(e))
	
	def cb_room_left(self, room):
		try:
			joined = self.data["rooms"].keys()
			joined.sort(key=str.lower)
			del self.data["rooms"][room]
			
			if room == self.Spl["room"]:
				if len(joined) == 1:
					self.ChatRoomChange(None)
				else:
					ix = joined.index(room)
					if ix > 0:
						ix -= 1
					elif ix == 0:
						ix = -1
					self.ChatRoomChange(joined[ix])
					self.ChatRoomAppend("Status", joined[ix], '!!!!', "Left room %s" % room)
			joined.remove(room)
			del self.logs["rooms"][room]
			del self.data["tickers"][room]
			del self.logs["roomstatus"][room]
			if joined == []:
				self.ChatRoomChange(None)
				self.DrawChatRoomWin()
				self.windows["text"]["chat"].noutrefresh()
			else:
				joined.sort(key=str.lower)
			if room in self.alert["CHAT"]:
				del self.alert["CHAT"][room]
			curses.doupdate()	
		except Exception, e:
			self.Hlog("debug", "CB Room Left" + str(e))
			
		if self.logs["alert"] == "%s" % room[:14]:
			self.AlertStatus("")
	
	def cb_room_user_joined(self, room, user, data):
		try:
			status, speed, downloads, files, dirs, other = data 
			s = self.windows["dimensions"]["chat"]
			did = "join"
			what = data
			if self.config !=  {}: 
				if "ignored" in self.config.keys(): 
					if user not in self.config["ignored"].keys():
						self.LogChatRoomStatus(user, room, did, what)
			if user not in self.data["rooms"][room]:
				self.data["rooms"][room].append(user)
			self.user["statistics"][user] = speed, downloads, files, dirs
			self.user["status"][user] = status
			# correct placement in roombox
			
			if self.display["mode"] == "chat" and self.Spl["room"] == room:
				if self.display["chat"]  == "roombox":
					self.data["rooms"][room].sort(key=str.lower)
					if self.data["rooms"][room].index(user) < self.scrolling["roombox"]:
						self.scrolling["roombox"] += 1

				self.DrawChatRoomBox()
				for lines in self.logs["rooms"][self.Spl["room"]][ len(self.logs["rooms"][self.Spl["room"]]) - s["height"]:]:
					# Update Chat history if user changes status
					if lines[2] == user:
						self.ChatRoomChange(self.Spl["room"])
						break
				curses.doupdate()
		except Exception, e:
			self.Hlog("debug", "CB Room User Joined" + str(e))

	
	def cb_room_user_left(self, room, user):
		try:
			did = "left"
			what = None
			if self.config !=  {}: 
				if "ignored" in self.config.keys(): 
					if user not in self.config["ignored"].keys():
						self.LogChatRoomStatus(user, room, did, what)
			# correct placement in roombox
			if  self.display["mode"] == "chat" and self.display["chat"]  == "roombox":
				self.data["rooms"][room].sort(key=str.lower)
				if self.data["rooms"][room].index(user) < self.scrolling["roombox"]:
					self.scrolling["roombox"] -= 1
			if user in self.data["rooms"][room]:
				self.data["rooms"][room].remove(user)
			if room in self.data["tickers"]:
				if user in self.data["tickers"][room]:
					del self.data["tickers"][room][user]
			if self.display["mode"] == "chat" and self.Spl["room"] == room:
				self.DrawChatRoomBox()
				for lines in self.logs["rooms"][room][len(self.logs["rooms"][self.Spl["room"]]) - self.windows["dimensions"]["chat"]["height"]:]:
					# Update Chat history if user changes status
					if lines[2] == user:
						self.ChatRoomChange(room)
						break
				curses.doupdate()
		except Exception, e:
			self.Hlog("debug", "CB Room User Left" + str(e))
	
	def cb_peer_status(self, user, status):
		try:
			if status == 1: what = "away"
			elif status == 2: what = "online"
			elif status == 0: what = "offline"
			
			if user in self.user["status"]:
				if self.user["status"][user] == status:
					return
				else: 
					self.user["status"][user] = status
			else:
				self.user["status"][user] = status

			room = None
			did = "change"
			if self.config !=  {}: 
				if "ignored" in self.config.keys(): 
					if user not in self.config["ignored"].keys():
						self.LogChatRoomStatus(user, room, did, what)
						
			if self.display["mode"] == "chat":
				if self.Spl["room"] != None:
					if user in self.data["rooms"][self.Spl["room"]]:
						self.DrawChatRoomBox()
						curses.doupdate()
			elif self.display["mode"] in ("private", "info", "browse", "lists"):
				self.ModeReload(user)
		except Exception, e:
			self.Hlog("debug", "CB Peer Status" + str(e))

			
	def cb_user_info(self, user, info, picture, uploads, queue, slotsfree):
		try:
			if user in self.requests["info"]:
				self.requests["info"].remove(user)
				self.usernames["info"] = user
				message = info.split('\n')
				self.LogUserInfo(user, message, [queue, uploads, slotsfree])
				if picture != '':
					r = file(config_dir+str(user)+".image", 'w')
					print >> r, str(picture)
					r.close()
					self.LogInfo( "Saved UserImage as: "+ str(user)+".image")
				if self.display["mode"] != "info":
					self.AlertStatus("New Userinfo")
					self.alert["INFO"].append(user)
					self.HotKeyBar()
		except Exception, e:
			self.Hlog( "debug", "cb_user_info: " + str(e))
				
	def cb_peer_address(self, user, ip, port):
		try:
			if user in self.requests["ip"]:
				self.requests["ip"].remove(user)
				
				if geoip_fail==0:
					try:
						country =  gi.country_name_by_addr( str(ip) )
						self.LogInfo("%s's IP: %s Port: %s Country: %s"  % (user, str(ip), str(port), country) )
					except Exception, e:
						self.Hlog("debug", "CB Peer Address: " + str(e))
				else:
					self.LogInfo("%s's IP: %s Port: %s"  % (user, str(ip), str(port)) )
				if self.display["mode"] != "info":
					self.AlertStatus("New IP")
		except Exception, e:
			self.Hlog( "debug", "cb_peer_address: " + str(e))
			
	def cb_peer_stats(self, user, avgspeed, numdownloads, numfiles, numdirs):
		try:
			self.user["statistics"][user] = avgspeed, numdownloads, numfiles, numdirs
			if user in self.requests["statistics"]:
	
				self.LogInfo("Peer Stats for: %s" % user)
				self.LogInfo("Speed: %s Bits/s" % str(avgspeed))
				self.LogInfo("Downloads: %s" % numdownloads)
				self.LogInfo("Files: %s" % numfiles)
				self.LogInfo("Directories: %s" % numdirs)
				
				self.requests["statistics"].remove(user)
				if self.display["mode"] != "info":
					self.AlertStatus("New Stats")
				else:
					self.DrawUserInfoStats()
			if user == self.usernames["username"]:
				self.data["mystats"] = user,  avgspeed, numdownloads, numfiles, numdirs
				if self.display["mode"] == "setup":
					self.ModeSetup()
		except Exception, e:
			self.Hlog( "debug", "cb_peer_stats: " + str(e))

	def cb_private_message(self, direction, timestamp, user, message):
		try:
			# direction 0 == incoming
			# direction 1 == outgoing (sent from this client)
			ctcpversion = 0
			if message == curses.ascii.ctrl("A")+"VERSION"+curses.ascii.ctrl("A"):
				message = "CTCP VERSION"
				ctcpversion = 1
			
			if user not in self.logs["private"].keys():
				self.logs["private"][user] = []
				if mucous_config["mucous"]["logging"] in ("yes"):
					self.PrivateChatOldLogs(user)
				
			if mucous_config["mucous"]["logging"] in ("yes"):
				if direction == 0:
					self.FileLog("private", time.strftime("%d %b %Y %H:%M:%S"), user, "["+user+"]\t"+ message )
				elif direction == 1:
					self.FileLog("private", time.strftime("%d %b %Y %H:%M:%S"), user, "["+self.usernames["username"]+"]\t"+ message )
			
			if self.usernames["private"] == None:
				self.usernames["private"] = user
			
			self.LogPrivateChat(direction, user, message)
			
			if self.display["mode"] != "private":
				self.AlertStatus("New PM")
				if user not in self.alert["PRIVATE"]:
					self.alert["PRIVATE"].append(user)
					self.HotKeyBar()
				self.beep()
				
			elif self.display["mode"] == "private" and self.usernames["private"] != user:
				if user not in self.alert["PRIVATE"]:
					self.alert["PRIVATE"].append(user)
					self.HotKeyBar()
				self.beep()
				
			if ctcpversion == 1 and direction == 0:
				if mucous_config["mucous"]["extra_requests"] == "Yes":
					self.PrivateChatSend(user, "Mucous %s" % Version)
				
		except Exception, e:
			self.Hlog( "debug", "cb_private_message: " + str(e))
				
		
	def cb_server_status_set(self, status):
		try:
			self.Spl["status"] = status
			if status:
				stat = "Away"
			else:
				stat = "Online"
			
			self.logs["onlinestatus"]=stat
			osw = self.windows["border"]["onlinestatus"]
			try:
				osw.erase()
				osw.addstr(self.dlang(self.logs["onlinestatus"]), self.colors["blafgcyabg"] )
				
			except:
				pass
			osw.refresh()
			self.TerminalTitle()
		except Exception, e:
			self.Hlog( "debug", "cb_server_status_set: " + str(e))
			
	def cb_room_tickers(self, room, tickers):
		
		try:
			for message, user in tickers.items():
				self.data["tickers"][room][user] = message
		except Exception, e:
			self.Hlog( "debug", "cb_room_tickers: " + str(e))
		
	def cb_room_ticker_set(self, room, user, message):
		try:
			what = message
			did = "ticker"
			if self.config !=  {}: 
				if "ignored" in self.config.keys(): 
					if user not in self.config["ignored"].keys():
						self.LogChatRoomStatus(user, room, did, what)
			if room in self.data["tickers"].keys():
				self.data["tickers"][room][user] = message
					
		except Exception, e:
			self.Hlog( "debug", "cb_room_ticker_set: " + str(e))
			
	def cb_search_ticket(self, query, ticket):
		try:
			self.data["search_tickets"][str(ticket)] = query
			self.Spl["current_search"] = str(ticket)
			self.SearchStart(self.Spl["current_search"], query)
		except Exception, e:
			self.Hlog( "debug", "cb_search_ticket: " + str(e))
		
	def cb_search_results(self, ticket, user, free, speed, queue, results):
		# search results
		try:
			if str(ticket) not in self.data["search_tickets"]:
				return 
			for result in results:
				result_list = []
				# Create Result List for future use 
				# clear it next interation
				# Count Search Result
				self.search_number += 1
				# Send Num of Results to Search Window
				self.DrawSearchCount(self.search_number)
	
				ftype = result[2]
				if ftype in ('', None):
					if result[0][-4:-3] == ".":
						ftype = result[0][-3:]
				ftype = ftype.upper()
				result_list = str(ticket), user, free, speed, queue, result[0], result[1], ftype, result[3]
				self.data["search_results"][self.search_number] = result_list
				
			if self.display["mode"] != "search" or self.Spl["current_search"] != str(ticket):
				if str(ticket) not in self.alert["SEARCH"]:
					self.alert["SEARCH"].append( str(ticket) )
					self.AlertCheck()
				
			if self.Spl["current_search"] == str(ticket) and  self.Spl["show_menu"] != True:
					self.Format_Search_Results(str(ticket))
		except Exception, e:
			pass


	def cb_user_shares(self, user, shares):
		try:
			if user in self.requests["browse"]:
				
				if user not in self.activeitems["browse"]:
					self.activeitems["browse"].append(user)
				self.requests["browse"].remove(user)
				self.usernames["browse"] = user
				if self.display["mode"] != "browse":
					self.alert["BROWSE"].append(self.usernames["browse"])
					self.AlertCheck()

				self.data["browse_results"][user] = {}
				self.data["collapsed_dirs"][user] = []
				self.data["browse_num"][user] = 0
				self.data["browse_results"][user]["dirs"] = []
				# Debugging
				#self.Hlog("debug", shares.keys())
				#########
				if shares != {}:
					sdirs = shares.keys()
					sdirs.sort(key=str.lower)
				
					if sdirs != []:
						for item in sdirs:
							s = item.split("\\")
							path = ''
		
							parent = s[0]
							for seq in s[1:]:
	
								parent += "\\"
		
								path = parent+seq
	
				
								if path not in self.data["browse_results"][user]["dirs"]:
									self.data["browse_results"][user]["dirs"].append(path)
								parent =  path
									
					self.data["browse_results"][user]["dirs"].sort(key=str.lower)
				else:
					self.data["browse_results"][user]["dirs"].append("Empty Shares")
                                        
				self.Spl["dir_browse"] = self.data["browse_results"][user]["dirs"][0]
				
				self.data["shares"][user] = shares
				
				for dirs, files in shares.items():
					self.data["browse_results"][user][dirs] = files
					#result_list = []
					
				if self.display["mode"] == "browse":
					self.set_edit_title("Browse "+user+"'s files in " + self.Spl["dir_browse"] + " ")
					self.ModeBrowse()
					
		except Exception, e:
			self.Hlog("debug", "CB User Shares: " + str(e))

			
	def cb_transfer_state(self, downloads, uploads):
		try:
			for transfer in uploads:
				self.transfers["uploads"][(transfer.user, transfer.path)] =  [transfer.is_upload, transfer.user, transfer.path, int(transfer.state), transfer.error, transfer.filepos, transfer.filesize, transfer.rate, transfer.place]
			self.DrawUploadCount(str(len(self.transfers["uploads"].keys())))
			
			for transfer in downloads:
				self.transfers["downloads"][(transfer.user, transfer.path)] =  [transfer.is_upload, transfer.user, transfer.path, int(transfer.state), transfer.error, transfer.filepos, transfer.filesize, transfer.rate, transfer.place]
	
			self.DrawDownloadCount(str(len(self.transfers["downloads"].keys())))		
			if self.display["mode"] == "transfer":
				if mucous_config["mucous"]["transbox"] == "split":
					self.TransfersManagerUpload()
					self.TransfersManagerDownload()
					curses.doupdate()
				else:
					if self.display["transfers"] == "uploads":
						self.TransfersManagerUpload()
						curses.doupdate()
					else:
						self.TransfersManagerDownload()
						curses.doupdate()
			if mucous_config["mucous"]["auto-retry"] == "yes":
				self.retry_timer.cancel()
				self.retry_timer = threading.Timer(30.0, self.ThreadTransfersRetry)
				self.retry_timer.start()
			if mucous_config["mucous"]["auto-clear"] == "yes":
				self.clear_timer.cancel()
				self.clear_timer = threading.Timer(30.0, self.ThreadTransfersClear)
				self.clear_timer.start()
		except Exception, e:
			self.Hlog("debug", "cb_transfer_state: " + str(e))
		
		
	def cb_transfer_update(self, transfer):
		try:
			if transfer.is_upload:
				self.transfers["uploads"][(transfer.user, transfer.path)] =   [transfer.is_upload, transfer.user, transfer.path, int(transfer.state), transfer.error, transfer.filepos, transfer.filesize, transfer.rate, transfer.place]
				if self.display["mode"] == "transfer":
					if mucous_config["mucous"]["transbox"] == "split":
						self.TransfersManagerUpload()
						curses.doupdate()
					else:
						if self.display["transfers"] == "uploads":
							self.TransfersManagerUpload()
							curses.doupdate()
				self.DrawUploadCount(str(len(self.transfers["uploads"].keys())))
			else:
		
				self.transfers["downloads"][(transfer.user, transfer.path)] =  [transfer.is_upload, transfer.user, transfer.path, int(transfer.state), transfer.error, transfer.filepos, transfer.filesize, transfer.rate, transfer.place]
				if self.display["mode"] == "transfer":
					if mucous_config["mucous"]["transbox"] == "split":
						self.TransfersManagerDownload()
						curses.doupdate()
					else:
						if self.display["transfers"] == "uploads":
							pass
						else:
							self.TransfersManagerDownload()
							curses.doupdate()
				self.DrawDownloadCount(str(len(self.transfers["downloads"].keys())))
			if self.display["mode"] == "transfer":
				if self.Spl["show_menu"] == True:
					self.MenuCreate(self.Spl["current_menu"], self.Spl["menunumber"])
		except Exception, e:
			self.Hlog("debug", "cb_transfer_update: " + str(e))
		
	def cb_transfer_remove(self, transfer):
		try:
			user_path = transfer[1], transfer[2]
			if transfer[0]:
				del self.transfers["uploads"][user_path]
				if self.display["mode"] == "transfer":
					if mucous_config["mucous"]["transbox"] == "split":
						self.TransfersManagerUpload()
						curses.doupdate()
					else:
						if self.display["transfers"] == "uploads":
							self.TransfersManagerUpload()
							curses.doupdate()
				self.DrawUploadCount(str(len(self.transfers["uploads"].keys())))
						
			else:
				del self.transfers["downloads"][user_path]
				if self.display["mode"] == "transfer":
					if mucous_config["mucous"]["transbox"] == "split":
						self.TransfersManagerDownload()
						curses.doupdate()
					else:
						if self.display["transfers"] == "uploads":
							pass
						else:
							self.TransfersManagerDownload()
							curses.doupdate()
				self.DrawDownloadCount(str(len(self.transfers["downloads"].keys())))
		except Exception, e:
			self.Hlog("debug", "cb_transfer_remove: " + str(e))
			
	def cb_config_set(self, domain, key, value):
		try:
			if key in self.config[domain].keys():
				if not domain.startswith("museeq"):
					self.Hlog("status", "Modified <"+key+"> in <" +domain+"> to <"+value + ">")
				self.config[domain][key] = value
			else:
				if value == '' and domain is not "userinfo" and not domain.startswith("museeq"):
					self.Hlog("status", "Added <"+key+"> to <" +domain+">")
				else:
					self.Hlog("status", "Added <"+key+"> to <" +domain+"> and set to <"+value+">")
				self.config[domain][key] = value
			self.display_config_update(domain)
		except Exception, e:
			self.Hlog("debug", "cb_config_set: " + str(e))
			
	#Delete keys from self.config
	def cb_config_remove(self, domain, key):
		try:
			if key in self.config[domain].keys():
				self.Hlog("status", "Removed <"+key+"> from <" +domain+">")
				del self.config[domain][key]
			self.display_config_update(domain)
		except Exception, e:
			self.Hlog("debug", "cb_config_remove: " + str(e))
	
	#Copy config to self.config at connection
	def cb_config_state(self, config):
		try:
			self.config = config.copy()
			self.Hlog("status", "Server is at: "+self.config["server"]["host"]+":"+self.config["server"]["port"])
			self.ListBuddy()
			self.ListBan()
			self.ListIgnore()
			self.refresh_windows()
			self.Spl["museekconfigfile"] = os.path.expanduser("~/.museekd/config.xml")
			if self.config["shares"]["database"] != "":
				pos = self.config["shares"]["database"].rfind(".")
				file = self.config["shares"]["database"][:33]+".xml"
				if os.path.exists(file):
					self.Spl["museekconfigfile"] = file
		except Exception, e:
			self.Hlog("debug", "cb_config_state: " + str(e))
	# -- ^ Museek Messages ^


		
	def ToggleLogging(self):
		try:
			if "logging" in mucous_config["mucous"]:
				if str(mucous_config["mucous"]["logging"]) not in ("yes", "no"):
					mucous_config["mucous"]["logging"] = "yes"
				else:
					if str(mucous_config["mucous"]["logging"]) == "yes":
						mucous_config["mucous"]["logging"] = "no"
					else:
						mucous_config["mucous"]["logging"] = "yes"
			else:
				if str(mucous_config["mucous"]["logging"]) == "yes":
					mucous_config["mucous"]["logging"] = "no"
				else:
					mucous_config["mucous"]["logging"] = "yes"
					
			if str(mucous_config["mucous"]["logging"]) == "yes":
				self.Hlog("status", "Logging Chat is now Enabled.")
			else:
				self.Hlog("status", "Logging Chat is now Disabled.")
		except Exception,e:
			self.Hlog("debug", "ToggleLogging: " + str(e))
		
	def ToggleBeep(self):
		try:
			if str(mucous_config["mucous"]["beep"]) == "yes":
				mucous_config["mucous"]["beep"] = "no"
			else:
				mucous_config["mucous"]["beep"] = "yes"
			if self.display["mode"]=="setup":
				self.ModeSetup()
		except Exception, e:
			self.Hlog("debug", "ToggleBeep: "+str(e))
	def ToggleTickersDisplay(self):
		try:
			if str(mucous_config["tickers"]["tickers_enabled"]) == 'no':
				mucous_config["tickers"]["tickers_enabled"] = 'yes'
				
			elif str(mucous_config["tickers"]["tickers_enabled"]) == 'yes':
				mucous_config["tickers"]["tickers_enabled"] = 'no'
			if self.display["mode"]=="setup":
				self.ModeSetup()
		except Exception, e:
			self.Hlog("debug", "ToggleTickersDisplay: "+str(e))
	def ToggleTickers(self):
		try:
			if mucous_config["tickers"]["ticker_cycle"] == 'no':
				mucous_config["tickers"]["ticker_cycle"] = 'yes'
				if str(mucous_config["tickers"]["ticker_scroll"]) == 'yes':
					mucous_config["tickers"]["ticker_scroll"] = 'no'
				
			elif mucous_config["tickers"]["ticker_cycle"] == 'yes':
				mucous_config["tickers"]["ticker_cycle"] = 'no'
				if str(mucous_config["tickers"]["ticker_scroll"]) == 'no':
					mucous_config["tickers"]["ticker_scroll"] = 'yes'
				
				
			#self.ticker_timer.cancel()
			if self.display["mode"]=="chat":
				self.DrawChatRoomStatusWin()
				self.DrawChatRoomStatusText()
				curses.doupdate()
			elif self.display["mode"]=="setup":
				self.ModeSetup()
		except Exception, e:
			self.Hlog("debug", "ToggleTickers: "+str(e))
					
	def ToggleAwayStatus(self):
		try:
			if self.Spl["status"] == 0:
				self.SendMessage(messages.SetStatus(1))
			elif self.Spl["status"] == 1:
				self.SendMessage(messages.SetStatus(0))
		except Exception,e:
			self.Hlog("debug", "ToggleAwayStatus: " +str( e) )
			
	def TerminalTitle(self):
		# Changes Terminal's Title when Away Status changes
		try:
			if os.path.expandvars("$SHELL") in  ("/bin/bash", "/bin/sh"):
				if str(curses.termname() ) != "linux":
					os.system("echo -ne \"\033]0;Mucous %s: %s\007\" " %(Version, self.logs["onlinestatus"] ))
		except Exception,e:
			self.Hlog("debug", "TerminalTitle: " +str( e) )
			
		
	def beep(self):
		try:
			if str(mucous_config["mucous"]["beep"]) == "yes":
				if os.path.expandvars("$SHELL") in  ("/bin/bash", "/bin/sh"):
					os.system("echo -ne \\\\a " )
		except Exception,e:
			self.Hlog("debug", "beep: " + str(e))
			
	def BrowseFiles(self, user, dirs):
		try:
			if self.display["mode"] != "browse":
				self.alert["BROWSE"].append(user)
				self.AlertStatus("Browse: %s" % user)
				return
			tw = self.windows["text"]["browse"]
			w = self.windows["dimensions"]["browse"]
			self.data["browse_num"][user] = 0
			browse_list = []
			count =0 
			# file, stats[ size, ftype, [bitrate, length ] ]
			if dirs not in self.data["shares"][user] or self.data["shares"][user][dirs] == {}:
				tw.erase()
				tw.addstr("Empty..")
				tw.refresh()
				self.data["files"] =  []
				return
			length_list = len(str(len(self.data["shares"][user][dirs].keys() ) ) )
			list1 = self.data["shares"][user][dirs].keys()
			list1.sort(key=str.lower)

			for file in list1:
				stats = self.data["shares"][user][dirs][file]
				count += 1
				
				self.data["browse_num"][user] = self.data["browse_num"][user] +1
				size = str(self.Humanize(stats[0]))
				if len(size) < 6:
					size = ' '* (6-len(size)) + size
				ftype =stats[1]
				
				if ftype.upper() in ('OGG', 'MP3') and stats[2] != []:
					bitrate =str(stats[2][0])
					if bitrate == '':
						bitrate = '0'	
					length =str(stats[2][1])
					if length != '' and length != None:
						minutes = int(length)/60
						seconds = str( int(length) - (60 * minutes))
						if len(seconds) < 2:
							seconds = '0' + seconds
						length = str(minutes)+":"+str(seconds)
					else:
						length = "0:00"
						bitrate = '0'
				else:
					ftype = "None"
					length = "0:00"
					bitrate = '0'
					
				filename = dirs + "\\" + file
				#result_list = user, filename
				# Activate Number for Result
				if len(str(count)) < 4:
					s = " " * (4 - len(str(count)))
				else:
					s = ''
				
				size = " " * (7 - len(str(size))) + size[:7]
				line = "%s%s|%s|%s" % ( s, str(count), size, file )
				browse_list.append(line)
				
			self.data["files"] = list1
				
			if self.bfilter != None:
				a = []
				for path in browse_list:
					if re.match( self.bfilter, path):
						a.append(path)
				browse_list = a
				del a
					
			clipped_list, self.scrolling["browsefile"], self.windows["dimensions"]["browse"]["start"] = self.scrollbox(browse_list, self.scrolling["browsefile"], w["height"])
			sup = self.scrolling["browsefile"]
				
			

			count = 0
			tw.erase()
			for line in clipped_list:
				self.DrawBrowseFileText(line, count, sup)
				count += 1
			tw.refresh()
			
		except Exception, e:
			self.Hlog("debug", "BrowseFiles: " + str(e))
			
	
	
	def BrowseFileBar(self, user, dirs):
		try:
			self.windows["text"]["browsebar"].erase()
			num = self.scrolling["browsefile"]
                        #self.usernames["browse"], self.Spl["dir_browse"]
			if dirs not in self.data["shares"][user]:
				self.windows["text"]["browsebar"].refresh()
				return
			if self.data["shares"][user][dirs].keys() != []:
                                list1 = self.data["shares"][user][dirs].keys()
			        list1.sort(key=str.lower)
                                file = list1[num]
                                stats = self.data["shares"][user][dirs][file] 
			else: 
				self.windows["text"]["browsebar"].refresh()
				return
	

			size  = self.Humanize(stats[0])
			
			ftype =stats[1]
			if ftype == '':
				ftype = "None"
				length = "0:00"
				bitrate = '0'
			else:
				bitrate =str(stats[2][0])
				if bitrate == '':
					bitrate = '0'	
				length =str(stats[2][1])
				if length != '' and length != None:
					minutes = int(length)/60
					seconds = str( int(length) - (60 * minutes))
					if len(seconds) < 2:
						seconds = '0' + seconds
					length = str(minutes)+":"+str(seconds)
				else:
					length = "0:00"
			
                        #l=len('['+str(num+1)+'] '+" Size: " + str(size)+" Length: " + length + " Bitrate: " + bitrate)
                        atr = self.colors["cyan"] | curses.A_BOLD

			self.windows["text"]["browsebar"].addstr("[")
                        self.windows["text"]["browsebar"].addstr(str(num+1), atr )
                        self.windows["text"]["browsebar"].addstr("] | Size: ")
                        self.windows["text"]["browsebar"].addstr(str(size), atr)
                        self.windows["text"]["browsebar"].addstr(" | ")
                        self.windows["text"]["browsebar"].addstr(bitrate, atr)
                        self.windows["text"]["browsebar"].addstr("Kbps | Length: ")
                        self.windows["text"]["browsebar"].addstr(length, atr)
			self.windows["text"]["browsebar"].refresh()
		except Exception, e:
			self.Hlog("debug", "BrowseFileBar: " + str(e))
			
			
	def ModeReload(self, user):
		# Redraw if user is in the current mode
		if self.display["mode"] == "private":
			if user in self.logs["private"].keys():
				self.ModePrivate()
		elif self.display["mode"] == "chat":
			if user in self.data["rooms"][self.Spl["room"]]:
				self.ModeChatRooms()
		elif self.display["mode"] == "info":
			if user in self.activeitems["info"]:
				self.ModeInfo()
		elif self.display["mode"] == "lists":
			if self.display["list"] in self.config.keys():
				if user in self.config[self.display["list"]].keys():
					self.ModeLists()
		elif self.display["mode"] == "browse":
			if user in self.activeitems["browse"]:
				self.ModeBrowse()
		elif self.display["mode"] == "search":
			if user in self.data["search_tickets"].keys():
				self.ModeSearch()
		elif self.display["mode"] == "transfers":
			self.ModeTransfers()
		elif self.display["mode"] == "roomlist":
			self.ModeRoomsList()
		elif self.display["mode"] == "setup":
			self.ModeSetupDefault()
		elif self.display["mode"] in ("help", "debug", "status"):
			self.ModeHelp()
			
	def SayInChat(self, mode, place, message):
		try:
			
			message = self.dencode_language(message)
			#message = self.encode_language(message)
			if place != None:
				if '\\n' in message:
					
					splited =  message.split('\\n')
					
					if len(splited) > 7:
						
						for i in range(8):
							if self.display["mode"] == "chat":
								
								self.SendMessage(messages.SayRoom(place, splited[i]))
							elif self.display["mode"] == "private":
								self.SendMessage(messages.PrivateMessage(1, place, splited[i]))
						self.Hlog("debug", "Your chat message was really long, so it was cut to keep you from getting muted.")
					else:
						for i in range(len(splited)):
							if self.display["mode"] == "chat":
								self.SendMessage(messages.SayRoom(place, splited[i]))
							elif self.display["mode"] == "private":
								self.SendMessage(messages.PrivateMessage(1, place, splited[i]))
					
	
				elif '\n' in message:
					splited =  message.split('\n')
					
					if len(splited) > 5:
						for i in range(5):
							if self.display["mode"] == "chat":
								self.SendMessage(messages.SayRoom(place, splited[i]))
							elif self.display["mode"] == "private":
								self.SendMessage(messages.PrivateMessage(1, place, splited[i]))
					else:
						for i in range(len(splited)):
							if self.display["mode"] == "chat":
								self.SendMessage(messages.SayRoom(place, splited[i]))
							elif self.display["mode"] == "private":
								self.SendMessage(messages.PrivateMessage(1, place, splited[i]))
				else:
					
					if self.display["mode"] == "chat":
						self.SendMessage(messages.SayRoom(place, message))
					elif self.display["mode"] == "private":
						self.SendMessage(messages.PrivateMessage(1, place, self.dencode_language(message)))
		except Exception, e:
			self.Hlog("debug", "SayInChat: " + str(e))
			
	def DrawUserInfoStats(self):
		try:
			itw = self.windows["text"]["infostats"]
			itw.erase()
			if self.usernames["info"] != None and self.display["mode"]=="info":
				userinfo = self.logs["info"][self.usernames["info"]]
				itw.addstr('Queue: %s' % str(userinfo[1][0]) + \
                                          '\nUploads: %s' % str(userinfo[1][1]) + \
                                          '\nSlots: %s' % str(userinfo[1][2]))

				if self.usernames["info"] in self.user["statistics"].keys():
					try:
                                                stats = self.user["statistics"][self.usernames["info"]]
						itw.addstr('\nSpeed: %sKB/s' % str(stats[0]/1024))
						itw.addstr('\nDown: %s' % str(stats[1]))
						itw.addstr('\nFiles: %s' % str(stats[2]))
						itw.addstr('\nDirs: %s' % str(stats[3]))
					except:
						pass
			itw.noutrefresh()
		except Exception, e:
			self.Hlog("debug", "DrawUserInfoStats: " + str(e))
				
	def LogUserInfo(self, user, message, stats):
		try:
			if self.usernames["info"] == None:
				self.usernames["info"] = user
			if user not in self.logs["info"]:
				self.logs["info"][user] = []
			if user not in self.activeitems["info"]:
				self.activeitems["info"].append(user)
			self.logs["info"][user] = message, stats
			if user not in self.user["statistics"].keys():
				self.SendMessage(messages.PeerStats(user))
			if self.display["mode"] == 'info':
				self.ModeInfo()
		except Exception, e:
			self.Hlog("debug", "LogUserInfo: " + str(e))
	
	def PrivateMessageEncoded(self, user, message):
		try:
			self.SendMessage(messages.PrivateMessage(1, user, self.dencode_language(message)))
		except:
			pass
		
	def PrivateChatSend(self, user, message):
		try:
			#Username is already utf-8ified
			
			lang = mucous_config["mucous"]["language"]
			if '\\n' in message:
				
				splited =  message.split('\\n')
				if len(splited) > 7:
					for i in range(8):
						self.PrivateMessageEncoded(user, splited[i])
				else:
					for i in range(len(splited)):
						self.PrivateMessageEncoded(user,  splited[i])
				

			elif '\n' in message:
				splited =  message.split('\n')
				
				if len(splited) > 5:
					for i in range(5):
						self.PrivateMessageEncoded(user,  splited[i])
				else:
					for i in range(len(splited)):
						self.PrivateMessageEncoded(user,  splited[i])
			else:
				self.PrivateMessageEncoded(user, message)
		
			if message == curses.ascii.ctrl("A")+"VERSION"+curses.ascii.ctrl("A"):
				message = "CTCP VERSION"
			if mucous_config["mucous"]["logging"] in ("yes"):
				self.FileLog("private", time.strftime("%d %b %Y %H:%M:%S"), user, "["+self.usernames["username"]+"]\t" +message )
			#pmtype = "outgoing"
			self.LogPrivateChat(1, user, message)
			
			if self.logs["alert"] == "New PM":
				self.AlertStatus("")
		except Exception ,e:
			self.Hlog("debug", "Send PM: " + str(e))
	

				
	def SearchStart(self, ticket, query):
		try:
			if self.display["mode"] == "search":
				self.ModeSearch()
				if query not in self.logs["search"]:
					self.logs["search"][str(ticket)] = []
				
				self.DrawSearchStats("sstatus", "Started search for: %s" % query, str(ticket), 0)
		except Exception, e:
			self.Hlog("debug", "SearchStart: " + str(e))
			
	def Format_Search_Results(self, this_ticket):
		if self.display["mode"] != "search":
			return
		try:
			tw = self.windows["text"]["search"]
			sorting_list = {}
			
			for numbers, results in self.data["search_results"].items():
				ticket, user, free, speed, queue, path, size, ftype, extended = results
				if this_ticket == ticket and  self.Spl["current_search"] == ticket and self.display["mode"] == "search":
					if ftype.upper() in ('MP3', 'OGG'):
						if extended != []:
							bitrate = extended[0]
							time = extended[1]
						else:
							bitrate = 0
							time = 0
					else: 
						bitrate = 0
						time = 0

					if time in ('', None):
						time = 0
					
					if self.Spl["search_order"] == "num":
						sorting_list[numbers] = 0
					elif self.Spl["search_order"] == "user":
						sorting_list[numbers] = user
					elif self.Spl["search_order"] == "free":
						sorting_list[numbers] =  free
					elif self.Spl["search_order"] == "speed":
						sorting_list[numbers] =  speed
					elif self.Spl["search_order"] == "que":
						sorting_list[numbers] =  queue
					elif self.Spl["search_order"] == "path":
						sorting_list[numbers] =  path
					elif self.Spl["search_order"] == "size":
						sorting_list[numbers] =  size
					elif self.Spl["search_order"] == "file":
						sorting_list[numbers] =  ftype
					elif self.Spl["search_order"] == "bitrate":
						sorting_list[numbers] = bitrate
					elif self.Spl["search_order"] == "time":
						sorting_list[numbers] = time
					
			
			slist = self.sortbyvalue (sorting_list)
			# Filter search while browsing
			if self.sfilter != None:
				s = []
				searchfilter = re.compile('.*' +str(self.sfilter) + '.*', re.DOTALL | re.I)
				for x,y  in slist:
					z =self.data["search_results"][x]
					for c in (z[1], z[5]) :
						if re.match(searchfilter, c): s.append(x); break
				
				self.sorted_search = s
			else:
				s = []
				for x,y  in slist:
					s.append(x)
				self.sorted_search = s
			if self.Spl["search_reverse"] == True:
				self.sorted_search.reverse()
			self.logs["search"][str(this_ticket)] = []
			
			clipped_list, self.scrolling["search"], self.windows["dimensions"]["search"]["start"] = self.scrollbox(self.sorted_search, self.scrolling["search"], self.windows["dimensions"]["search"]["height"])
			tw.erase()
			count = 0
			self.activeitems["search"] = clipped_list
			for number in clipped_list:
				#self.format_this_search(n)
				self.DrawSearchStats("result1", number, str( self.data["search_results"][number][0] ), count )
				count += 1
			tw.noutrefresh()
		except Exception, e:
			self.Hlog("debug", "FSR: " + str(e))
	
	def byte_format(self, filesize):
		try:
			filesize =  int(filesize)
			if filesize >= 1073741824:
				filefrmt = str(filesize/1024/1024/1024) +"GB"
			elif filesize >= 1048576 and filesize <= 1073741824:
				filefrmt = str(filesize/1024/1024) +"MB"
			elif filesize < 1048576 and filesize >= 1024:
				filefrmt = str(filesize/1024) +"KB"
			elif filesize < 1024 and filesize > 0:
				filefrmt = str(filesize) +" B"	
			elif filesize == 0:
				filefrmt = '0'
			return filefrmt
		except Exception, e:
			self.Hlog("debug", "byte_format: " + str(e))
                        
	def Humanize(self, size):
		if size is None:
			return None
		try:
			s = int(size)
			if s >= 1000*1024*1024:
				r = "%.1fGB" % ((float(s) / (1024.0*1024.0*1024.0)))
			elif s >= 1000*1024:
				r = "%.1fMB" % ((float(s) / (1024.0*1024.0)))
			elif s >= 1000:
				r = "%.1fKB" % ((float(s) / 1024.0))
			else:
				r = str(size)
			return r
		except Exception, e:
			return size

	def StringSplitPath(self, path):
		try:
			r = path.split('\\')
			directory = ''
			for s in r:
				if s is not r[-1]:
					directory += s+'\\'
				if s is r[-1]:
					file = s
			return directory, file
		except Exception, e:
			self.Hlog("debug", "StringSplitPath: " + str(e))
			
	def DrawSearchStats(self, typer, result, ticket, count):
		if str(ticket) in self.logs["search"]:
			try:
				if self.display["mode"] != "search":
					return
				if self.Spl["current_search"] != str(ticket):
					return
				tw = self.windows["text"]["search"]
				ss = self.windows["border"]["searchstats"]
				if typer == "sstatus":
					ss.erase()
					ss.addstr(self.dlang(result), self.colors["cyan"])
					ss.noutrefresh()
				elif typer == "result1":
					number = result
					ticket, user, free, speed, queue, path, size, ftype, extended = self.data["search_results"][number]
					size  = self.byte_format(size)

					if ftype.upper() in ('MP3', 'OGG'):
						if extended != []:
							bitrate = extended[0]
							length = int(extended[1])
							minutes = length/60
							seconds = str(length - (60 * minutes))
							
							if len(seconds) < 2:
								seconds = '0' + seconds
						else:
							bitrate = '0'
							minutes = '0'
							seconds = '00'
							length = 0
					else:
						bitrate = '0'
						minutes = '0'
						seconds = '00'
						length = 0
					if free:
						free = 'Y'
					else:
						free = 'N'
			
					
					if count + self.windows["dimensions"]["search"]["start"]== self.scrolling["search"]:
						attr =  curses.A_REVERSE | curses.A_BOLD
						attrc = self.colors["cybg"]| curses.A_BOLD
						ss.erase()

						ss.addstr("F: ")
						atr = self.colors["cyan"] | curses.A_BOLD
						ss.addstr(free, atr )
						ss.addstr(" | Q:")
						ss.addstr(str(queue), atr )
						ss.addstr(" | ")
						ss.addstr(user[:15], atr )
						ss.addstr(" | ")
						ss.addstr(str(speed/1024), atr )
						ss.addstr("KB/s | Size: ")
						ss.addstr(str(size), atr )
						if bitrate != '0' and length != 0:
							ss.addstr(" | ")
							ss.addstr(str(bitrate), atr )
							ss.addstr("Kbps| Len: ")
							ss.addstr(str(minutes), atr )
							ss.addstr(":")
							ss.addstr(str(seconds), atr )
						ss.noutrefresh()
					else:
						attr = curses.A_NORMAL
						attrc = self.colors["cyan"]
					try:
						sn = len(str(number))
						sr = len(str(self.search_number))
						if sn < sr :
							nub = (" " * (sr - sn)) + str(number)
						else:
							nub = str(number)
						
						if len(nub+"| ")+len(path) >= self.w-2:
							pos = self.w-2-len(str(nub)+"| ")-len(path)
							#pp = path[-pos:]
							directory, file = self.StringSplitPath(path)
							if abs(pos) > len(directory):
								a = abs(pos) - len(directory)
								file = file[:-a]
								directory = ''
							else:
								directory = directory[-pos:]
								
							extra = ''
						else:
							if len(str(nub)+"| "+ path) < self.w-2:
								
								directory, file = self.StringSplitPath(path)
								extra = " " * (self.w-2-len(str(nub)+"| "+ path))
							else:
								directory, file = self.StringSplitPath(path)
								extra = ''
						tw.addstr(nub, attrc)
						tw.addstr("| "+directory, attr)
						tw.addstr(file, attrc)
						tw.addstr(extra, attr)
					except:
						pass

			except Exception, e:
				self.Hlog("debug", "Search Log: " + str(e))

	def BrowseChangeDir(self, line):
		try:
			if self.Spl["dir_browse"]== '' or line[0:1] == '\\' or line[1:2] == ":":
				if self.usernames["browse"] in self.data["browse_results"].keys():
					if line[0:1] == '\\':
						if line in self.data["browse_results"][self.usernames["browse"]].keys():
							self.Spl["dir_browse"] = line
						else:
							self.Hlog("status", "No such directory: %s user:" % (line[1:],  self.usernames["browse"]))
					if line[1:2] == ":":
						if line in self.data["browse_results"][self.usernames["browse"]].keys():
							self.Spl["dir_browse"] = line
						else:
							self.Hlog("status", "No such directory: %s user:" % (line,  self.usernames["browse"]))
					else:
						if line in self.data["browse_results"][self.usernames["browse"]].keys():
							self.Spl["dir_browse"] = line
						else:
							self.Hlog("status", "No such directory: %s user:" % (line,  self.usernames["browse"]))
				
			elif line =='..':
				z = self.BrowseParentDir()
				if z != 0:
					self.Spl["dir_browse"] = z
				else:
					self.Hlog("status", "No parent directory, User: " +  self.usernames["browse"])
			else:
				if self.Spl["dir_browse"] + '\\'+line in self.data["browse_results"][self.usernames["browse"]].keys():
					self.Spl["dir_browse"] += '\\'+line
				else:
					self.Hlog("status", "No such directory: %sUser: " % (line, self.usernames["browse"]) )
					
			if self.usernames["browse"] == None:
				self.set_edit_title("Choose a user to Browse Shares")
			else:
				s = "Browse "+self.usernames["browse"]+"'s files in "
				ls = len(s)
				self.set_edit_title(s  + self.Spl["dir_browse"][:self.w-ls-4] + " ")
		except Exception, e:
			self.Hlog("debug", "BrowseChangeDir: " + str(e))
			
	def BrowseParentDir(self):
		try:
			splitit = self.Spl["dir_browse"]
			splitit = splitit.split("\\")
			s = len(splitit)
			z=''
			for r in range(s-1):
				if r == 0:
					z += splitit[r]
				else:
					z += "\\"+splitit[r]
					
			if z in self.data["browse_results"][self.usernames["browse"]].keys():
				return z
			else:
				return 0
		except Exception, e:
			self.Hlog("debug", "BrowseParentDir: " + str(e))
			
	#Add new/replace old keys to self.config
	def ModifyConfig(self, changetype, username, value):
		try:
			
			username = self.dlang(username)
			if changetype == "buddy":
				if username not in self.config["buddies"].keys():
					self.SendMessage(messages.ConfigSet("buddies", username, "buddied by mucous"))
					
			elif changetype == "unbuddy":
				if username in self.config["buddies"].keys():
					self.SendMessage(messages.ConfigRemove("buddies", username))
				else:
					self.Hlog("status", "User not in buddy list: %s" % username)
			elif changetype == "ban":
				if username not in self.config["banned"].keys():
					self.SendMessage(messages.ConfigSet("banned", username, "banned by mucous"))
			elif changetype == "trusted":
				if username not in self.config["trusted"].keys():
					self.SendMessage(messages.ConfigSet("trusted", username, ""))
			elif changetype == "unban":
				if username in self.config["banned"].keys():
					self.SendMessage(messages.ConfigRemove("banned", username))
				else:
					self.Hlog("status", "User not in ban list: %s" % username)
			elif changetype == "ignore":
				if username not in self.config["ignored"].keys():
					self.SendMessage(messages.ConfigSet("ignored", username, ""))
					self.Hlog("status", "Ignored: %s" % username)
			elif changetype == "unignore":
				if username in self.config["ignored"].keys():
					self.SendMessage(messages.ConfigRemove("ignored", username))
				else:
					self.Hlog("status", "User not in ignore list: %s" % username)
			elif changetype == "autojoin":
				room = username
				if room not in self.config["autojoin"].keys():
					self.SendMessage(messages.ConfigSet("autojoin", room, ""))
				else:
					self.SendMessage(messages.ConfigRemove("autojoin", room))
	
			elif changetype == "unautojoin":
				room = username
				if room in self.config["autojoin"].keys():
					self.SendMessage(messages.ConfigRemove("autojoin", room))
				else:
					self.SendMessage(messages.ConfigSet("autojoin", room, ""))
			elif changetype == "trust":
				if username not in self.config["trusted"].keys():
					self.SendMessage(messages.ConfigSet("trusted", username,  ""))
			elif changetype == "distrust":
				if username in self.config["trusted"].keys():
					self.SendMessage(messages.ConfigRemove("trusted", username))
		except Exception, e:
			self.Hlog("debug", "ModifyConfig: " + str(e))
			
	def display_config_update(self, domain):
		try:
			if domain in ("buddies", "banned", "trusted", "ignored",  "autojoin", "trusted"):
				if self.display["mode"] == "lists":
					if self.display["list"] == "buddied" and domain == "buddies":
						self.ModeBuddy()
					elif self.display["list"] == "banned"  and domain == "banned":
						self.ModeBan()
					elif self.display["list"] == "ignored" and domain == "ignored":
						self.ModeIgnore()
					elif self.display["list"] == "trusted" and domain == "trusted":
						self.ModeTrust()
				elif self.display["mode"] == "chat" :
					self.DrawChatRoomBox()
					
				if self.Spl["show_menu"] == True:
					self.MenuDraw(self.Spl["current_menu"])
					
			elif domain in ("interests.like", "interests.hate"):
				if self.display["mode"] == "lists" and self.display["list"] == "interests":
					self.ModeInterests()
			elif domain in ("clients", "transfers", "server", "interfaces", "interfaces.bind", "userinfo") and self.display["mode"] == "setup":
				self.ModeSetup()
			elif domain in ("encoding.users", "encoding" ) and self.display["mode"] == "browse":
				self.ModeBrowse()
			elif domain in ("encoding.users" ) and self.display["mode"] == "private":	
				self.ModePrivate()
			elif domain in ("encoding.rooms" ) and self.display["mode"] == "chat":
				self.ModeChatRooms()
		except Exception, e:
			self.Hlog("debug", "display_config_update: " + str(e))
			
	def download_path_file(self, dtype, number):
		try:
			
			number = int(number)
			if self.display["mode"]=="search":
				if self.data["search_results"] != {}:
					if self.data["search_results"][number] != None:
						user = self.data["search_results"][number][1]
						path = self.data["search_results"][number][5]
						directory = ''
						if dtype == "dir":
							path = path.replace("/", "\\")
							r = path.split('\\')
							r.remove(r[-1])
		
							for s in r:
								if s is not r[-1]:
									directory += s + "\\"
								else:
									directory += s
					else:
						self.Hlog("status", "No such file")
				else:
					self.Hlog("status", "You need to search, first ;)")
					
			elif self.display["mode"]=="browse":
				
				if self.display["browse"] == "files":
					w = self.windows["dimensions"]["browse"]
					if dtype == "dir":
						directory = path = self.Spl["dir_browse"]
						user = self.usernames["browse"]

					elif dtype == "file":
						user = self.usernames["browse"]
						path = self.Spl["dir_browse"]+"\\"+self.data["files"][number]
				elif self.display["browse"] == "directories":
					w = self.windows["dimensions"]["directories"]
					if dtype != "dir":
						return
					directory = path = self.Spl["dir_browse"]
					user = self.usernames["browse"]

			if user != None and path != None:
				if dtype == "file":
					path = path.replace("/", "\\")
					self.SendMessage(messages.DownloadFile(user, path))
					self.Hlog("status", "Try to Download file: %s from %s" % (path, user))
				elif dtype == "dir":
					directory = directory.replace("/", "\\")
					self.SendMessage(messages.GetFolderContents(user, directory))
					self.Hlog("status", "Try to Download directory: %s from %s" % (directory, user))
				
				if mucous_config["mucous"]["autobuddy"]  == "yes":
					if user not in self.config["buddies"].keys():
						self.SendMessage(messages.ConfigSet("buddies", user, "buddied by mucous"))
						self.Hlog("status", "Auto-Buddied: %s" % user)
				
		except Exception, e:
			self.Hlog("debug", "DPF: " + str(e))
			
	def TransfersListCompact(self, list):
		try:
			if self.display["transfer_sort"] == 'active':
				status_list = (1, 2, 3, 4, 5, 6, 8, 9,)
			elif self.display["transfer_sort"] == 'all':
				status_list = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
			elif self.display["transfer_sort"] == 'finished':
				status_list = (0, 99999)
			elif self.display["transfer_sort"] == 'queued':
				status_list = (7, 99999)
			elif self.display["transfer_sort"] == 'failed':
				status_list = ( 10, 11, 12, 13)
				
			self.data["downloads"] = {}

			statuslist = []
			statuslist = self.transfers[list].keys()
			statuslist.sort()
			
			self.sorted_transfer_list[list] = statuslist
			num = 0
			filterlist = []
			for user_path in statuslist:
				valid = 1
				num += 1
				transfer, user, path, status, error, filepos, filesize, rate, place = self.transfers[list][user_path]
				username = {}
				username[user] = path
				self.data[list][num] = username
				if status not in status_list:
					valid = 0
				if valid:
					filterlist.append([user_path, num])
				
			del statuslist

			clipped_list, self.scrolling[list], self.windows["dimensions"][list]["start"] = self.scrollbox(filterlist, self.scrolling[list], self.windows["dimensions"][list]["height"]-1)
			del filterlist
			finallist = []
			for user_path, number in clipped_list:
				item = self.TransferItem(list, user_path, number)
				finallist.append(item)
			del clipped_list
			return finallist
		except Exception, e:
			self.Hlog("debug", "TransfersListCompact: " + str(e))
			
	def TransfersManagerDownload(self):
		try:
			if self.display["mode"] != "transfer":
				return
			if self.display["transfers"] != "downloads" and mucous_config["mucous"]["transbox"] != "split":
				return
			
			dtw = self.windows["text"]["downloads"]
			w = self.windows["dimensions"]["downloads"]

			finallist = self.TransfersListCompact("downloads")
			s = self.scrolling["downloads"]
			start = self.windows["dimensions"]["downloads"]["start"]

			try:
				if self.display["t_speed"] == True:
					swting = "Numb","Speed"," Size "," Username ","  Status  "," Que","  Path"
				else:
					swting = "Numb","Perc "," Size "," Username ","  Status  "," Que","  Path"
				
				dtw.erase()
				length = 0
				if self.display["transfers"] == "downloads":
					hattr = self.colors["green"] | curses.A_REVERSE
					hattr1 = self.colors["green"]
				else:
					hattr = self.colors["blafgcyabg"]
					hattr1 = curses.A_NORMAL  
				for i in swting:
					length += len(i)
					dtw.addstr(i, hattr)
					if i is not swting[-1]:
						dtw.addch(curses.ACS_VLINE, hattr1)
						length += 1
				filler = ((self.w-2 - length) * " ")
				dtw.addstr(filler, hattr)

				
			except:
				pass
			try:
				
				if finallist == []:
					dtw.addstr("\nNo transfers in this category, hit INSERT to switch to another.")
					dtw.noutrefresh()
					return
				count = 0
				for transfers in finallist:
					if transfers == None:
						continue
					
					if transfers[1] == 1:
						sattr = self.colors["green"] | curses.A_BOLD
					elif transfers[1] == 0:
						sattr = self.colors["magenta"] | curses.A_BOLD
					elif transfers[1] in (2, 3, 4, 5, 6, 8, 9):
						sattr = self.colors["yellow"]| curses.A_BOLD
					elif transfers[1] in (10, 11, 12, 13, 14):
						sattr = self.colors["red"] | curses.A_BOLD
					else:
						sattr = curses.color_pair(0) | curses.A_BOLD
					attr = curses.A_NORMAL
					attr1 = curses.A_NORMAL
					if count + start == s:
						attr = curses.A_REVERSE | curses.A_BOLD
						attr1 = curses.A_NORMAL | curses.A_BOLD
						sattr = curses.A_REVERSE | curses.A_BOLD | sattr

					try:
						dtw.addstr(self.encode_language(transfers[0])[:4], attr)
						dtw.addch(curses.ACS_VLINE, attr1)
						dtw.addstr(self.encode_language(transfers[0])[5:10], attr)
						dtw.addch(curses.ACS_VLINE, attr1)
						dtw.addstr(self.encode_language(transfers[0])[11:17], attr)
						dtw.addch(curses.ACS_VLINE, attr1)
						dtw.addstr(self.encode_language(transfers[0])[18:28], attr)
						dtw.addch(curses.ACS_VLINE, attr1)
						dtw.addstr(self.encode_language(transfers[0])[29:39], sattr)
						dtw.addch(curses.ACS_VLINE, attr1)
						dtw.addstr(self.encode_language(transfers[0])[40:44], attr)
						dtw.addch(curses.ACS_VLINE, attr1)
						dtw.addstr(self.encode_language(transfers[0])[45:w["width"]], attr)
						
					except :
						pass
					count += 1
			except Exception, e:
				self.Hlog("debug", "Download log: " + str(e))
			dtw.noutrefresh()

		except Exception, e:
			self.Hlog("debug", "Download Manager: " + str(e))
			
	def TransfersManagerUpload(self):
		try: 
			if self.display["mode"] != "transfer":
				return
			if self.display["transfers"] != "uploads" and mucous_config["mucous"]["transbox"] != "split":
				return

			utw = self.windows["text"]["uploads"]
			w = self.windows["dimensions"]["uploads"]
			
			finallist = self.TransfersListCompact("uploads")
			s = self.scrolling["uploads"]
			start = self.windows["dimensions"]["uploads"]["start"]
			try:
				if self.display["t_speed"] == True:
					swting = "Numb","Speed"," Size "," Username ","  Status  ","  Path"
				else:
					swting = "Numb","Perc "," Size "," Username ","  Status  ","  Path"
				utw.erase()
				length = 0
				if self.display["transfers"] == "uploads":
					hattr = self.colors["green"] | curses.A_REVERSE
					hattr1 = self.colors["green"]
				else:
					hattr = self.colors["blafgcyabg"]
					hattr1 = curses.A_NORMAL  
				for i in swting:
					length += len(i)
					utw.addstr(i, hattr)
					if i is not swting[-1]:
						utw.addch(curses.ACS_VLINE, hattr1)
						length += 1
				filler = ((self.w-2 - length) * " ")
				utw.addstr(filler, hattr)
			except:
				pass
				
			try:
				if finallist == []:
					utw.addstr("\nNo transfers in this category, hit INSERT to switch to another.")
					utw.noutrefresh()
					return
				count = 0
				for transfers in finallist:
					if transfers == None:
						continue
					
					if transfers[1] == 1:
						sattr = self.colors["green"] | curses.A_BOLD
					elif transfers[1] == 0:
						sattr = self.colors["magenta"] | curses.A_BOLD
					elif transfers[1] in (10, 11, 12, 13, 14):
						sattr = self.colors["red"] | curses.A_BOLD
					else:
						sattr = curses.color_pair(0) | curses.A_BOLD
					
					if count + start == s:
						attr = curses.A_REVERSE | curses.A_BOLD
						attr1 = curses.A_NORMAL | curses.A_BOLD
						sattr = curses.A_REVERSE | curses.A_BOLD | sattr
					else:
						attr = curses.A_NORMAL 
						attr1 = curses.A_NORMAL
					try:
						utw.addstr(self.encode_language(transfers[0])[:4], attr)
						utw.addch(curses.ACS_VLINE, attr1)
						utw.addstr(self.encode_language(transfers[0])[5:10], attr)
						utw.addch(curses.ACS_VLINE, attr1)
						utw.addstr(self.encode_language(transfers[0])[11:17], attr)
						utw.addch(curses.ACS_VLINE, attr1)
						utw.addstr(self.encode_language(transfers[0])[18:28], attr)
						utw.addch(curses.ACS_VLINE, attr1)
						utw.addstr(self.encode_language(transfers[0])[29:39], sattr)
						utw.addch(curses.ACS_VLINE, attr1)
						utw.addstr(self.encode_language(transfers[0])[40:w["width"]], attr)

					except:
						pass
					count += 1
					
			except:
				pass
			utw.noutrefresh()
		except Exception, e:
			self.Hlog("debug", "Upload Manager: " + str(e))
			
	def TransferItem(self, tran, user_path, num):
		try:
			vals = self.transfers[tran][user_path]
			transfer, user, path, status, error, filepos, filesize, rate, place = vals
			path = self.dlang(path)

			if filesize:
				filefrmt  = self.byte_format(filesize)
				if len(filefrmt) < 6:
					filefrmt = ' ' * (6-len(filefrmt)) + filefrmt

			else:
				percent = '  0'
				filefrmt = '0 Bits'
			n =  ((4 - len(str(num))) * " ") + str(num)
			u =  user[:10] + ((10 - len(user[:10])) * " ")
			if status == 14 :
				cut_status = self.dlang(error)[:10]
			else:	
				cut_status = self.states[status][:10]
			if len(cut_status) < 10:
				cut_status += (10-len(cut_status)) *" "
			
			if tran == "downloads":
				if place == 4294967295:
					place = ""
				else:
					place = str(place)
				if len(place) < 4:
					cut_place = (" " * (4 -(len(place) )) )+ place
				else:
					cut_place = place[:3] + "~"

			if self.display["t_speed"] == True:
				#Speed
				ratefrmt  = self.byte_format(rate)
				if len(ratefrmt) < 5:
					ratefrmt += ' '* (5-len(ratefrmt))
				
				if tran == "downloads":
					line = "%s|%s|%s|%s|%s|%s|%s" % (str(n), ratefrmt[:5], filefrmt , u, cut_status, cut_place, path[-self.w+45+2:])
				else:
					line = "%s|%s|%s|%s|%s|%s" % (str(n), ratefrmt[:5], filefrmt , u, cut_status,  path[-self.w+40+2:])
			else:
				# Percent
				if filesize != 0:
					percent = str(100 * filepos / filesize)
					percent =  ((3 - len(percent)) * " ") + percent
				else: percent = '  0'
				
				if tran == "downloads":
					line = "%s| %s%%|%s|%s|%s|%s|%s" % (str(n), percent[:5] , filefrmt , u, cut_status, cut_place, path[-self.w+45+2:])
				else:
					line = "%s| %s%%|%s|%s|%s|%s" % (str(n), percent[:5] , filefrmt , u, cut_status,  path[-self.w+40+2:])
			line += ((self.w-2 - len(line)) * " ")
			return line, status
		except Exception, e:
			self.Hlog("debug", "Transfer Item: "+tran +": " + str(e))

		# Change Room Title in edit window
		
	def scrollbox(self, current_list, hightlight_position, height):
		# Limit text to what fits inside the window
		try:
			length =len(current_list)
			if hightlight_position < 0:
				hightlight_position = 0
			elif hightlight_position > length -1:
				hightlight_position = length-1
			
			start = hightlight_position-height/2
			
			if start  < 0:
				to = hightlight_position + (height-height/2)-start
				start  = 0
				
			else:
				to = hightlight_position + (height-height/2)
				
			if to >= length:
				start = abs(to - length - start)
				to =length
				
			if length < height:
				start =0
			#self.Hlog("debug", "s%se%su%s"%(start,to,hightlight_position) )
			if current_list[start:to] != [None]:
				clipped_list = current_list[start:to]
			else:
				clipped_list = []
			return clipped_list, hightlight_position, start
		except Exception, e:
			self.Hlog("debug", "scrollbox: " + str(e))
			
	def show_nick_list(self, room):
		try:
			self.colorednicks = {}
			
			if self.data["rooms"][room] == None:
				return
			
			self.colorednicks[room] = []
			alphanicks=[]
			alphanicks = self.data["rooms"][room]
			alphanicks.sort(key=str.lower)
			self.Hlog("status", "Users in " + room)
			for username in alphanicks:
				if username == self.usernames["username"]:
					self.colorednicks[room].append([username, "Me"])
				elif username not in self.data["rooms"][room]:
					self.colorednicks[room].append([username, "Left"])
				elif username in self.config["banned"]:
					self.colorednicks[room].append([username, "Banned"])
				elif username in self.config["buddies"]:
					self.colorednicks[room].append([username, "Buddies" ])
				else:
					self.colorednicks[room].append([username, "Normal"])
				self.colorednicks[room].append([" ["+str(self.user["statistics"][username])+"]", "Normal"])
				line = username + (" " * (30 - len(username)) ) + "Files: " + str(self.user["statistics"][username][2])
				
				#line = "%s": [%s] Files" % (username,  )
				self.Hlog("status", line)
				if username is not alphanicks[-1]:
					self.colorednicks[room].append([", ", "NotLast"])
			mtype = "List"
			user = "!!!!"
			msg = self.colorednicks[room]
			
			#self.ChatRoomAppend("List", room, '!!!!', msg)
		except Exception, e:
			self.Hlog("debug", "show_nick_list: " + str(e))
			
			
	def UserInfoClose(self, user):
		try:
			if user in self.activeitems["info"]:
				self.activeitems["info"].remove(user)
			if self.activeitems["info"] != []:
				for users in self.activeitems["info"]:
					self.usernames["info"] = users
					break
			else:
				self.usernames["info"] = None
			if user in self.alert["INFO"]:
				self.alert["INFO"].remove(user)
			if self.display["mode"] == 'info':
				self.ModeInfo()
		except Exception, e:
			self.Hlog("debug", "UserInfoClose: " + str(e))
			
	def PrivateChatClose(self, user):
		try:
			if user in self.logs["private"].keys():
				del self.logs["private"][user]
			if self.logs["private"].keys() != []:
				for users in self.logs["private"].keys():
					self.usernames["private"] = users
					break
			else:
				self.usernames["private"] = None
			if user in self.alert["PRIVATE"]:
				self.alert["PRIVATE"].remove(user)
			if self.display["mode"] == 'private':
				self.ModePrivate()
		except Exception, e:
			self.Hlog("debug", "PrivateChatClose: %s" % str(e))
					
	def SearchClose(self, ticket):
		try:
			if ticket in self.data["search_tickets"].keys():
				del self.data["search_tickets"][ticket]
			if ticket in self.logs["search"]:
				del self.logs["search"][ticket]
			if self.data["search_tickets"].keys() != []:
				self.Spl["current_search"] = self.data["search_tickets"].keys()[0]
			else:
				self.Spl["current_search"] = "default__"
				
			if ticket in self.alert["SEARCH"]:
				self.alert["SEARCH"].remove(ticket)
			self.ModeSearch()
		except Exception, e:
			self.Hlog("debug", "SearchClose: " + str(e))
			
	def BrowseClose(self, user):
		try:
			if user in self.activeitems["browse"]:
				self.activeitems["browse"].remove(user)
				self.scrolling["browsedir"] = 0
			if user in self.logs["browse"]:
				del self.logs["browse"][user]
			if self.activeitems["browse"] != []:
				if self.usernames["browse"] == user:
					self.usernames["browse"] = self.activeitems["browse"][0]
			else:
				self.usernames["browse"] = "default__"
			if user in self.alert["BROWSE"] and user != "__default":
				self.alert["BROWSE"].remove(user)
			self.ModeBrowse()
		except Exception, e:
			self.Hlog("debug", "BrowseClose: " + str(e))
			
	def SearchClear(self):
		try:
			self.data["search_tickets"] = {}
			self.logs["search"] = {}
			self.search_number = 0
			self.Spl["current_search"]="default__"
			self.ModeSearch()
		except Exception, e:
			self.Hlog("debug", "SearchClear: " + str(e))
	
		
	# Rebuild ListBuddy from self.config
	def ListBuddy(self):
		try:
			if "buddies" not in self.config.keys():
				return
			self.logs["buddied"] = []
			alpha_list = SortedDict()
			for keyname, keyvalue in self.config["buddies"].items():
				alpha_list[keyname] = keyvalue
			
			for user, note in alpha_list.items():
				attributes = []
				if user in self.config["trusted"].keys():
					attributes.append("trusted")
				if user in self.config["ignored"].keys():
					attributes.append("ignored")
				if user in self.config["banned"].keys():
					attributes.append("banned")
				self.logs["buddied"].append([attributes, user, note])
		except Exception, e:
			self.Hlog("debug", "ListBuddy: " + str(e))
	# Rebuild ListTrust from self.config
	def ListTrust(self):
		try:
			if "trusted" not in self.config.keys():
				return
			self.logs["trusted"] = []
			alpha_list = SortedDict()
			for keyname, keyvalue in self.config["trusted"].items():
				alpha_list[keyname] = keyvalue
			
			for user, note in alpha_list.items():
				attributes = []
				if user in self.config["ignored"].keys():
					attributes.append("ignored")
				if user in self.config["banned"].keys():
					attributes.append("banned")
				if user in self.config["buddies"].keys():
					attributes.append("buddies")
				self.logs["trusted"].append([attributes, user, note])
				
		except Exception, e:
			self.Hlog("debug", "ListTrust: " + str(e))
	# Rebuild ListBan from self.config
	def ListBan(self):
		try:
			if "banned" not in self.config.keys():
				return
			self.logs["banned"] = []
			alpha_list = SortedDict()
			for keyname, keyvalue in self.config["banned"].items():
				alpha_list[keyname] = keyvalue
			
			for user, note in alpha_list.items():
				attributes = []
				if user in self.config["ignored"].keys():
					attributes.append("ignored")
				if user in self.config["buddies"].keys():
					attributes.append("buddies")
				if user in self.config["trusted"].keys():
					attributes.append("trusted")
				self.logs["banned"].append([attributes, user, note])
		except Exception, e:
			self.Hlog("debug", "ListBan: " + str(e))
	# Rebuild ListIgnore from self.config
	def ListIgnore(self):
		try:
			if self.config ==  {}:
				return
			if "ignored" not in self.config.keys():
				return
			self.logs["ignored"] = []
			alpha_list = SortedDict()
			for keyname, keyvalue in self.config["ignored"].items():
				alpha_list[keyname] = keyvalue
			
			for user, note in alpha_list.items():
				attributes = []
				if user in self.config["banned"].keys():
					attributes.append("banned")
				if user in self.config["buddies"].keys():
					attributes.append("buddies")
				if user in self.config["trusted"].keys():
					attributes.append("trusted")
				self.logs["ignored"].append([attributes, user, note])
				
							
		except Exception, e:
			self.Hlog("debug", "ListIgnore: " + str(e))
					
	def InputCompletionList(self):
		try:
			usercompletionlist = {}
			if "buddies" in self.config:
				for users in self.config["buddies"].keys():
					usercompletionlist[self.dlang(users)] = 0
			if "banned" in self.config:
				for users in self.config["banned"].keys():
					usercompletionlist[self.dlang(users)] = 0
			if "ignored" in self.config:
				for users in self.config["ignored"].keys():
					usercompletionlist[self.dlang(users)] = 0
			
			if self.display["mode"] == "chat":
				# Autocomplete users in the current room only
				if self.data["rooms"].keys() != []:
					for user in self.data["rooms"][self.Spl["room"]]:
						usercompletionlist[self.dlang(user)] = 0
			elif self.display["mode"] == "private":
				pmusers = self.logs["private"].keys()
				for user in pmusers:
					usercompletionlist[self.dlang(user)] = 0
			elif self.display["mode"] == "transfers":
				if self.transfers["uploads"].keys() != []:
					for userpath, values in self.transfers["uploads"].items():
						usercompletionlist[self.dlang(values[1])] = 0
				if self.transfers["downloads"].keys() != []:
					for userpath, values in self.transfers["downloads"].items():
						usercompletionlist[self.dlang(values[1])] = 0
			elif self.display["mode"] == "browse":
				if self.usernames["browse"] != None:
					if self.usernames["browse"] in self.data["browse_results"]:
						for dirs in self.data["browse_results"][self.usernames["browse"]].keys():
							usercompletionlist[self.dlang(dirs)] = 0
			for values in self.commandlist:
				usercompletionlist[self.dlang(values)] = 0
				
			if usercompletionlist.keys() != []:
				self.logs["tab_completion"] = usercompletionlist.keys()
				self.logs["tab_completion"].sort(key=str.lower)
			else:
				self.logs["tab_completion"] = []
		except Exception, e:
			self.Hlog("debug", "InputCompletionList: " + str(e))

	def ScrollText(self, line):
		try:
			key = self.key
			color_added = None
			scrolltext = None
			scrollchange = 0
			if self.display["mode"] not in ( "transfer", "search", "help", "debug", "info", "private", "lists", "roomlist", "chat", "browse"):
				self.key = None
				return 
			if self.display["mode"] == "chat":
				if self.display["chat"] == "chatroom":
					scrolltext = "chatroom"
					
					w = self.windows["dimensions"]["chat"]
					if self.Spl["room"] != None:
						selected_log = self.logs["rooms"][self.Spl["room"]]
					else: 
						self.DrawChatRoomWin()
						self.windows["text"]["chat"].refresh()
						return
				elif self.display["chat"] == "roombox":
					scrolltext = "roombox"
					w = self.windows["dimensions"]["roombox"]
					selected_log = self.logs["roombox"][self.Spl["room"]]
				elif self.display["chat"] == "roomstatus":
					scrolltext = "roomstatus"
					w = self.windows["dimensions"]["roomstatus"]
					selected_log = self.logs["roomstatus"][self.Spl["room"]]
				scrolldiff = w["height"]
			elif self.display["mode"] == "browse":
				if self.display["browse"] == "directories":
					scrolltext = "browsedir"
				else:
					scrolltext = "browsefile"
				scrolldiff = self.windows["dimensions"]["browse"]["height"]
			elif self.display["mode"] in ("debug", "help"):
				scrolltext = self.display["mode"]
				scrolldiff = self.windows["dimensions"]["help"]["height"]
			elif self.display["mode"] in ("info", "private"):
				scrolltext = self.display["mode"]
				scrolldiff = self.windows["dimensions"][self.display["mode"]]["height"]
			elif self.display["mode"] == "search":
				scrolltext = self.display["mode"]
				scrolldiff = self.windows["dimensions"]["search"]["height"]
			elif self.display["mode"] == "lists":
				if self.display["list"] == "interests":
					scrolltext = self.display["interests"]
					scrolldiff = self.windows["dimensions"][self.display["list"]]["height"]
					selected_log = self.logs[self.display["interests"]]
				else:
					scrolltext = self.display["list"]
					scrolldiff = self.windows["dimensions"][self.display["list"]]["height"]
					selected_log = self.logs[self.display["list"]]

			elif self.display["mode"] == "roomlist":
				scrolltext = "roomlist"
				scrolldiff = self.windows["dimensions"][ self.display["mode"] ]["height"]
			elif self.display["mode"] == "transfer":
				scrolltext = self.display["transfers"]
				scrolldiff = self.windows["dimensions"][scrolltext]["height"]-1
					
			if key == "KEY_UP":	
				self.scrolling[scrolltext] -= 1
				scrollchange = -1
			elif key == "KEY_DOWN":
				self.scrolling[scrolltext] += 1
				scrollchange = 1
			elif key == "KEY_PPAGE":
				self.scrolling[scrolltext] -= scrolldiff
				scrollchange = -scrolldiff 
				
				# upload or download window height - one line for heading
			elif key == "KEY_NPAGE":
				self.scrolling[scrolltext] += scrolldiff
				scrollchange = scrolldiff
			if self.scrolling[scrolltext] < 0:
				self.scrolling[scrolltext] = 0
			
			if self.display["mode"] == "chat":
				if self.display["chat"]  == "chatroom":
					#start -= 1
					self.FormatChatRoomText()
				elif self.display["chat"]  == "roombox":
					self.FormatChatRoomBox()
				elif self.display["chat"]  == "roomstatus":
					self.DrawChatRoomStatusText()
					
			elif self.display["mode"] == "browse":
				if self.scrolling[scrolltext]  >= len(self.data["directories"]):
					self.scrolling[scrolltext] = len(self.data["directories"] )
					curses.doupdate()
					return
				if self.display["browse"] == "directories":
					self.FormatBrowse(1)
				else:
					self.FormatBrowse(0)
				curses.doupdate()
			elif self.display["mode"] == "info":
				self.DrawUserInfoText()
			elif self.display["mode"] == "private":
				self.DrawPrivateChat()
			elif self.display["mode"] == "search":
				self.FormatSearches()
			elif self.display["mode"] == "lists":
				if self.display["list"] != "interests":
					self.SelectLists()
				else:
					self.DrawLikedInterests()
					self.DrawHatedInterests()
					self.DrawRecommendations()
					self.DrawSimilarUsers()
				return
			elif self.display["mode"] == "roomlist":
				self.FormatRoomsList()
				return self.sizedrooms[self.scrolling["roomlist"]]
			elif self.display["mode"] in ("help", "debug"):
				self.FormatHelp()
			elif self.display["mode"] == "transfer":
				if self.display["transfers"] == "uploads":
					self.TransfersManagerUpload()
					curses.doupdate()
				elif self.display["transfers"] == "downloads":
					self.TransfersManagerDownload()
					curses.doupdate()
				
			self.key = None
		except Exception, e:
			self.Hlog("debug", "scrolltext: " + str(e))
	# ---v  KEYS v
	
	# Tab completion

				
	def InputTabCompletion(self, line, part, firsttab, listline, pos):
		try:
			self.firsttab = firsttab
			self.listline = listline
			
			if self.firsttab ==0:
				self.InputCompletionList()
				
			if self.logs["tab_completion"] == []:
				return self.listline, self.firsttab, part, pos
				
			if self.display["mode"] not in ("roomlist", "chat", "lists", "info", "private", "browse", "transfer", "setup", "search", "help", "debug", "status"):
				return self.listline, self.firsttab, part, pos
			if len(part) <= 0:
				return self.listline, 0, part, pos
			if self.firsttab ==0:
				self.keepit=[]
				if self.display["mode"] == "roomlist":
					for words in self.data["roomlist"].keys():
						if words.upper().startswith(part[0:1].upper()):
							self.keepit.append(words)
				else:
					for words in self.logs["tab_completion"]:
						if part[0:1] == '/':
							# Be more picky with /commands
							if len(words) > len(part):
								if words.upper().startswith(part.upper()):
									self.keepit.append(words)
							
						else:
							if words.upper().startswith(part.upper()):
								self.keepit.append(words)
				self.keepit.sort(key=str.lower)
			self.firsttab +=1

			currentword = self.listline[pos]	
			lw = len(currentword)

			if currentword.upper().startswith(part.upper()):
				
				for words in self.keepit:
					self.listline[pos] = self.keepit[0]
					z = self.keepit[0]
					self.keepit.remove(self.keepit[0])
					self.keepit.append(z)


					break
				else:
					
					self.firsttab = 0
			else:
				self.firsttab = 0

			return self.listline, self.firsttab, part, pos

		except Exception, e:
			self.Hlog("debug", "InputTabCompletion: " + str(e))
							
	def InputHistory(self, key, line, history_count):
		try:
			self.Spl["history_count"] = history_count
			if line not in self.logs["history"] and line !='':
				if line.isspace():
					pass
				else:
					self.logs["history"].append(line)
			if len(self.logs["history"]) == 0:
				return line, self.Spl["history_count"]
			if key == "KEY_UP":
				self.Spl["history_count"] += 1
			if key == "KEY_DOWN":
				self.Spl["history_count"] -= 1
	
			last_line = len(self.logs["history"]) -1 - self.Spl["history_count"]
			if last_line < 0:
				last_line = len(self.logs["history"]) -1
				self.Spl["history_count"] = 0
			elif last_line > len(self.logs["history"]) -1:
				last_line = len(self.logs["history"]) -1
				self.Spl["history_count"] += 1
			line = self.logs["history"][ last_line]
			
			return line, self.Spl["history_count"]
		except Exception, e:
			self.Hlog("debug", "history: " + str(e))
			
	def get_transfer_number(self, this_list):
		try:
			if self.display["transfers"] != "downloads":
				mode = "uploads"
			else:
				mode = "downloads"
			number = None
			username = this_list[self.scrolling[mode]][1] 
			path = this_list[self.scrolling[mode]][2]
			
			userpath = (username, path)
			
			
			count = 1
			transfer = None
			for user, path  in self.sorted_transfer_list[mode]:
				if (user, path) == userpath:
					#transfer = count
					number = count
					break
				count += 1
			return number
		except Exception, e:
			self.Hlog("debug", "get_transfer_number: " + str(e))

	def MenuCreate(self, menu, up):
		try:
			
			self.Spl["current_menu"]=menu
			title = None
			number = None
			self.Spl["menunumber"] = up
			this_list = self.MenuFindList()
			if this_list == []:
				return
			if menu == "roombox":
				mode = "roombox"
				if self.display["chatshape"] == "rightlist":
					left = self.windows["dimensions"]["roombox"]["left"] - 22
				else:
					left = self.windows["dimensions"]["roombox"]["left"]+self.windows["dimensions"]["roombox"]["width"]+1
				top = 2; width = 20
				title = "%s" % (self.logs["roombox"][self.Spl["room"]][self.scrolling[mode]])[:16]
				user = name = self.logs["roombox"][self.Spl["room"]][self.scrolling[mode]]
				if user in self.user["statistics"].keys():
					number = str(self.user["statistics"][user][2]) + " Files"
				items = [["Private Message", "all"], ["Userinfo", "all"], ["IP Address", "all"], ["Browse", "all"], ["", "line"], ["Buddy", "buddies"], ["Ban", "banned"], ["Ignore", "ignored"], ["Trusted", "trusted"], ["Give Privileges", "giveprivs"]  ]
				height = len(items) + 2	
			elif menu == "lists":
				mode = self.display["list"]
				left = 25; top = 2; width = 20
				title = "%s" % (this_list[self.scrolling[mode]])[1][:16]
				name = this_list[self.scrolling[mode]][1]
				number = self.scrolling[mode] +1
				
				items = [["Private Message", "all"], ["Userinfo", "all"], ["IP Address", "all"], ["Browse", "all"], ["", "line"], ["Buddy", "buddies"], ["Ban", "banned"], ["Ignore", "ignored"], ["Trusted", "trusted"], ["Give Privileges", "giveprivs"]  ]
				height = len(items) + 2
				
			elif menu == "transfers":
				mode = self.display["transfers"]
				left = 25; top = 1; width = 20
				
				title = "%s" % this_list[self.scrolling[mode]][1][:16]
				name = this_list[self.scrolling[mode]][1]
				
				number = self.get_transfer_number(this_list)
				if self.display["transfers"] == "downloads":
					items = [["Retry", "transfers"], ["Retry All", "transfers"],["Abort", "transfers"], ["Abort User", "transfers"], ["Clear", "transfers"], ["Clear Finished", "transfers"], ["Clear User", "transfers"], ["", "line"], ["Private Message", "all"], ["Userinfo", "all"], ["IP Address", "all"], ["Browse", "all"], ["", "line"], ["Buddy", "buddies"], ["Ban", "banned"], ["Ignore", "ignored"], ["Trusted", "trusted"], ["Give Privileges", "giveprivs"],  ["Get Queue Place", "getplace"] ]
				else:
					items = [["Retry", "transfers"], ["Retry All", "transfers"],["Abort", "transfers"], ["Abort User", "transfers"], ["Clear", "transfers"], ["Clear Finished", "transfers"], ["Clear User", "transfers"], ["", "line"], ["Private Message", "all"], ["Userinfo", "all"], ["IP Address", "all"], ["Browse", "all"], ["", "line"], ["Buddy", "buddies"], ["Ban", "banned"], ["Ignore", "ignored"], ["Trusted", "trusted"], ["Give Privileges", "giveprivs"]  ]
				height = len(items) + 2	
			elif menu == "search":
				mode = "search"
				left = 25; top = 5; width = 20
				number = this_list[self.scrolling[mode]-self.windows["dimensions"]["search"]["start"]]
				title = "%s" % (self.data["search_results"][number][1])
				name = self.data["search_results"][number][1]
				
				items = [ ["Download", "download"], ["Download Dir", "downdir"], ["Display Full Path", "displaypath"], ["", "line"], ["Private Message", "all"], ["Userinfo", "all"], ["IP Address", "all"], ["Browse", "all"], ["", "line"], ["Buddy", "buddies"], ["Ban", "banned"], ["Ignore", "ignored"], ["Trusted", "trusted"], ["Give Privileges", "giveprivs"]]
				height = len(items) + 2	
			elif menu == "browse-dirs":
				mode = "browsedir"
				left = 23; top = 5; width = 20
				#number = this_list[self.scrolling[mode]-self.windows["dimensions"]["directories"]["start"]]
				title = "Directory" 
				name = self.usernames["browse"]
				
				items = [ ["Download Dir", "downdir"], ["Display Full Path", "displaypath"], ["", "line"], ["Private Message", "all"], ["Userinfo", "all"], ["IP Address", "all"], ["Refresh Shares", "all"], ["", "line"], ["Buddy", "buddies"], ["Ban", "banned"], ["Ignore", "ignored"], ["Trusted", "trusted"],  ["Give Privileges", "giveprivs"]]
				height = len(items) + 2	
			elif menu == "browse-files":	
				mode = "browsefile"
				left = 2; top = 5; width = 20
				number =self.scrolling[mode] + 1 #self.windows["dimensions"]["browse"]["start"]+1
				title = "File"
				name = self.usernames["browse"]
				
				items = [ ["Download", "download"], ["Download Dir", "downdir"], ["Display Full Path", "displaypath"], ["", "line"], ["Private Message", "all"], ["Userinfo", "all"], ["IP Address", "all"], ["Browse", "all"], ["", "line"], ["Buddy", "buddies"], ["Ban", "banned"], ["Ignore", "ignored"], ["Trusted", "trusted"], ["Give Privileges", "giveprivs"]]
				height = len(items) + 2	
			elif menu == "encoding":
				left = self.w-27; top = 2; width = 20
				number =  None
				title = "Encoding"
				
				if self.display["mode"] == "browse":
					if self.usernames["browse"] != "default__":
						name = self.usernames["browse"]
					else:
						name = "Filesystem"
				elif self.display["mode"] == "chat":
					name = self.Spl["room"]
				elif self.display["mode"] == "private":
					name = self.usernames["private"]
					
				items = [ ["UTF-8", ""], ["iso-8859-1", ""], ["iso-8859-2", ""], ["iso-8859-3", ""], ["iso-8859-4", ""], ["iso-8859-5", ""], ["iso-8859-6", ""], ["iso-8859-7", ""], ["iso-8859-8", ""], ["iso-8859-9", ""], ["iso-8859-10", ""], ["iso-8859-11", ""], ["iso-8859-13", ""],["iso-8859-14", ""],["iso-8859-15", ""], ["iso-8859-16", ""],["KIO8-R", ""], ["CP1250", ""], ["CP1251", ""],["CP1252", ""],["CP1253", ""],["CP1254", ""],["CP1255", ""],["CP1256", ""],["CP1257", ""],["CP1258", ""],["CP874", ""] ]
				if  len(items)+2 > self.h-9:
					height = self.h-9
				else:
					height = len(items)+2
			# Cleanup stale windows
			if "menu" in self.windows["text"]:
				del self.windows["text"]["menu"]
			if "menu" in self.windows["border"]:
				del self.windows["border"]["menu"]
			if "menubg" in self.windows["border"]:
				del self.windows["border"]["menubg"]
			winbg = self.windows["border"]["menubg"] = curses.newwin(height+1, width+1, top, left)
			winbg.erase()
			winbg.noutrefresh()
			win =  self.windows["border"]["menu"] = curses.newwin(height, width, top, left)
			win.attron(self.colors["green"] | curses.A_BOLD)
# 			win.bkgdset(" ", self.colors["green"])
			win.erase()
			win.border()
			if title != None:
				win.addstr(0, 1,  "<%s>" % title)
			if number != None:
				win.addstr(height-1, 1,  "< %s >" % number)
			win.attroff(self.colors["green"] | curses.A_BOLD)
			win.noutrefresh()
			scroll = self.windows["text"]["menu"] = win.subwin(height-2, width-2, top+1, left+1)
# 			scroll.erase()
			scroll.scrollok(0)
# 			scroll.noutrefresh()
			self.menus[menu] = {"window": win, "scroll": scroll, "name": name, "items": items, "top": top, "width": width, "height": height, "left": left}
			self.MenuDraw(menu)

			#sleep(1)
		except Exception, e:
			self.Hlog("debug", "Create Menu " +str(e))
		
	def MenuDraw(self, menu):
		try:
			self.menus[menu]["scroll"].erase()
			c = 0

			clipped_list, self.Spl["menunumber"], start = self.scrollbox(self.menus[menu]["items"], self.Spl["menunumber"], self.menus[menu]["height"]-2)
			#for z in self.menus[menu]["items"]:
			for z in clipped_list:
				try:
					username = self.menus[menu]["name"]
						
					if z[1] in ("banned", "ignored", "buddies", "trusted"):
						if z[1]=="buddies":
							that_list = self.config["buddies"].keys()
						elif z[1]=="banned":
							that_list = self.config["banned"].keys()
						elif z[1]=="ignored":
							that_list = self.config["ignored"].keys()
						elif z[1]=="trusted":
							that_list = self.config["trusted"].keys()	
						r = 0
						if username in that_list:
							r = 1
								
						if r == 1:
							self.menus[menu]["scroll"].addstr("* ", self.colors["green"])
						else:
							self.menus[menu]["scroll"].addstr("* ", self.colors["red"])
						
						spaces = " " * (self.menus[menu]["width"]-2 - len(z[1]) -2)
						line = z[1].capitalize()+spaces
	
					elif z[1] == "line":
						line =" "  * (self.menus[menu]["width"]-2)
						if self.Spl["menunumber"] == c + start:
							self.menus[menu]["scroll"].addstr(line, self.colors["green"] | curses.ACS_HLINE)
						else:
							self.menus[menu]["scroll"].addstr(line,  curses.ACS_HLINE)
						c += 1
						continue
					else:
						spaces = " " * (self.menus[menu]["width"]-2 - len(z[0]) )
						line = z[0] + spaces
						
					if self.Spl["menunumber"] == c +start:
						self.menus[menu]["scroll"].addstr(line, self.colors["green"])
					else:
						self.menus[menu]["scroll"].addstr(line)
				except Exception, e:
	
					pass
				c += 1
			self.menus[menu]["scroll"].noutrefresh()
			curses.doupdate()
		except Exception, e:
			self.Hlog("debug", "MenuDraw " +str(e))
			
	def MenuFindList(self):
		try:
			if self.Spl["current_menu"] == "encoding":
				return [""]
			if self.display["mode"] == "chat":
				this_list = self.logs["roombox"][self.Spl["room"]]
			elif self.display["mode"] == "lists":
				this_list = self.logs[self.display["list"]]

			elif self.display["mode"] == "transfer":
				this_list = self.get_transfers_list()
			elif self.display["mode"] == "search":
				this_list = self.activeitems["search"]
			elif self.display["mode"] == "browse":
				if self.usernames["browse"] != "default__":
					if self.display["browse"] == "files":
						this_list = self.data["files"]
					elif self.display["browse"] == "directories":
						this_list = self.data["directories"]
				
			return this_list
		except Exception, e:
			self.Hlog("debug", "MenuFindList " +str(e))
			
	def get_transfers_list(self):
		try:
			this_list = []
			
			if self.display["transfer_sort"] == 'active':
				status_list = (1, 2, 3, 4, 5, 6, 8, 9,)
			elif self.display["transfer_sort"] == 'all':
				status_list = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,  14)
			elif self.display["transfer_sort"] == 'finished':
				status_list = (0, 99999)
			elif self.display["transfer_sort"] == 'queued':
				status_list = (7, 99999)
			elif self.display["transfer_sort"] == 'failed':
				status_list = (  10, 11, 12, 13)
			if self.display["transfers"] == "uploads":
				
				for username, path in self.sorted_transfer_list["uploads"]:
					vals = self.transfers["uploads"][(username, path)]
					upload, username, path, status, error, filepos, filesize, rate = vals[0], vals[1], vals[2], vals[3], vals[4], vals[5], vals[6], vals[7]
					if status in status_list:
						this_list.append(vals)
						
			elif self.display["transfers"] == "downloads":
				#self.Hlog("debug", self.sorted_transfer_list["downloads"])
				for username, path in self.sorted_transfer_list["downloads"]:
					vals = self.transfers["downloads"][(username, path)]
					upload, username, path, status, error, filepos, filesize, rate = vals[0], vals[1], vals[2], vals[3], vals[4], vals[5], vals[6], vals[7]
					if status in status_list:
						this_list.append(vals)
			#this_list.sort(key=str.lower)
			return this_list
		except Exception, e:
			self.Hlog("debug", "get_transfers_list: " + str(e))
			
	def MenuPickItem(self, x, y, click):
		try:
			width = self.menus[self.Spl["current_menu"]]["width"]
			top = self.menus[self.Spl["current_menu"]]["top"]
			height = self.menus[self.Spl["current_menu"]]["height"]
			left = self.menus[self.Spl["current_menu"]]["left"]
			
			if x >= left and x < width + left and y >= top and y < top + height:
				if y > top and y < top + height -1:
					y -= top+1
					#self.error_bar("y"+str(y) + " x"+ str(x))
					self.Spl["menunumber"] = y
					self.MenuDraw(self.Spl["current_menu"])
					if click in (2, 8, 16384):
						
						s = self.MenuExecute()
						if s == 0:
							self.refresh_windows()
							self.Spl["show_menu"] = False
							self.Spl["current_menu"] = None
						elif s == 3:
							self.Spl["show_menu"] = False
							self.Spl["current_menu"] = None
			else:
				self.Spl["show_menu"] = False
				self.Spl["current_menu"] = None
				self.MenuRefresh()
		except Exception, e:
			self.Hlog("debug", "MenuPickItem: " + str(e))
			
	def MenuEnter(self):
		try:
			s = self.MenuExecute()
			if s == 0:
				self.refresh_windows()
				self.Spl["show_menu"] = False
				self.Spl["current_menu"] = None
			elif s == 3:
				self.Spl["show_menu"] = False
				self.Spl["current_menu"] = None
			else:
				self.MenuDraw(self.Spl["current_menu"])
			#self.menu()
		except Exception, e:
			self.Hlog("debug", "MenuEnter: " + str(e))
			
	def MenuRefresh(self):
		try:
			#self.menu()
			self.refresh_windows()
		except Exception, e:
			self.Hlog("debug", "MenuRefresh: " + str(e))
			
	def MenuClear(self):
		try:
			self.Spl["show_menu"] = False
			self.Spl["current_menu"] = None
			self.MenuRefresh()
		except Exception, e:
			self.Hlog("debug", "MenuClear: " + str(e))
			
	def MenuExecute(self):
		try:
			
			num = self.Spl["menunumber"]
			if self.Spl["current_menu"] in ("roombox", "lists", "transfers", "search", "browse-dirs", "browse-files"):
				if self.Spl["current_menu"] == "roombox":
					mode = "roombox"
					username = self.logs["roombox"][self.Spl["room"]][self.scrolling[mode]]
				elif self.Spl["current_menu"] == "lists":
					mode = self.display["list"]
					username = self.MenuFindList()[self.scrolling[mode]][1]
				elif self.Spl["current_menu"] == "transfers":
					mode = self.display["transfers"]
					the_list = self.MenuFindList()
					item_num = self.scrolling[mode]
					username = the_list[item_num][1] 
					
					path = the_list[item_num][2]
					userpath = (username, path)
					transfer = self.get_transfer_number(the_list)
					if transfer == None:
						return
					if num == 0:
						# RETRY DOWNLOAD
						
						if self.display["transfers"] != "downloads":
							return 1
						if transfer in self.data["downloads"].keys():
							for username, path in self.data["downloads"][transfer].items():
								self.Hlog("status", "Retrying download: [%s] %s" % (username, path))
								self.SendMessage(messages.DownloadFile(username, path))
						else:
							self.Hlog("status", "No such transfer #" + str(transfer))
						return 0
					elif num == 1:
						# RETRY ALL DOWNLOADS
						if self.display["transfers"] != "downloads":
							return 1
						for user_path, transfer  in self.transfers["downloads"].items():
							if int(transfer[3]) in (10, 11, 12, 13, 14):
								self.SendMessage(messages.DownloadFile(transfer[1], transfer[2]))
						return 0
					elif num == 2:
						# ABORT TRANSFER
						if self.display["transfers"] == "downloads":
							if transfer in self.data["downloads"].keys():
								for username, path in self.data["downloads"][transfer].items():
									self.Hlog("status", "Aborting download: [%s] %s" % (username, path))
									self.SendMessage(messages.TransferAbort(0, username, path))
							else:
								self.Hlog("status", "No such transfer #" + str(transfer))
						elif self.display["transfers"] == "uploads":
							if transfer in self.data["uploads"].keys():
								for username, path in self.data["uploads"][transfer].items():
									self.Hlog("status", "Aborting upload: [%s] %s" % (username, path))
									self.SendMessage(messages.TransferAbort(1, username, path))
							else:
								self.Hlog("status", "No such transfer #" + str(transfer))
						return 0
					elif num == 3:
						# ABORT USER's TRANSFER(s)
						if self.display["transfers"] == "downloads":
							for userpath, values in self.transfers["downloads"].items():
								if userpath[0] == username:
									self.Hlog("status", "Aborting download: [%s] %s" % (username, values[2]))
									self.SendMessage(messages.TransferAbort(0, username, values[2]))
	
						elif self.display["transfers"] == "uploads":
							for userpath, values in self.transfers["uploads"].items():
								if userpath[0] == username:
									self.Hlog("status", "Aborting upload: [%s] %s" % (username, values[2]))
									self.SendMessage(messages.TransferAbort(1, username, values[2]))
	
						return 0
					elif num == 4:
						# Clear
						if self.display["transfers"] == "downloads":
							if transfer in self.data["downloads"].keys():
								for username, path in self.data["downloads"][transfer].items():
									self.Hlog("status", "Removing download: [%s] %s" % (username, path))
									self.SendMessage(messages.TransferRemove(0, username, path))
							else:
								self.Hlog("status", "No such transfer #" + str(transfer))
							
						elif self.display["transfers"] == "uploads":
							if transfer in self.data["uploads"].keys():
								for username, path in self.data["uploads"][transfer].items():
									self.Hlog("status", "Removing upload: [%s] %s" % (username, path))
									self.SendMessage(messages.TransferRemove(1, username, path))
							else:
								self.Hlog("status", "No such transfer #" + str(transfer))
						return 0
					elif num == 5:
						# Clear ALL FINISHED/FAILED
						if self.display["transfers"] == "downloads":
							for userpath, values in self.transfers["downloads"].items():
								if values[3] == 0:
									self.SendMessage(messages.TransferRemove(0, values[1], values[2]))
						elif self.display["transfers"] == "uploads":
							for userpath, values in self.transfers["uploads"].items():
								if values[3] in (0, 10, 11, 12, 13, 14):
									self.SendMessage(messages.TransferRemove(1, values[1], values[2]))
						return 0
					elif num == 6:
						# Clear USER's Transfers
						if self.display["transfers"] == "downloads":
							for userpath, values in self.transfers["downloads"].items():
								if userpath[0] == username:
									self.SendMessage(messages.TransferRemove(0, values[1], values[2]))
						elif self.display["transfers"] == "uploads":
							for userpath, values in self.transfers["uploads"].items():
								if userpath[0] == username:
									self.SendMessage(messages.TransferRemove(1, values[1], values[2]))
						return 0
					elif num == 7:
						return 1
					else:
						num -=8
				elif self.Spl["current_menu"] == "search":
					the_list = self.MenuFindList()
					mode = "search"
					number = the_list[self.scrolling[mode]-self.windows["dimensions"]["search"]["start"]]
					#self.Hlog("status", number)
					username = self.data["search_results"][number][1]
					path = self.data["search_results"][number][5]
					
					userpath = (username, path)
					
					if num == 0:
						# Download
						self.download_path_file("file", number)
						return 0
					elif num == 1:
						# Download Dir
						self.download_path_file("dir", number)
						return 0
					elif num == 2:
						self.Hlog("status", "[%d] %s" % (number, path))
						return 0
					elif num == 3:
						# Line
						return 1
					else:
						num -= 4
				elif self.Spl["current_menu"] in ("browse-dirs", "browse-files"):
					the_list = self.MenuFindList()
					username = self.usernames["browse"]

					path = self.Spl["dir_browse"]
					
					userpath = (username, path)
					
					if self.display["browse"] == "directories":
						mode = "browsedir"
						number = self.scrolling[mode]-self.windows["dimensions"]["directories"]["start"]
						if num == 0:
							# Download
							self.download_path_file("dir", number)
							return 0
						elif num == 1:
							self.Hlog("status", "[%d] %s" % (number, path))
							return 0
						else:
							num -= 2
					if self.display["browse"] == "files":
						mode = "browsefile"
						number = self.scrolling[mode]
						if num == 0:
							# Download
							self.download_path_file("file", number)
							return 0
						elif num == 1:
							# Download Dir
							self.download_path_file("dir", number)
							return 0
					
						elif num == 2:
							self.Hlog("status", "[%d] %s" % (number, path))
							return 0
						else:
							num -= 3
	
					if num == 0:
						return 1
					else:
						num -=1
				if num == 0:
					self.PrivateChatStart(username)
					self.ModePrivate()
				elif num == 1:
					self.requests["info"].append( username)
					self.SendMessage(messages.UserInfo(username))
					self.ModeInfo()
				elif num == 2:
					self.requests["ip"].append(username)
					self.SendMessage(messages.PeerAddress(username))
					self.ModeInfo()
				elif num == 3:
					self.BrowseUser(username)
				elif num == 4:
					return 1
				elif num == 5:
					if username not in self.config["buddies"].keys():
						self.ModifyConfig("buddy", username, '')
					else:
						self.ModifyConfig("unbuddy", username, '')
					return 1
				elif num == 6:
					if username not in self.config["banned"].keys():
						self.ModifyConfig("ban", username, '')
					else:
						self.ModifyConfig("unban", username, '')
					return 1
				elif num == 7:
					if username not in self.config["ignored"].keys():
						self.ModifyConfig("ignore", username, '')
					else:
						self.ModifyConfig("unignore", username, '')
					return 1
				elif num == 8:
					if username not in self.config["trusted"].keys():
						self.ModifyConfig("trust", username, '')
					else:
						self.ModifyConfig("distrust", username, '')
					return 1
				elif num == 9:
					self.usernames["privileges"] = username
					self.set_edit_title( "% Give Privileges to " + self.usernames["privileges"])
				elif num == 10:
					self.SendMessage(messages.TransferUpdate(username, path) )
			elif self.Spl["current_menu"] == "encoding":
				if num == 0: coding = "UTF-8"
				elif num == 1: coding = "iso-8859-1"  
				elif num == 2: coding = "iso-8859-2"  
				elif num == 3: coding = "iso-8859-3"  
				elif num == 4: coding = "iso-8859-4"  
				elif num == 5: coding = "iso-8859-5"  
				elif num == 6: coding = "iso-8859-6"  
				elif num == 7: coding = "iso-8859-7" 
				elif num == 8: coding = "iso-8859-8"  
				elif num == 9: coding = "iso-8859-9"  
				elif num == 10: coding = "iso-8859-10"  
				elif num == 11: coding = "iso-8859-11"  
				elif num == 12: coding = "iso-8859-13" 
				elif num == 13: coding = "iso-8859-14" 
				elif num == 14: coding = "iso-8859-15"  
				elif num == 15: coding = "iso-8859-16" 
				elif num == 16: coding = "KIO8-R" 
				elif num == 17: coding = "CP1250" 
				elif num == 18: coding = "CP1251" 
				elif num == 19: coding = "CP1252" 
				elif num == 20: coding = "CP1253" 
				elif num == 21: coding = "CP1254" 
				elif num == 22: coding = "CP1255" 
				elif num == 23: coding = "CP1256" 
				elif num == 24: coding = "CP1257" 
				elif num == 25: coding = "CP1258"
				elif num == 26: coding = "CP874" 
				#self.Hlog("debug", coding)
				if self.display["mode"] == "chat":
					self.SendMessage(messages.ConfigSet("encoding.rooms", self.Spl["room"], coding))
				elif self.display["mode"] == "private":
					self.SendMessage(messages.ConfigSet("encoding.users", self.usernames["private"], coding))
				elif self.display["mode"] == "browse":
					if self.usernames["browse"] != "default__":
						self.SendMessage(messages.ConfigSet("encoding.users", self.usernames["browse"], coding))
					else:
						self.SendMessage(messages.ConfigSet("encoding", "filesystem", coding))
					
			return 0
		except Exception, e:
			self.Hlog("debug", "MenuExecute " +str(e))

	def refresh_windows(self):
		
		try:
			if self.display["mode"] =="transfer":
				if mucous_config["mucous"]["transbox"]=="split":
					self.windows["border"]["uploads"].redrawwin()
					self.windows["border"]["uploads"].refresh()
					self.windows["border"]["downloads"].redrawwin()
					self.windows["border"]["downloads"].refresh()
				else:
					if self.display["transfers"] == "downloads":
						self.windows["border"]["downloads"].redrawwin()
						self.windows["border"]["downloads"].refresh()
					elif self.display["transfers"] == "uploads":
						self.windows["border"]["uploads"].redrawwin()
						self.windows["border"]["uploads"].refresh()
			elif self.display["mode"] =="lists":
				self.windows["border"][self.display["list"]].redrawwin()
				self.windows["border"][self.display["list"]].refresh()
				self.windows["text"][self.display["list"]].redrawwin()
				self.windows["text"][self.display["list"]].refresh()
			elif self.display["mode"] =="chat":
				self.windows["border"]["chat"].redrawwin()
				self.windows["border"]["chat"].refresh()
				self.windows["text"]["chat"].redrawwin()
				self.windows["text"]["chat"].refresh()
				if self.display["chatshape"] not in ("chat-only",  "nostatuslog"):
					self.windows["border"]["roomstatus"].redrawwin()
					self.windows["border"]["roomstatus"].refresh()
					self.windows["text"]["roomstatus"].redrawwin()
					self.windows["text"]["roomstatus"].refresh()
				if self.display["chatshape"] not in ( "noroombox", "chat-only"):
					self.windows["border"]["roombox"].redrawwin()
					self.windows["border"]["roombox"].refresh()
					
			elif self.display["mode"] =="browse":
				self.DrawBrowseWin()
				self.FormatBrowse()
				curses.doupdate()
			elif self.display["mode"] =="setup":
				self.ModeSetup()
			else:
				if self.display["mode"] in self.windows["border"]:
					self.windows["border"][self.display["mode"]].redrawwin()
					self.windows["border"][self.display["mode"]].refresh()
					self.windows["text"][self.display["mode"]].redrawwin()
					self.windows["text"][self.display["mode"]].refresh()
			self.windows["border"]["input"].redrawwin()
			self.windows["border"]["input"].refresh()
		except Exception,e:
			self.Hlog("debug", "Refresh Windows: "+str(e))
			
	def RotateList(self, direction, _list, place, sort):
		try:
			if not _list:
				return place
			if sort == "yes":
				_list.sort(key=str.lower)
			if not place in _list:
				if direction == "left":
					ix = -1
				elif direction == "right":
					ix = 0
				

			else:
				ix = _list.index(place)
				if direction == "left":
					ix -= 1
				elif direction == "right":
					ix += 1
				
				if ix < 0:
					ix = -1
				elif ix >= len(_list):
					ix = 0
			if ix != None:
				place = _list[ix]
			return place
		except Exception, e:
			self.Hlog("debug", "RotateList: " +str(e) )
			
	def MouseBrowse(self, x,y,z,event):
		try:
			d = self.windows["dimensions"]["directories"]
			w = self.windows["dimensions"]["browse"]
			if y in (1, 2, 3):
				if len(self.activeitems["browse"]) >= 1:
					
					if self.usernames["browse"] == "default__":
						self.usernames["browse"] = self.activeitems["browse"][0]
					else:
						self.usernames["browse"], match = self.MouseClickTab(x, self.usernames["browse"])
						if match == None:
							s = self.activeitems["browse"].index(self.usernames["browse"])
							self.usernames["browse"] = self.activeitems["browse"][s-1]
						sdirs =  self.data["browse_results"][self.usernames["browse"]].keys()
						sdirs.sort(key=str.lower)
						self.Spl["dir_browse"]=sdirs[0]
					
					self.ModeBrowse()
			elif y == w["top"] + w["height"]:
				if x < mucous_config["mucous"]["browse_width"]:
					if x in (7,8,9,10):
						if mucous_config["mucous"]["browse_width"] > 20: 
							mucous_config["mucous"]["browse_width"] -= 1
							self.ModeBrowse()
					elif x in (12,13,14,15,16,17):
						if mucous_config["mucous"]["browse_width"] < self.w-20:
							mucous_config["mucous"]["browse_width"] += 1
							self.ModeBrowse()
					
			elif y == w["top"]-1:
			
				if x >=self.w-17 and self.usernames["browse"] != "default__":
					self.usernames["browse"]="default__"
					self.ModeBrowse()
			elif x in range(d["width"]) and y >= d["top"] and y <= d["top"] + d["height"]:
				if self.usernames["browse"] == "default__":
					return
				if self.display["browse"] != "directories":
					self.display["browse"] = "directories"
					self.DrawBrowseWin()
					
				self.scrolling["browsedir"] = y - d["top"] + d["start"]
				self.FormatBrowse()
				
				if event in ( 4096, 16384):
					self.DrawChatRoomBox()
					self.Spl["show_menu"] = True
					self.MenuCreate("browse-dirs", 0)
				else:
					self.DrawChatRoomBox()
				curses.doupdate()
				
			elif x >=  w["left"] and y >= w["top"] and y <= w["top"] + w["height"]:
				if self.usernames["browse"] == "default__":
					return
				if self.display["browse"] != "files":
					self.display["browse"] = "files"
					self.DrawBrowseWin()
				self.scrolling["browsefile"] = y - w["top"]+ w["start"]
				self.FormatBrowse()
				
				if event in ( 4096, 16384):
					self.DrawChatRoomBox()
					self.Spl["show_menu"] = True
					self.MenuCreate("browse-files", 0)
				else:
					self.DrawChatRoomBox()
				curses.doupdate()
				
			elif y in ( self.h-5, self.h-6):
				if x>= self.w-27 and x < self.w-18:
					self.Spl["show_menu"] = True
					self.MenuCreate("encoding", 0)
					return
				elif x >=self.w-10 and x < self.w-1 and self.usernames["browse"] != "default__":
					self.BrowseClose(self.usernames["browse"])
		except Exception, e:
			self.Hlog("debug", "MouseBrowse: " +str(e) )
			
	def MouseChat(self, x,y,z,event, line):
		try:
			w = self.windows["dimensions"]["chat"]
			if y == w["top"]-1 and x >= w["left"]-1 and x < w["left"]+3:
				self.ChatRoomLayout()
				return
			# Clickable room switch
			
			if "roombox" in self.windows["dimensions"] and self.display["chatshape"] not in ( "noroombox", "chat-only"):
				roombox = self.windows["dimensions"]["roombox"]
				if y >= roombox["top"]-1 and y < roombox["top"] + roombox["height"] and x < roombox["width"] + roombox["left"] and x > roombox["left"]:
					if self.display["chat"] != "roombox":
						self.display["chat"] = "roombox"
						self.ModeChatRooms()
					y -= roombox["top"]
					if "start" not in roombox:
						return
					if y  + roombox["start"] in range(len(self.logs["roombox"][self.Spl["room"]])):
						
						sup = y  + roombox["start"]
						if event in ( 4096, 16384):
							if sup != self.scrolling["roombox"]:
								self.scrolling["roombox"] = sup
							self.DrawChatRoomBox()
							
							self.Spl["show_menu"] = True
							self.MenuCreate("roombox", 0)
							curses.doupdate()
						else:
							if sup != self.scrolling["roombox"]:
								self.scrolling["roombox"] = sup
								self.DrawChatRoomBox()
								curses.doupdate()
					return
				elif y == roombox["top"] + roombox["height"] and x < roombox["width"] + roombox["left"] and x > roombox["left"]:
					self.ModifyConfig("autojoin", self.Spl["room"], '')
						
			if y == self.h-3 or y == self.h-4:
				if x>= self.w-27 and x < self.w-18:
					self.Spl["show_menu"] = True
					self.MenuCreate("encoding", 0)
				
				elif x >= self.w-17 and x < self.w-1:
					joined = self.data["rooms"].keys()
					joined.sort(key=str.lower)
					if not self.Spl["room"] in joined:
						ix = 0
					else:
						ix = joined.index(self.Spl["room"])
						
						if x >= self.w-9 and x < self.w-1:
							# Next Button
							ix += 1
						elif x <= self.w-10 and x >= self.w-17:
							# Prev Button
							ix -= 1
						else:
							return
						if ix < 0:
							ix = -1
						elif ix >= len(joined):
							ix = 0
					self.ChatRoomChange(joined[ix])
					
			elif y  in (w["top"] + w["height"], w["top"] + w["height"]-1) and x >= w["left"] + w["width"]-5 and x <= w["left"] + w["width"]:
				self.key = "KEY_NPAGE"
				self.ScrollText(line)
				
			elif y in ( w["top"], w["top"]+1)  and x >= w["left"] + w["width"]-5 and x <= w["left"] + w["width"]:
				self.key = "KEY_PPAGE"
				self.ScrollText(line)
			else:
				if y >= w["top"]-1 and y < w["top"] + w["height"] +1 and x >= w["left"] -1 and x < w["left"] +w["width"]+1:
					if self.display["chat"] != "chatroom":
						self.display["chat"] = "chatroom"
						self.ModeChatRooms()
				if "roomstatus" in self.windows["dimensions"] and self.display["chatshape"] not in ( "nostatuslog", "chat-only") and self.display["chat"] != "roomstatus":
					w =  self.windows["dimensions"]["roomstatus"]
					if y >= w["top"]-1 and y < w["top"] + w["height"] +1 and x >= w["left"] -1 and x < w["left"] +w["width"]+1:
						self.display["chat"] = "roomstatus"
						self.ModeChatRooms()
		except Exception, e:
			self.Hlog("debug", "MouseChat: " +str(e) )
				
	def MouseClickTab(self, x, chosen):
		try:
			choz = self.activeitems["positions"][chosen]
			match = None
			if x >= choz[0] and x < choz[1]:
				# do nothing if chose search is clicked
				return chosen, 'yes'
			else:
				for key, pos in self.activeitems["positions"].items():
					if x >= pos[0]   and x < pos[1] :
						match = 'yes'
						break
			if match != None:
				return key, match
			else:
				return chosen, None
		except Exception, e:
			self.Hlog("debug", "MouseClickTab: " +str(e) )
		
	def MouseInterests(self, x,y,z,event):
		try:
			rexw = self.windows["dimensions"]["recommendations"]
			userw = self.windows["dimensions"]["similar_users"]
			hatew = self.windows["dimensions"]["hates"]
			likew = self.windows["dimensions"]["likes"]
			
			if y >= userw["top"]-1 and y < userw["top"] + userw["height"]+1 and x >= userw["left"]-1 and x < userw["left"]+1 +userw["width"]:
				w = userw
				if self.display["interests"] != "similar_users":
					self.display["interests"] = "similar_users"
			
				if y == w["top"] + w["height"]:
					if x >= w["left"]+w["width"] -11 and x <=  w["left"]+w["width"]:
						self.SendMessage(messages.GetSimilarUsers())
				if y >= w["top"] and y < w["top"] + w["height"] and x >= w["left"] and x < w["left"] +w["width"]:
					y -= w["top"]
					this_list = self.logs[self.display["interests"]]
					if y  + w["start"] in range(len(this_list)):
						self.scrolling[self.display["interests"]]  = y  + w["start"]
						self.line = str(self.logs[self.display["interests"]][self.scrolling[self.display["interests"]]][0])
				self.ModeInterests()
				return self.line
			elif y >= likew["top"]-1 and y < likew["top"] + likew["height"]+1 and x >= likew["left"]-1 and x < likew["left"]+1 +likew["width"]:
				w = likew
				if self.display["interests"] != "likes":
					self.display["interests"] = "likes"
					
				
				if y == w["top"] + w["height"]:
					
					if x >= w["left"]+2 and x <= w["left"]+7:
						
						if self.Spl["interests_input"] == "add_likes":
							self.InterestLikedAdd(self.line)
						else:
							self.Spl["interests_input"] = "add_likes"
					elif x >= w["left"]+9 and x <= w["left"]+w["width"]:
						if self.Spl["interests_input"] == "del_likes":
							self.InterestLikedRemove(self.line)
						else:
							self.Spl["interests_input"] = "del_likes"
						
				if y >= w["top"] and y < w["top"] + w["height"] and x >= w["left"] and x < w["left"] +w["width"]:
					y -= w["top"]
					this_list = self.logs[self.display["interests"]]
					
					if y  + w["start"] in range(len(this_list)):
						self.scrolling[self.display["interests"]]  = y  + w["start"]
						self.line = self.logs[self.display["interests"]][self.scrolling[self.display["interests"]]]

					
				self.ModeInterests()
				return self.line
			elif y >= hatew["top"]-1 and y < hatew["top"] + hatew["height"]+1 and x >= hatew["left"]-1 and x < hatew["left"]+1 +hatew["width"]:
				w = hatew
				if self.display["interests"] != "hates":
					self.display["interests"] = "hates"
				if y == w["top"] + w["height"]:
					if x >= 2 and x <= 7:
						if self.Spl["interests_input"] == "add_hates":
							self.InterestHatedAdd(self.line)
						else:
							self.Spl["interests_input"] = "add_hates"
						
					elif x >= w["left"]+9 and x <= w["left"]+w["width"]:
						if self.Spl["interests_input"] == "del_hates":
							self.InterestHatedRemove(self.line)
						else:
							self.Spl["interests_input"] = "del_hates"
				if y >= w["top"] and y < w["top"] + w["height"] and x >= w["left"] and x < w["left"] +w["width"]:
					y -= w["top"]
					this_list = self.logs[self.display["interests"]]
					if y  + w["start"] in range(len(this_list)):
						self.scrolling[self.display["interests"]]  = y  + w["start"]
						self.line = self.logs[self.display["interests"]][self.scrolling[self.display["interests"]]]
				self.ModeInterests()
				return self.line
					
			elif y >= rexw["top"]-1 and y < rexw["top"] + rexw["height"]+1 and x >= rexw["left"]-1 and x < rexw["left"]+1 +rexw["width"]:
				w = rexw
				if self.display["interests"] != "recommendations":
					self.display["interests"] = "recommendations"
				if y == w["top"] -1:
					if x >= w["left"]+w["width"] -len(self.Spl["recommend_sort"]) -5 and x <=  w["left"]+w["width"]:
						if self.Spl["recommend_sort"] == "size":
							self.Spl["recommend_sort"] = "alpha"
						elif self.Spl["recommend_sort"] == "alpha":
							self.Spl["recommend_sort"] = "size"
				elif y == w["top"] + w["height"]:
					if x >= w["left"]+ 1 and x <=  w["left"]+12:
						self.SendMessage(messages.GetRecommendations())
					elif x >= w["left"]+w["width"] -10 and x <=  w["left"]+w["width"]:
						self.SendMessage(messages.GetGlobalRecommendations())
				elif y >= w["top"] and y < w["top"] + w["height"] and x >= w["left"] and x < w["left"] +w["width"]:
					y -= w["top"]
					this_list = self.logs[self.display["interests"]]
					if y  + w["start"] in range(len(this_list)):
						self.scrolling[self.display["interests"]]  = y  + w["start"]
						self.line = self.logs[self.display["interests"]][self.scrolling[self.display["interests"]]][0]
						
				self.ModeInterests()
				return self.line
		except Exception, e:
			self.Hlog("debug", "MouseInterests: " +str(e) )
			
	
	def MousePrivate(self, x,y,z,event):
		try:
			if self.usernames["private"] == None:
				return
			if y in (2, 3, 4):
				if len(self.logs["private"].keys()) > 1:
					pmusers =  self.logs["private"].keys()
					pmusers.sort(key=str.lower)
					self.usernames["private"], match = self.MouseClickTab(x, self.usernames["private"])
					if match == None:
						s = pmusers.index(self.usernames["private"])
						self.usernames["private"] = pmusers[s-1]
					self.PrivateChatStart(self.usernames["private"])
					self.ModePrivate()
					
			if y == self.h-3 or y == self.h-4:
				if x>= self.w-27 and x < self.w-18:
					self.Spl["show_menu"] = True
					self.MenuCreate("encoding", 0)
				elif x >=self.w-10 and x < self.w-1:
					self.PrivateChatClose(self.usernames["private"])
		except Exception, e:
			self.Hlog("debug", "MousePrivate: " +str(e) )
			
		
	def MouseRoomList(self, x,y,z,event):
		try:
			if y == self.h-5:
				if x >= 14 and x <= 22:
					mucous_config["mucous"]["rooms_sort"] = "alpha"
					self.ModeRoomsList()
				elif x >= 24 and x <= 35:
					mucous_config["mucous"]["rooms_sort"] = "alpha-reversed"
					self.ModeRoomsList()
				elif x >= 37 and x <= 46:
					mucous_config["mucous"]["rooms_sort"] = "size"
					self.ModeRoomsList()
				elif x >= 47 and x <= 56:
					mucous_config["mucous"]["rooms_sort"] = "size-reversed"
					self.ModeRoomsList()
				elif x >= self.w-16:
					self.SendMessage(messages.RoomList())
					
			w = self.windows["dimensions"]["roomlist"]
			if y >= w["top"] and y < w["top"] + w["height"] and x >= w["left"] and x < w["left"] +w["width"]:
				y -= w["top"]
				if y  + w["start"] in range(len(self.sizedrooms)):
					self.scrolling["roomlist"]  = y  + w["start"]
					self.FormatRoomsList()
					return self.sizedrooms[self.scrolling["roomlist"]]
		except Exception, e:
			self.Hlog("debug", "MouseRoomList: " +str(e) )
			
	def MouseSearch(self, x,y,z,event):
		try:
			w = self.windows["dimensions"]["search"]
			if self.Spl["current_search"] != "default__":
				if y >= w["top"] and y < w["top"] + w["height"] and x >= w["left"] and x < w["left"] +w["width"]:
					#self.Hlog("debug", "%d:%d::%d" %(x,y,w["top"]) )
					y1 = y- w["top"]
					
					if y1  + w["start"] in range(self.search_number):
						self.scrolling["search"]  = y1  + w["start"]
						self.FormatSearches()
						if event in ( 4096, 16384):
							self.Spl["show_menu"] = True
							self.MenuCreate("search", 0)
							return

			if y in (1, 2, 3):
				if len(self.data["search_tickets"].keys()) >= 1:
					
					
					if self.Spl["current_search"] == "default__":
						self.Spl["current_search"] = self.data["search_tickets"].keys()[0]

					self.Spl["current_search"], match = self.MouseClickTab(x, self.Spl["current_search"])	
						
					if match == None:
						s = self.data["search_tickets"].keys().index(self.Spl["current_search"])
						self.Spl["current_search"] = self.data["search_tickets"].keys()[s-1]
					self.ModeSearch()

			elif y in ( self.h-3, self.h-4):
				if x >= 10 and x <= 20:
					# Toggle type of search
					if self.Spl["search_method"] == "globally":
						self.Spl["search_method"] = "buddies"
					elif self.Spl["search_method"] == "buddies":
						self.Spl["search_method"] = "rooms"
					elif self.Spl["search_method"] == "rooms":
						self.Spl["search_method"] = "globally"
					self.ModeSearch()
					
			elif y in ( self.h-5, self.h-6):
#m< Num|User|Free|Speed|Que|Path|Size|File|Bitrate|Time >< Reverse >

				change = 0
				if x >= 2 and x <= 6 and self.Spl["search_order"] != "num":
					self.Spl["search_order"] = "num"
					change = 1
				elif x >= 7 and x <= 11 and self.Spl["search_order"] != "user":
					self.Spl["search_order"] = "user"
					change = 1
				elif x >= 12 and x <= 16  and self.Spl["search_order"] != "free":
					self.Spl["search_order"] = "free"
					change = 1
				elif x >= 17 and x <= 22  and self.Spl["search_order"] != "speed":
					self.Spl["search_order"] = "speed"
					change = 1
				elif x >= 23 and x <= 26  and self.Spl["search_order"] != "que":
					self.Spl["search_order"] = "que"
					change = 1
				elif x >= 27 and x <= 31  and self.Spl["search_order"] != "path":
					self.Spl["search_order"] = "path"
					change = 1
				elif x >= 33 and x <= 36  and self.Spl["search_order"] != "size":
					self.Spl["search_order"] = "size"
					change = 1
				elif x >= 37 and x <= 41  and self.Spl["search_order"] != "file":
					self.Spl["search_order"] = "file"
					change = 1
				elif x >= 42 and x <= 49  and self.Spl["search_order"] != "bitrate":
					self.Spl["search_order"] = "bitrate"
					change = 1
				elif x >= 50 and x <= 54  and self.Spl["search_order"] != "time":
					self.Spl["search_order"] = "time"
					change = 1
				elif x >= 56 and x <= self.w-10:
					if self.Spl["search_reverse"] == True:
						self.Spl["search_reverse"] = False
					elif self.Spl["search_reverse"] == False:
						self.Spl["search_reverse"]= True
					change = 1
				elif x >=self.w-10 and x < self.w-1:
					self.SearchClose(self.Spl["current_search"])
				if change == 1:
					self.ModeSearch()
			
			elif y == 4:
				if self.Spl["current_search"] != "default__":
					if x >=self.w-18:
						self.Spl["current_search"]="default__"
						self.ModeSearch()
		except Exception, e:
			self.Hlog("debug", "MouseSearch: " +str(e) )
			
	## Mouse Coordinates in the Setup Mode
	# @param self is mucous
	# @param x is the horizontal position from the left
	# @param y is the vertical postion from the top
	# @param z is unimportant
	# @param event is the mouse event (button, doubleclick, etc) represented by a number
	def MouseSetup(self, x,y,z,event):
		try:
			
			if y in (0, 1):
				if x >=1 and x <=12:
					if self.display["setup"] != "mucous":
						self.display["setup"]="mucous"
						self.Spl["setup_input"] = "default"
				elif x >=16 and x <=26:
					if self.display["setup"] != "museek":
						self.display["setup"]="museek"
						self.Spl["setup_input"] = "default"
				elif x >=31 and x <=41:
					if self.display["setup"] != "shares":
						self.display["setup"]="shares"
						self.Spl["setup_input"] = "default"
				elif x >=46 and x <=57:
					if self.display["setup"] != "userinfo":
						self.display["setup"]="userinfo"
						self.Spl["setup_input"] = "default"
				elif x >=60 and x <=69:
					if self.display["setup"] != "logs":
						self.display["setup"]="logs"
						self.Spl["setup_input"] = "default"
				self.ModeSetup()

			if self.display["setup"]=="shares":
				if y in ( 3, 4, 5):
					if x >= 1 and x <= 16:
						self.MuscanListNormal()
					elif x >= 17 and x <= 32:
						self.MuscanAddNormal()
					elif x >= 33 and x < 49:
						self.MuscanRemoveNormal()

				if y in ( 6, 7, 8):
					if x >= 1 and x <= 16:
						self.MuscanRescanNormal()
					elif x >= 17 and x <= 32:
						self.MuscanUpdateNormal()
				elif y in ( 9, 10, 11):
					if x >= 1 and x <= 16:
						self.MuscanListBuddy()
					elif x >= 17 and x <= 32:
						self.MuscanAddBuddy()
					elif x >= 33 and x < 49:
						self.MuscanRemoveBuddy()
				elif y in ( 12, 13, 14):
					if x >= 1 and x <= 16:
						self.MuscanRescanBuddy()
					elif x >= 17 and x <= 32:
						self.MuscanUpdateBuddy()
					elif x >= 49 and x <= 66:
						self.SendMessage(messages.ReloadShares())
			elif self.display["setup"]=="userinfo":
				if y >= 1 and y < self.h-7:
					self.Spl["setup_input"]="userinfo"
				elif y <= self.h-5 and y >= self.h-7:
					self.Spl["setup_input"]="userimage"
				self.ModeSetup()
			elif self.display["setup"]=="logs":
				if y >= 2 and y <= 3 and x < 37:
					self.ToggleLogging()
					self.ModeSetup()
				
					
			if self.display["setup"] not in ("museek", "mucous"):
				return
			if y not in (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17):
				return
			if self.display["setup"]=="museek" and "transfers" in self.config:
				if y in (2, 3) and x >=1 and x <=35:
					self.Spl["setup_input"]="server-host"
					self.ModeSetup()
				elif y == 4 and x >=1 and x <=35:
					self.Spl["setup_input"]="soulseek-username"
					self.ModeSetup()
				elif y == 5 and x >=1 and x <=35:
					self.Spl["setup_input"]="soulseek-password"
					self.ModeSetup()
				elif y in (2, 3, 4) and x >=40 and x <=63:
					self.Spl["setup_input"]="museek-interface-password"
					self.ModeSetup()
				elif y in (5,6,7) and x >=50 and x <=63:
					# Connect Mode
					if "clients" in self.config:
						
						if self.config["clients"]["connectmode"] == "passive":
							self.SendMessage(messages.ConfigSet("clients", "connectmode", "active"))
						elif self.config["clients"]["connectmode"] == "active":
							self.SendMessage(messages.ConfigSet("clients", "connectmode", "passive"))
							
				elif y==8 and x >=1 and x <=30:
					#Buddies-only
					
					if self.config["transfers"]["only_buddies"] == "true":
						self.SendMessage(messages.ConfigSet("transfers", "only_buddies", "false"))
					elif self.config["transfers"]["only_buddies"] == "false":
						self.SendMessage(messages.ConfigSet("transfers", "only_buddies", "true"))
				elif y==9 and x >=1 and x <=30:
					
					if self.config["transfers"]["privilege_buddies"] == "true":
						self.SendMessage(messages.ConfigSet("transfers", "privilege_buddies", "false"))
							
					elif self.config["transfers"]["privilege_buddies"] == "false":
						self.SendMessage(messages.ConfigSet("transfers", "privilege_buddies", "true"))
				elif y==10 and x >=1 and x <=30:
					if self.config["transfers"]["have_buddy_shares"] == "true":
						self.SendMessage(messages.ConfigSet("transfers", "have_buddy_shares", "false"))
							
					elif self.config["transfers"]["have_buddy_shares"] == "false":
						self.SendMessage(messages.ConfigSet("transfers", "have_buddy_shares", "true"))
				elif y==11 and x >=1 and x <=50:
					if self.config["transfers"]["trusting_uploads"]== "true":
						self.SendMessage(messages.ConfigSet("transfers", "trusting_uploads", "false"))
							
					elif self.config["transfers"]["trusting_uploads"] == "false":
						self.SendMessage(messages.ConfigSet("transfers", "trusting_uploads", "true"))
				elif y==12 and x >=1 and x <=50:
					if self.config["transfers"]["user_warnings"] == "true":
						self.SendMessage(messages.ConfigSet("transfers", "user_warnings", "false"))
							
					elif self.config["transfers"]["user_warnings"] == "false":
						self.SendMessage(messages.ConfigSet("transfers", "user_warnings", "true"))
				
				elif y in (8,9,10)  and x >=49 and x <=64:
					s = int(self.config["transfers"]["upload_slots"]) 
					if x >=49 and x <=53:
						s  -= 1
					elif x >=54 and x <=64:
						s  += 1
					if s < 0:
						s = 0
					s = str(s)
					self.SendMessage(messages.ConfigSet("transfers", "upload_slots", s))
					self.ModeSetup()
				elif y in (13, 14):
					# Download Directory
					self.Spl["setup_input"]="download-dir"
					self.ModeSetup()
				elif y in (15, 16):
					# Incomplete Download Directory
					self.Spl["setup_input"]="incomplete-dir"
					#if x >=1 and x <=61:
					self.ModeSetup()
					
			elif self.display["setup"]=="mucous":
				if y in (2, 3, 4):
					if x >=1 and x <=35:
						self.Spl["setup_input"]="interface"
						self.ModeSetup()
				elif y in (5, 6, 7):
					if x >=1 and x <=35:
						self.Spl["setup_input"]="interface-password"
					self.ModeSetup()
				elif y == 8 and x >=1 and x <=40:
					self.ToggleTickersDisplay()
				elif y in (9, 10) and  x >=1 and x <=38:
					self.ToggleTickers()
						
				elif y == 11 and x >=1 and x <=38:
					if mucous_config["mucous"]["auto-clear"] == "yes":
						mucous_config["mucous"]["auto-clear"] = "no"
						self.clear_timer.cancel()
						self.clear_timer = threading.Timer(30.0, self.ThreadTransfersClear)
						
					else:
						mucous_config["mucous"]["auto-clear"] ="yes"
						self.clear_timer.cancel()
						self.clear_timer = threading.Timer(30.0, self.ThreadTransfersClear)
						self.clear_timer.start()
					self.ModeSetup()
				elif y in (8, 9, 10, 11) and x >= 39 and x <= 54:
					# Minimum size of rooms displayed in room list
					
					if x >=39 and x <=47:
						
						if y in (8, 9):
							
							mucous_config["tickers"]["cycletime"] = str(float (mucous_config["tickers"]["cycletime"])-0.5) 
						elif y in (10,11):
							
							mucous_config["tickers"]["scrolltime"] = str(float( mucous_config["tickers"]["scrolltime"])-0.1)
					elif x >=48 and x <=54:
						if y in (8, 9):
							
							mucous_config["tickers"]["cycletime"] = str( float( mucous_config["tickers"]["cycletime"])+0.5)
						elif y in (10,11):
							mucous_config["tickers"]["scrolltime"] = str(float( mucous_config["tickers"]["scrolltime"])+0.1)
					if float(mucous_config["tickers"]["scrolltime"]) < 0.1:
						mucous_config["tickers"]["scrolltime"] = str(0.1)
					if float(mucous_config["tickers"]["cycletime"]) < 1.0:
						mucous_config["tickers"]["cycletime"] = str(1.0)
					self.ModeSetup()
				elif y in (8, 9, 10) and x >= 55 and x <= 71:
					# Minimum size of rooms displayed in room list
					if x >=55 and x <=61:
						mucous_config["mucous"]["roomlistminsize"] -= 1
					elif x >=62 and x <=71:
						mucous_config["mucous"]["roomlistminsize"] += 1
					if mucous_config["mucous"]["roomlistminsize"] < 1:
						mucous_config["mucous"]["roomlistminsize"] = 1
					self.ModeSetup()
				
				elif y == 12 and x >=1 and x <=40:
					if str(mucous_config["mucous"]["auto-retry"]) == "yes":
						mucous_config["mucous"]["auto-retry"] = "no"
						self.retry_timer.cancel()
					else:
						mucous_config["mucous"]["auto-retry"] ="yes"
						self.retry_timer.cancel()
						self.retry_timer = threading.Timer(30.0, self.ThreadTransfersRetry)
						self.retry_timer.start()
					self.ModeSetup()
					
				elif y ==13  and x >=1 and x <=40:
					# Toggle Autobuddy
					if mucous_config["mucous"]["autobuddy"]  == "yes":
						mucous_config["mucous"]["autobuddy"] = "no"

					elif mucous_config["mucous"]["autobuddy"]  == "no":
						mucous_config["mucous"]["autobuddy"] = "yes"
					self.ModeSetup()
				elif y == 14 and  x >=1 and x <=40:
					self.ToggleBeep()

					
				elif y in (12, 13, 14) and x >=39 and x <=55:
					# Change charset, encoding, language that text is piped thru
					if "language" in mucous_config["mucous"]:
						if mucous_config["mucous"]["language"] in self.encodings:
							pos = self.encodings.index(mucous_config["mucous"]["language"])
							pos +=1
							if pos not in range(len(self.encodings)):
								pos = 0
							mucous_config["mucous"]["language"]=self.encodings [pos]
							self.ModeSetup()
						else:
							mucous_config["mucous"]["language"]=self.encodings [0]
							self.ModeSetup()
			
				elif y in (15, 16, 17):
					if x >=1 and x <=32:
						# Edit custom URL handler process
						self.Spl["setup_input"]="custom-url"
						self.ModeSetup()
					elif x >=35 and x <=49:
						# Cycle thru list of URL handlers
						u = mucous_config["mucous"]["url reader"]
						if u == 'lynx': u = 'links'
						elif u == 'links': u = 'elinks'
						elif u == 'elinks': u = 'firefox'
						elif u == 'firefox': u = 'custom'
						elif u == 'custom': u = 'lynx'
						mucous_config["mucous"]["url reader"] = u
						self.ModeSetup()
					elif x >=50 and x <=65:
						update_config()
						self.Hlog("status", "Config Saved")
		except Exception, e:
			self.Hlog("debug", "MouseSetup: " +str(e) )
	
	## Mouse Coordinates in the Transfers Modes
	# @param self is mucous
	# @param x is the horizontal position from the left
	# @param y is the vertical postion from the top
	# @param z is unimportant
	# @param event is the mouse event (button, doubleclick, etc) represented by a number
	def MouseTransfers(self, x,y,z,event):
		try:
			up = self.scrolling[self.display["transfers"]]
			if mucous_config["mucous"]["transbox"]=="split":
				u = self.windows["dimensions"]["uploads"]
				d = self.windows["dimensions"]["downloads"]
				
				w = None
				
				if y >= u["top"]+1 and y <= u["top"] + u["height"] and x >= u["left"] and x < u["left"] +u["width"]:
					if self.display["transfers"] != "uploads":
						self.display["transfers"] = "uploads"
						self.ModeTransfers()
					w = u
					#y -= w["top"]+1
				elif y >= d["top"]+1 and y <= d["top"] + d["height"] and x >= d["left"] and x < d["left"] +d["width"]:
					if self.display["transfers"] != "downloads":
						self.display["transfers"] = "downloads"
						self.ModeTransfers()
					w = d

				if w != None:
					if self.MouseTransferWindow(x, y, z, event, w) == 1:
						return

			else:
				if y == 1:
					if x >=2 and x < 26:
						self.display["transfers"]="uploads"
					elif x >=27 and x < 40:	
						self.display["transfers"]="downloads"
					self.ModeTransfers()
					return
					
				if self.display["transfers"] == "uploads":
					w = self.windows["dimensions"]["uploads"]
				else:
					w = self.windows["dimensions"]["downloads"]
				r = self.MouseTransferWindow(x, y, z, event, w)
				if r == 1:
					return	
		except Exception, e:
			self.Hlog("debug", "MouseTransfers: " +str(e) )
	
	## Mouse Coordinates in a Transfers Window
	# @param self is mucous
	# @param x is the horizontal position from the left
	# @param y is the vertical postion from the top
	# @param z is unimportant
	# @param event is the mouse event (button, doubleclick, etc) represented by a number
	# @param w is the curses window
	def MouseTransferWindow(self, x, y, z, event, w):
		try:
			if y >= w["top"]+1 and y < w["top"] + w["height"] and x >= w["left"] and x < w["left"] +w["width"]:
							
				y -= w["top"] +1
				if y  + w["start"] in range(len( self.get_transfers_list() )):
					if self.display["mode"] in ("chat", "private", "info", "search", "browse", "transfer"):
						mode = self.display["transfers"]
						self.scrolling[mode] = y  + w["start"]
	
				
				if self.display["transfers"] == "downloads":
					self.TransfersManagerDownload()
					curses.doupdate()
				else:
					self.TransfersManagerUpload()
					curses.doupdate()
				if event in ( 4096, 16384):
					if self.get_transfers_list() != []:
						self.Spl["show_menu"] = True
						self.MenuCreate("transfers", 0)
				return 1
			elif y == w["top"] + w["height"]:
				if x >=2 and x < 18:
					if mucous_config["mucous"]["transbox"]=="split":
						mucous_config["mucous"]["transbox"]="tabbed"
					elif mucous_config["mucous"]["transbox"]=="tabbed":
						mucous_config["mucous"]["transbox"]="split"
					self.ModeTransfers()
					return
				elif x >= 20:
					if x >=20 and x < 28:
						self.display["transfer_sort"] = 'all'
					elif x >=28 and x < 39:
						self.display["transfer_sort"] = 'active'
					elif x >=39 and x < 50:
						self.display["transfer_sort"] = 'queued'	
					elif x >=50 and x < 58:
						self.display["transfer_sort"] = 'finished'
					elif x >=63 and x < 75:
						self.display["transfer_sort"] = 'failed'
					self.ModeTransfers()
					return 1
			return 0
		except Exception, e:
			self.Hlog("debug", "MouseTransferWindow: " + str(e))
		
	## Mouse Coordinates in the User Info Mode
	# @param self is mucous
	# @param x is the horizontal position from the left
	# @param y is the vertical postion from the top
	# @param z is unimportant
	# @param event is the mouse event (button, doubleclick, etc) represented by a number
	def MouseUserInfo(self, x,y,z,event):
		try:
			if y in (2, 3, 4):
				if len(self.activeitems["info"]) >= 1:
					
					if self.usernames["info"] == None:
						self.usernames["info"] = self.activeitems["info"][0]
					self.usernames["info"], match = self.MouseClickTab(x, self.usernames["info"])
					if match == None:
						s = self.activeitems["info"].index(self.usernames["info"])
						self.usernames["info"] = self.activeitems["info"][s-1]
					#self.DrawUserInfoStats()
					self.ModeInfo()
					
			if self.usernames["info"] != None:
				if y  in (5,6):
					if x >=self.w-19-2-16 and x < self.w-12:
						self.usernames["info"]=None
						self.ModeInfo()
				elif y in ( self.h-3, self.h-4, self.h-5):
					if x >=self.w-10 and x < self.w-1:
						self.UserInfoClose(self.usernames["info"])
		except Exception, e:
			self.Hlog("debug", "MouseUserInfo: " +str(e) )
	
	## Mouse Coordinates in the Users Lists
	# @param self is mucous
	# @param x is the horizontal position from the left
	# @param y is the vertical postion from the top
	# @param z is unimportant
	# @param event is the mouse event (button, doubleclick, etc) represented by a number
	def MouseUsersLists(self, x,y,z,event):
		try:
			
			w = self.windows["dimensions"][self.display["list"]]
			if y == 1:
				if x >= 4 and x <= 15:
					self.display["list"]="buddied"
					self.ModeLists()
				elif x >= 17 and x <= 27:
					self.display["list"]="banned"
					self.ModeLists()
				elif x >= 29 and x <= 40:
					self.display["list"]="ignored"
					self.ModeLists()
				elif x >= 42 and x <= 51:
					self.display["list"]="trusted"
					self.ModeLists()
				elif x >= 52 and x <= 64:
					self.display["list"]="interests"
					self.ModeLists()
				return
			if self.display["list"] == "interests":
				return self.MouseInterests(x,y,z,event)
			elif self.display["list"] in ("buddied", "banned", "ignored", "trusted"):
				# clicking on items in lists
				if y >= w["top"] and y < w["top"] + w["height"] and x >= w["left"] and x < w["left"] +w["width"]:
					y -= w["top"]
					
					this_list = self.logs[self.display["list"]]
					if y  + w["start"] in range(len(this_list)):
						self.scrolling[self.display["list"]]  = y  + w["start"]
						
						if event in ( 4096, 16384):
							self.SelectLists()
							self.Spl["show_menu"] = True
							self.MenuCreate("lists", 0)
						else:
							self.SelectLists()
		except Exception, e:
			self.Hlog("debug", "MouseUsersLists: " +str(e) )
	
	## Mouse Coordinates: Switch modes or options in position matches requirements
	# @param self is mucous
	# @param line is a text string
	def MouseXY(self, line):
		
		try:
			(id,x,y,z,event) = curses.getmouse()
			#self.Hlog("debug", "%d %d %d %d %d" % (id, x, y, z,event))
			if event in (1, 128, 8192):
				# Ignore PRESSED and RELEASED
				return
			if x in range(8) and y == 0:
				if self.Spl["connected"] == 0:
					self.connect()
				elif self.Spl["connected"] == 1:
					self.ToggleAwayStatus()
				return
# 1Chat 2Private 3Transfers 4Search 5Info 6Browse 7Users 8Rooms 9Setup 10Help
			if y >= self.h-1:
				# clickable mode switching
				if x >= 0 and x < 7:
					self.ModeChatRooms()
				elif x >= 7 and x < 16:
					self.ModePrivate()
				elif x >= 16 and x < 27:
					self.ModeTransfers()
				elif x >= 27 and x < 35:
					self.ModeSearch()
				elif x >= 35 and x < 41:
					self.ModeInfo()
				elif x >= 41 and x < 49:
					self.ModeBrowse()
				elif x >= 49 and x < 56:
					self.ModeLists()
				elif x >= 56 and x < 63:
					self.ModeRoomsList()
				elif x >= 63 and x < 70:
					self.ModeSetupDefault()
				elif x >= 70 and x < 76:
					self.ModeHelp()
				return
				
			if self.Spl["show_menu"] == True and self.Spl["current_menu"] != None:
				width = self.menus[self.Spl["current_menu"]]["width"]
				top = self.menus[self.Spl["current_menu"]]["top"]
				height = self.menus[self.Spl["current_menu"]]["height"]
				left = self.menus[self.Spl["current_menu"]]["left"]
				if x >= left and x < left+width and y >= top and y < top+height:
					self.MenuPickItem(x, y, event)
					return
				else:
					self.MenuClear()
					
			if self.display["mode"] == "chat":
				self.MouseChat(x,y,z,event, line)
			elif self.display["mode"] == "private":
				# Clickable private message switch
				return self.MousePrivate(x,y,z,event)
			elif self.display["mode"] == "browse":
				return self.MouseBrowse(x,y,z,event)
			elif self.display["mode"] == "info":
				# Clickable user info tabs
				return self.MouseUserInfo(x,y,z,event)
			elif self.display["mode"] == "search":
				return self.MouseSearch(x,y,z,event)
			elif self.display["mode"] == "roomlist":
				# ROOMLIST BUTTONS
				return self.MouseRoomList(x,y,z,event)
			elif self.display["mode"] == "lists":
				return self.MouseUsersLists(x,y,z,event)
			elif self.display["mode"] == "transfer":
				# TRANSFERS BUTTONS
				# Clickable transfer type switcher
				return self.MouseTransfers(x,y,z,event)
			elif self.display["mode"] == "setup":
				return self.MouseSetup(x,y,z,event)
				

			elif self.display["mode"] in ("help", "debug"):
				if y == self.windows["dimensions"]["help"]["top"]-1:
					if x >= 4 and x <= 16 and self.display["mode"] != "help":
						self.display["mode"] = "help"
						self.ModeHelp()
					elif x >= 18 and x <= 31 and self.display["mode"] != "debug":
						self.display["mode"] = "debug"
						self.ModeHelp()
			# END OF MOUSE
			return line
		except Exception, e:
			self.Hlog("debug", "MouseXY: "+str(e) )
	
	## Parse Entry box for commands
	# @param self is mucous
	# @param line is a text string
	def InputCommands(self, line):
		try:
			if line[:1] != "/" or line[:2] == '//' or line[:4] == '/me ':
				if self.Spl["title"] and line:
					self.InputText(line)
				return
			#if line[:1] == "/" and line[:4] != "/me " and line[:2] != '//':
			
			if line == "/quit" or line == "/exit":
				update_config()
				self.shutdown()
				return 2
			elif line[:11] == "/disconnect":
				self.disconnect()
			elif line == "/debug":
				self.display["mode"] = "debug"
				self.ModeHelp()
			elif line[:5] == "/help":
				self.display["mode"] = "help"
				self.ModeHelp()
				if line[5:] == " chat":
					for line in self.help_chat:
						self.Hlog("help", line)
				elif line[5:] == " mode":
					for line in self.ModeHelp_text:
						self.Hlog("help", line)
				elif line[5:] == " user":
					for line in self.help_user:
						self.Hlog("help", line)
				elif line[5:] == " search":
					for line in self.help_search:
						self.Hlog("help", line)
				elif line[5:] == " browse":
					for line in self.help_browse:
						self.Hlog("help", line)
				elif line[5:] == " transfer":
					for line in self.help_transfer:
						self.Hlog("help", line)
				elif line[5:] == " ticker":
					for line in self.help_ticker:
						self.Hlog("help", line)
				elif line[5:] == " download":
					for line in self.help_download:
						self.Hlog("help", line)
				elif line[5:] == "":
					for line in self.help_help:
						self.Hlog("help", line)
				elif line[5:] == " keys":
					for line in self.help_keys:
						self.Hlog("help", line)
				elif line[5:] == " connect":
					for line in self.help_connect:
						self.Hlog("help", line)
				elif line[5:] == " setup":
					for line in self.help_setup:
						self.Hlog("help", line)
				try:
					self.edit.reset()
				except:
					pass
				'''
				Chatrooms
				'''
			elif line[:6] == "/talk ": 
				self.ChatRoomChange(line[6:])
				
			elif line[:6] == "/join ":
				self.doJoin(line[6:])
				
			elif line[:3] == "/j ":
				self.doJoin(line[3:])
				
			elif line in ("/part", "/p", "/l", "/leave")  and self.Spl["room"]:
				self.SendMessage(messages.LeaveRoom(self.Spl["room"]))
				
			elif line[:6] == "/part ":
				for room in self.data["rooms"].keys():
					if self.dlang( line[6:] ) == room:
						self.SendMessage(messages.LeaveRoom(room))
						
			elif line[:7] == "/leave ":
				for room in self.data["rooms"].keys():
					if self.dlang( line[7:] ) == room:
						self.SendMessage(messages.LeaveRoom(room))
				
			elif line[:10] == "/autojoin " and line[10:] != '':
				if line[10:] in self.data["rooms"].keys():
					room = line[10:]
					self.ModifyConfig("autojoin", room, '')
				else:
					self.Hlog("status", "You aren't in room: %s" % line[5:])
					
			elif line == "/autojoin":
				if self.Spl["room"] != None:
					room = self.Spl["room"]
					self.ModifyConfig("autojoin", room, '')
					
			elif line == "/extra":
				
				if mucous_config["mucous"]["extra_requests"] == "Yes":
					mucous_config["mucous"]["extra_requests"] = "No"
				elif mucous_config["mucous"]["extra_requests"] == "No":
					mucous_config["mucous"]["extra_requests"] = "Yes"
				if mucous_config["mucous"]["extra_requests"] not in ("Yes", "No"):
					mucous_config["mucous"]["extra_requests"] = "No"
				self.Hlog("status", "Extra CTCP-like version requests are responded to? %s"  % mucous_config["mucous"]["extra_requests"] )
				
			elif line[:4] == "/ut ":
				try:
					try:
						num = int(line[4:])
						for username, path in self.data["downloads"][num].items():
							self.SendMessage(messages.TransferUpdate(username, path) )
					except:
						return
					
				except Exception, e:
					self.Hlog("debug", str(e) )
					
			elif line == "/beep":
				self.ToggleBeep()
			elif line =="/ping":
				self.SendMessage(messages.Ping(1) )
			elif line[:6] == "/close":
				user = None
				if line[6:7] == " " and line[7:] != '':
					user == line[7:]
					
				if self.display["mode"] == 'private':
					if user != None: this_user = user
					else: this_user = self.usernames["private"]
					if this_user != None:
						self.PrivateChatClose(this_user)
						
				elif self.display["mode"] == 'chat':
					if user != None: room = user
					else: room = self.Spl["room"]
					if room in self.data["rooms"].keys():
						self.SendMessage(messages.LeaveRoom(room))
						
				elif self.display["mode"] == 'info':
					if user != None: this_user = user
					else: this_user = self.usernames["info"]
					if this_user != None:
						self.UserInfoClose(this_user)
						
				elif self.display["mode"] == 'browse':
					if user != None: this_user = user
					else: this_user = self.usernames["browse"]
					if this_user != "default__":
						self.BrowseClose(this_user)
						
				elif self.display["mode"] =='search':
					if self.Spl["current_search"] != "default__":
						self.SearchClose(self.Spl["current_search"])

			elif line[:4] == "/pm " and line[4:] != '':
				self.usernames["private"] = line[4:]
				self.PrivateChatStart(self.usernames["private"])
				if self.display["mode"] == 'private':
					self.ModePrivate()

					
			elif line[:5] == "/msg " and line[5:] != '':
				if self.usernames["private"] != None:
					message = line[5:]
					
					self.PrivateChatSend(self.usernames["private"], message)
				else:
					self.display["mode"] = "debug"
					self.ModeHelp()
					self.Hlog("status", "Set a user to message with /pm!")
					
			elif line == "/autoaway":
				aa = mucous_config["mucous"]["autoaway"]
				if aa == "yes":
					aa = "no"
				elif aa == "no":
					aa = "yes"
				mucous_config["mucous"]["autoaway"] = aa
				self.Hlog("status", "Autoaway is On? " + aa )
			elif line[:5] == "/away":
				self.ToggleAwayStatus()
					
			elif line[:5] == "/say " and line[5:] !='':
				# /say <room> /me is hungry
				sine = line[5:]
				splited = sine.split(' ')
				if len(splited) > 1:
					
					if splited[0] in self.data["rooms"].keys():
						room = splited[0]
						if splited[1].isspace():
							pass
						else:
							message = string.join(map(str, splited[1:]))
							self.SayInChat("chat", room, message)
					else:
						if len(splited) > 2:
							s = ''
							n = 0
							
							#self.Hlog("debug", str(splited))
							for i in range(len(splited)):
								if i == 0:
									s =splited[i]
								else:
									s += ' ' +splited[i]
								n += 1
								if s in self.data["rooms"].keys():
									break
		
							if s not in self.data["rooms"].keys():
								self.Hlog("debug", s)
								pass
							else:
								room = s
								message = string.join(map(str, splited[n:]))
								if message.isspace():
									pass
								else:
									self.SayInChat("chat", room, message)
							
		
			elif line[:4] == "/url" and line[4:] == '':
				self.url = None
				logfile = None
				if self.display["mode"] == "chat" and self.Spl["room"] != None:
					logfile = []
					for line in self.logs["rooms"][self.Spl["room"]]:
						logfile.append(line)
				elif self.display["mode"] == "private" and self.usernames["private"] != None:
					logfile = []
					for line in self.logs["private"][self.usernames["private"]]:
						logfile.append(line)
				if logfile != None:
					lene = len(logfile)
					logfile.reverse()
					if self.display["mode"] == "chat":
						for line in logfile:
							if "://" in line[3]:
								urline = line[3].split(" ")
								for x in urline:
									if "://" in x: self.url = x
									break
								break
					elif self.display["mode"] == "private":
						for timestamp, user, message in logfile:
							if "://" not in message:
								continue
							urline = message.split(" ")
							for x in urline:
								if "://" in x:
									 self.url = x
									 break
							break
						
		
				if self.url != None:
					urlr = mucous_config["mucous"]["url reader"]
					if  urlr == "links":
						if os.path.expandvars("$TERM") != "linux" and os.path.exists("/usr/bin/links"):
							os.system("xterm -e 'TERM=xterm-color links "+self.url +"' &")
					elif urlr == "elinks":
						if os.path.expandvars("$TERM") != "linux" and os.path.exists("/usr/bin/elinks"):
							os.system("xterm -e 'TERM=xterm-color elinks "+self.url +"' &")
					elif urlr == "lynx":
						if os.path.expandvars("$TERM") != "linux" and os.path.exists("/usr/bin/lynx"):
							os.system("xterm -e 'TERM=xterm-color lynx "+self.url +"' &")	
					elif urlr == "firefox":
						os.system("firefox -a firefox -remote 'openURL("+self.url +",new-tab)' &")
					elif urlr == "custom":
						os.system(mucous_config["mucous"]["url custom prefix"]+self.url+mucous_config["mucous"]["url custom suffix"]+" &")
						
			elif line[:11] == "/urlreader " and line[11:] != '':
				mucous_config["mucous"]["url reader"] = line[11:]
			elif line[:11] == "/urlcustom " and line[11:] != '':
				if "$" in line[11:]:
					custom = line[11:].split("$")
					if len(custom) > 1 and len(custom) < 3:
						mucous_config["mucous"]["url custom prefix"] = custom[0]
						mucous_config["mucous"]["url custom suffix"] = custom[1]
					elif len(custom) == 1:
						mucous_config["mucous"]["url custom prefix"] = custom[0]
						mucous_config["mucous"]["url custom suffix"] = ''
			elif line[:3] == "/np" and line[3:] == '':
				self.NowPlaying()
				
			elif line[:3] == "/w " and line[3:] != '' or line[:8] == "/window " and line[8:] != "":	
				if line[:3] == "/w ":
					num = line[3:]
				elif line[:8] == "/window ":
					num = line[8:]
				
				if num.isdigit() == 0:
					return
				
				if num == "1":
					self.ModeChatRooms()
				elif num == "2":
					self.ModePrivate()
				elif num == "3":
					self.ModeTransfers()
				elif num == "4":
					self.ModeSearch()
				elif num == "5":
					self.ModeInfo()
				elif num == "6":
					self.ModeBrowse()
				elif num == "7":
					self.ModeLists()
				elif num == "8":
					self.ModeRoomsList()
				elif num == "9":
					self.ModeSetupDefault()
				elif num == "10":
					self.ModeHelp()
						
			elif line[:7] == "/npset " and line[7:] != '':
				mucous_config["mucous"]["now-playing"] =line[7:]
				
			elif line[:8] == "/npcheck" and line[8:] == '':
				if "now-playing" in mucous_config["mucous"].keys():
					self.Hlog("status", "Now playing command is: "+ str(mucous_config["mucous"]["now-playing"]))
				
			elif line[:10] == "/npprefix " and line[10:] != '':
				mucous_config["mucous"]["now-playing-prefix"] = line[10:]
				
			elif line == "/npprefix":
				if "now-playing-prefix" in mucous_config["mucous"]:
					mucous_config["mucous"]["now-playing-prefix"] = None
			elif line in ("/rescan", "/rescanshares"):
				self.muscan_command = ["muscan", "-v"]
				self.muscan_timer.cancel()
				self.muscan_timer = threading.Timer(1.0, self.ThreadMuscan)
				self.muscan_timer.start()
				self.Hlog("status", "Updating normal shares with muscan, don't forget to Reload them.")
			elif line in ("/rescanbuddy"):
				self.muscan_command = ["muscan", "-b", "-v"]
				self.muscan_timer.cancel()
				self.muscan_timer = threading.Timer(1.0, self.ThreadMuscan)
				self.muscan_timer.start()
				self.Hlog("status", "Updating buddy shares with muscan, don't forget to Reload them.")
					
			elif line in ("/reload", "/reloadshares"):
				self.SendMessage(messages.ReloadShares() )
						
			elif line == "/redraw":
				self.line = self.build()
				
			elif line == "/logging":
				self.ToggleLogging()
				
				if self.display["mode"]=="setup":
					self.ModeSetup()
			elif line[:8] == "/logdir ":
				path = line[8:]
				if not path.isspace() and path != "":
					if os.path.exists(os.path.expanduser(path)):
						mucous_config["mucous"]["log_dir"] = os.path.expanduser(path)
						self.Hlog("debug", "Logs directory set to: %s" % path)
					else:
						self.Hlog("debug", "Path for logs directory, %s, doesn't exist" % path)
				'''
				User Information
				'''
			elif line[:10] == "/userinfo " and line[10:] != '':
				user = self.dlang( line[10:] ) 
				self.requests["info"].append(user)
				self.SendMessage(messages.UserInfo(user) )
					
			elif line[:3] == "/tc":
				self.InputCompletionList()
			elif line[:10] == "/language ":
				mucous_config["mucous"]["language"] = line[10:]
				
			elif line[:4] == "/ip " and line[4:] != '':
				try:
					
					user  = self.dlang( str(line[4:]) )
					self.requests["ip"].append(user)
					self.SendMessage(messages.PeerAddress(user))
				except Exception, e:
					self.Hlog("debug", e)
					
			elif line == "/ip":
				try:
					if self.display["mode"] == "private" and self.usernames["private"] != None:
						user  =  self.usernames["private"]
						self.requests["ip"].append(user)
						self.SendMessage(messages.PeerAddress(user))
				except Exception, e:
					self.Hlog("debug", e)
					
			elif line[:6] == "/stat " and line[6:] != '':
				user = self.dlang( str(line[6:]) )
				self.requests["statistics"].append(user)
				self.SendMessage(messages.PeerStats(user))
			elif line[:8] == "/status " and line[8:] != '':
				user = self.dlang( str(line[8:]) )
				self.requests["statistics"].append(user)
				self.SendMessage(messages.PeerStatus(user))
				'''
				MODE SELECTIONS
				'''
			
			elif line == "/chat" :
				self.ModeChatRooms()
		
			elif line == "/private"  or line == "/privatechat":
				self.ModePrivate()
		
			elif line[:7] == "/search"  and line[7:] == '':
				self.ModeSearch()
		
			elif line == "/transfer"  or line == "/transfers":
				self.ModeTransfers()
		
			elif line == "/info":
				self.ModeInfo()
				
			elif line == "/browse":
				self.ModeBrowse()
					
			elif line == "/buddylist" :
				self.display["list"] = "buddied"
				self.ModeLists()
			elif line == "/ListTrust" :
				self.display["list"] = "trusted"
				self.ModeLists()	
			elif line == "/banlist" :
				self.display["list"] = "banned"
				self.ModeLists()
				
			elif line == "/ignorelist" :
				self.display["list"] = "ignored"
				self.ModeLists()
				
			elif line == "/interests" :
				self.display["list"] = "interests"
				self.ModeLists()
				
			elif line[:6] == "/setup"   and line[6:] == '':
				self.ModeSetupDefault()
				
				'''
				CONFIG
				'''
			elif line[:5] == "/save" and line[5:] == '':
				update_config()
				self.display["mode"] = "debug"
				self.ModeHelp()
				self.Hlog("status", "Config Saved")
			elif line[:11] == "/interface " and line[11:] != "":
				mucous_config["connection"]["interface"] = line[11:]
				self.Hlog("status", "Museekd interface set to: " + line[11:])
		
			elif line[:10] == "/password " and line[10:] != "":
				mucous_config["connection"]["passw"] = line[10:]
				self.Hlog("status", "New password set")
			elif line[:13] == "/ctcpversion ":
				user = line[13:]
				if user != "" and user.isspace() == False:
					self.PrivateChatSend(user, curses.ascii.ctrl("A")+"VERSION"+curses.ascii.ctrl("A"))
			elif line == "/version":
				self.display["mode"] = "debug"
				self.ModeHelp()
				self.Hlog("status", "Mucous version: %s" % Version)
			elif line[:8] == "/connect":
				if self.Spl["connected"] == 0:
					self.invalidpass = 0
					self.line =""
					self.edit.reset()
					self.connect()
					
					return 0
				else:
					self.Hlog("status", "Already connected... aborting connection attempt.")
				'''
				Tickers
				'''
			elif line[:9] == "/tickroom":
				if line[9:] == '':
					self.Spl["ticker_room"] =  self.Spl["room"]
				elif line[9:10] == " " and line[10:] != '':
					self.Spl["ticker_room"] = line[10:]
			elif line == "/showtickers":
				self.ToggleTickersDisplay()
			elif line[:10] == "/tickers" and line[10:] == '':
				self.ToggleTickers()
			elif line[:13] == "/defaulttick " and line[13:] != '':
				message = line[13:]
				self.SendMessage(messages.ConfigSet("default-ticker", "ticker", message))
				
			elif line[:13] == "/settemptick " and line[13:] != '':
				if self.Spl["ticker_room"] != None:
					message = line[13:]
					self.SendMessage(messages.RoomTickerSet(self.Spl["ticker_room"], message))
				else:
					self.Hlog("status", "Choose a room with /tickroom, first.") 		
			elif line[:9] == "/settick " and line[9:] != '':
				if self.Spl["ticker_room"] != None:
					message = line[9:]
					self.SendMessage(messages.ConfigSet("tickers", self.Spl["ticker_room"], message))
					self.SendMessage(messages.RoomTickerSet(self.Spl["ticker_room"], message))
				else:
					self.Hlog("status", "Choose a room with /tickroom, first.") 
				'''
				List tickers in current room or selected rooms
				'''
			
			elif line[:9] == "/listtick":
				if line [9:] == '':
					woom = self.Spl["room"]
				else:
					woom = line[10:]
					
				alpha_list  = SortedDict()
				for rooms12 in self.data["tickers"]:
					alpha_list[rooms12] = self.data["tickers"][rooms12]
				#if mucous_config["tickers"]["tickers_enabled"] == 'yes':
				for rooms13, ticks in alpha_list.items():
					if rooms13 == woom:
						ttickers =[]
						ttickers = ticks.keys()
						if ttickers != []:
							self.LogInfo("Tickers in room: "+str(rooms13))
						ttickers.sort(key=str.lower)
						for names in ttickers:
							self.LogInfo(" ["+str(names)+'] '+str(ticks[names]))
		
		
				'''
				User Management
				'''
			elif line[:5] == "/ban " and line[5:] != '':
				username = line[5:]
				self.ModifyConfig("ban", username, '')
				
				
			elif line[:7] == "/unban " and line[7:] != '':
				username = line[7:]
				self.ModifyConfig("unban", username, '')
				
					
			elif line[:8] == "/ignore " and line[8:] != '':
				username = line[8:]
				self.ModifyConfig("ignore", username, '')
				
			elif line[:10] == "/unignore " and line[10:] != '':
				username = str(line[10:])
				self.ModifyConfig("unignore", username, '')
						
			elif line[:7] == "/buddy " and line[7:] != '':
				username = str(line[7:])
				self.ModifyConfig("buddy", username, '')
				
			elif line[:9] == "/unbuddy " and line[9:] != '':
				username = str(line[9:])
				self.ModifyConfig("unbuddy", username, '')
				
			elif line[:6] == "/nuke " and line[6:] != '':
				username = str(line[6:])
				self.ModifyConfig("ban", username, '')
				self.ModifyConfig("ignore", username, '')
				
				self.Hlog("status", "Nuked: %s" % username)
				
			elif line[:8] == "/unnuke " and line[8:] != '':
				username = str(line[8:])
				if username in self.config["ignored"].keys():
					self.ModifyConfig("unignore", username, '')
				if username in self.config["banned"].keys():
					self.ModifyConfig("unban", username, '')
					
				self.Hlog("status", "Irradiated: %s" % username)
				
			elif line[:7] == "/trust ":
				username = line[7:]
				self.ModifyConfig("trust", username, '')
			elif line[:10] == "/distrust ":	
				username = line[10:]
				self.ModifyConfig("distrust", username, '')
				
			elif line == "/autobuddy":
				if mucous_config["mucous"]["autobuddy"]  == "yes":
					mucous_config["mucous"]["autobuddy"] = "no"
					self.Hlog("status", "AutoBuddy Disabled")
				elif mucous_config["mucous"]["autobuddy"]  == "no":
					mucous_config["mucous"]["autobuddy"] = "yes"
					self.Hlog("status", "AutoBuddy Enabled")
				if self.display["mode"] == "setup":
					self.ModeSetup()
			elif line == "/autoclear":
				if str(mucous_config["mucous"]["auto-clear"]) == "yes":
					mucous_config["mucous"]["auto-clear"] = "no"
				else:
					mucous_config["mucous"]["auto-clear"] = "yes"
				if self.display["mode"] == "setup":
					self.ModeSetup()
			elif line == "/autoretry":
				if str(mucous_config["mucous"]["auto-retry"]) == "yes":
					mucous_config["mucous"]["auto-retry"] = "no"
				else:
					mucous_config["mucous"]["auto-retry"] = "yes"
				if self.display["mode"] == "setup":
					self.ModeSetup()
				'''
				List Users in room
				'''
			elif line[:5] == "/list":
				if line [5:6] == ' ':
					woom = line[6:]
				else:
					woom = self.Spl["room"]
				if woom != None:
					self.show_nick_list(woom)
					
			elif line[:6] == "/users":
				if line [6:7] == ' ':
					woom = line[7:]
				else:
					woom = self.Spl["room"]
				if woom != None:
					self.show_nick_list(woom)
					
			elif line == "/roombox":
				self.ChatRoomLayout()
				
			elif line == "/login":
				self.SendMessage(messages.ConnectServer())
				
			elif line == "/logout":
				self.SendMessage(messages.DisconnectServer())
				
			elif line == "/globalrex":
				self.SendMessage(messages.GetGlobalRecommendations())

				
			elif line in ("/rex", "/recommendations"):
				self.SendMessage(messages.GetRecommendations())
				
			elif line[:10] == "/uploadto ":
				user = line[10:]
				if user.isspace() == 0 and user != "":
					self.usernames["upload"] = user
					
			elif line[:8] == "/upload":
				path = line[8:]
				if path.isspace() == 0 and path != "":
					self.SendMessage(messages.UploadFile(self.usernames["upload"], path))	
					
			elif line in ("/similar", "/similarusers"):
				self.SendMessage(messages.GetSimilarUsers())
				
			elif line[:9] == "/itemrex ":
				if line[9:] != "" and line[9:].isspace() == 0:
					item = line[9:]
					self.SendMessage(messages.GetItemRecommendations(item))
					
			elif line[:13] == "/itemsimilar ":
				if line[13:] != "" and line[13:].isspace() == 0:
					item = line[13:]
					self.SendMessage(messages.GetItemSimilarUsers(item))
					
			elif line[:6] == "/like ":
				interest = line[6:]
				self.InterestLikedAdd(interest)
					
			elif line[:6] == "/hate ":
				interest = line[6:]
				self.InterestHatedAdd(interest)
					
			elif line[:11] == "/donotlike ":
				interest = line[11:]
				if interest in self.config["interests.like"]:
					self.InterestLikedRemove(interest)
					
			elif line[:11] == "/donothate ":
				interest = line[11:]
				if interest in self.config["interests.hate"]:
					self.InterestHatedRemove(interest)
					
			elif line == "/transbox":
				if mucous_config["mucous"]["transbox"]=="split":
					mucous_config["mucous"]["transbox"]="tabbed"
				elif mucous_config["mucous"]["transbox"]=="tabbed":
					mucous_config["mucous"]["transbox"]="split"
				self.ModeTransfers()
				'''
				List Rooms whose number of users is greater than the number you input
				'''
			elif line[:9] == "/roomlist":
				
				if line[9:] == '':
					self.ModeRoomsList()
				elif line[9:] == 'refresh':
					self.SendMessage(messages.RoomList())
					
			elif line in ("/privs", "/privileges"):
				self.SendMessage(messages.CheckPrivileges())
				
			elif line[:11] == "/giveprivs " :
				try:
					self.usernames["privileges"]  = str(line[11:])
					self.set_edit_title( "% Give Privileges to " + self.usernames["privileges"])
				except Exception, e:
					self.Hlog("debug", str(e))
				#self.SendMessage(messages.GivePrivileges("daelstorm", 20))
				
			elif line[:8] == "/inrooms" and line[8:] == '':
				w = ''
				for room in self.data["rooms"].keys():
					w += room + ', '
					
				self.Hlog("status", "You are in: %s" %w[:-2])
				
				'''
				Manual Download
				'''	
			elif line[:10] == "/downuser " and  line[10:] != '':
				self.ModeTransfers()
				self.usernames["download"] = line[10:]
				self.set_edit_title("% % User: "+line[10:] + " (input download path) % %")
				
			elif line[:12] == "/setdowndir " and  line[12:] != '':
				self.ModeTransfers()
				self.Spl["downloaddir"] = line[12:]
				self.set_edit_title("Download directory set to: "+self.Spl["downloaddir"] )
						
			elif line[:10] == "/downpath " and line[10:] != '':
				path = line[10:]
				if self.usernames["download"] != None and self.usernames["download"] != '':
					user = self.usernames["download"]
					p = path.split("\\")
					
					self.SendMessage(messages.DownloadFileTo(user, path, self.Spl["downloaddir"]+"/"+p[-1]))
					self.Hlog("status", "Trying to Download: " + path+" from "+ user+"to "+self.Spl["downloaddir"])
			elif line[:13] == "/downpathdir " and line[13:] != '':
				directory = line[13:]
				if self.usernames["download"] != None and self.usernames["download"] != '':
					user = self.usernames["download"]
					self.SendMessage(messages.GetFolderContents(user, directory))
					self.Hlog("status", "Try to Download directory: %s from %s" % (directory, user))
		
				'''
				Search Globally for files & Download them
				'''
			elif line[:11] == "/searchfor " and line[11:] != '':
				query = line[11:]
				if query not in ('mp3', ' ') and len(query) > 2:
					self.SendMessage(messages.Search(0, query))
					
				else:
					self.DrawSearchStats("sstatus", "Query \""+ query+"\" was ignored", "default__", 0)
					
			elif line[:12] == "/searchuser " and line[12:] != '':
				self.usernames["search"] = user = line[12:]
				if self.display["mode"]=='search':
					self.ModeSearch()
			elif line[:13] == "/searchbuddy " and line[13:] != '':
				query = line[13:]
				self.SendMessage(messages.Search(1, query))
			elif line[:12] == "/searchroom " and line[12:] != '':
				query = line[12:]
				self.SendMessage(messages.Search(2, query))
					
			elif line[:10] == "/download " or line[:9] == "/downdir ":
				linput = None
				if line[:10] == "/download " and line[10:] != '':
					dtype = "file"
					linput = line[10:]
				elif line[:9] == "/downdir "  and line[9:] != '':
					dtype = "dir"
					linput = line[9:]
				if linput != None:
					if linput.isdigit():
						self.download_path_file(dtype, linput)
					else:
						self.Hlog("status", "Enter an Integer")
						
			elif line[:8] == "/filter " and line[8:] != '':
				
				self.sfilter=line[8:]
				if self.display["mode"]=='search':
					self.ModeSearch()
			elif line == "/filter":
				self.sfilter=None
				if self.display["mode"]=='search':
					self.ModeSearch()
				'''
				Browse Shares & Download from them
				'''
			elif line[:4] == "/cd " and line[4:] != '':
				self.BrowseChangeDir(line[4:])
				
	
				
			elif line[:4] == "/get" and line[4:] != '':
				linput = None
				if line[:5] == "/get " and line[5:] != '':
					dtype = "file"
					linput = line[5:]
				elif line[:8] == "/getdir "  and line[8:] != '':
					dtype = "dir"
					linput = line[8:]
				if linput != None:
					if linput.isdigit():
						self.download_path_file(dtype, linput)
					else:
						self.Hlog("status", "Enter an Integer")
						
			elif line[:13] == "/browsewidth " and line[13:] != "":
				if line[13:].isdigit():
					width = int(line[13:])
					if width > self.w-20:
						width = self.w-20
					if width < 20:
						width = 20 
					mucous_config["mucous"]["browse_width"] = width
					
					if self.display["mode"] == "browse":
						self.ModeBrowse()
					
			elif line[:12] == "/browseuser " or line[:7] == "/buser ":
				user = None
				if line[:12] == "/browseuser " and line[12:] != '':
					user = line[12:]
				elif line[:7] == "/buser " and line[7:] != '':
					user = line[7:]
				if user != None:
					self.BrowseUser(user)
					
					
			elif line[:14] == "/browsesearch " or line[:9] == "/bsearch ":
				l_input = None
				if line[:14] == "/browsesearch " and line[14:] != '':
					l_input = line[14:]
				elif line[:9] == "/bsearch " and line[9:] != '':
					l_input = line[9:]
				if l_input != None:
					self.bfilter = re.compile('.*' +str(l_input) + '.*', re.DOTALL | re.I)
					self.FormatBrowse()
					curses.doupdate()
			elif line == "/browsesearch" or line == "/bsearch":
				self.bfilter = None
				self.FormatBrowse()
				curses.doupdate()
				'''
				Manage Transfers
				'''
			elif line[:8] == "/abortd " or line[:11] == "/abortdown ":
				transfer = None
				if line[:8] == "/abortd " and line[8:] != '':
					if line[8:].isdigit():
						transfer = int(line[8:])
					else:
						self.Hlog("status", "Enter an Integer")
				elif line[:11] == "/abortdown " and line[11:] != '':
					try:
						transfer = int(line[11:])
					except:
						self.Hlog("status", "Enter an Integer")
					
				if transfer != None:
					if transfer in self.data["downloads"].keys():
						for username, path in self.data["downloads"][transfer].items():
							#self.Hlog("debug", username +' '+ path)
							self.Hlog("status", "Aborting download: [%s] %s" % (username, path))
							self.SendMessage(messages.TransferAbort(0, username, path))
					else:
						self.Hlog("status", "No such transfer #" + str(transfer))
			elif line[:8] == "/abortu " or line[:9] == "/abortup ":
				transfer = None
				if line[:8] == "/abortu " and line[8:] != '':
					try:
						transfer = int(line[8:])
					except:
						self.Hlog("status", "Enter an Integer")
				elif line[:9] == "/abortup " and line[9:] != '':
					try:
						transfer = int(line[9:])
					except:
						self.Hlog("status", "Enter an Integer")
				if transfer != None:
					if transfer in self.data["uploads"].keys():
						for username, path in self.data["uploads"][transfer].items():
							self.Hlog("status", "Aborting upload: [%s] %s" % (username, path))
							self.SendMessage(messages.TransferAbort(1, username, path))
					else:
						self.Hlog("status", "No such transfer #" + str(transfer))
			elif line[:9] == "/removeu " or line[:10] == "/removeup ":
				transfer = None
				if line[:9] == "/removeu " and line[9:] != '':
					try:
						transfer = int(line[9:])
					except:
						self.Hlog("status", "Enter an Integer")
				elif line[:10] == "/removeup " and line[10:] != '':
					try:
						transfer = int(line[10:])
					except:
						self.Hlog("status", "Enter an Integer")
				if transfer != None:
					if transfer in self.data["uploads"].keys():
						for username, path in self.data["uploads"][transfer].items():
							self.Hlog("status", "Removing upload: [%s] %s" % (username, path))
							self.SendMessage(messages.TransferRemove(1, username, path))
					else:
						self.Hlog("status", "No such transfer #" + str(transfer))
					
		
			elif line[:9] == "/removed " or line[:12] == "/removedown ":
				transfer = None
				if line[:9] == "/removed " and line[9:] != '':
					try:
						transfer = int(line[9:])
					except:
						self.Hlog("status", "Enter an Integer")
				elif line[:12] == "/removedown " and line[12:] != '':
					try:
						transfer = int(line[12:])
					except:
						self.Hlog("status", "Enter an Integer")
				if transfer != None:
					if transfer in self.data["downloads"].keys():
						for username, path in self.data["downloads"][transfer].items():
							self.Hlog("status", "Removing download: [%s] %s" % (username, path))
							self.SendMessage(messages.TransferRemove(0, username, path))
					else:
						self.Hlog("status", "No such transfer #" + str(transfer))
		
						
			elif line[:7] == "/retry " and line[7:] != '':
				transfer = None
				try:
					transfer = int(line[7:])
				except:
					self.Hlog("status", "Enter an Integer")
				if transfer != None:
					
					if transfer in self.data["downloads"].keys():
						for username, path in self.data["downloads"][transfer].items():
							self.Hlog("status", "Retrying download: [%s] %s" % (username, path))
							self.SendMessage(messages.DownloadFile(username, path))
					else:
						self.Hlog("status", "No such transfer #" + str(transfer))
						
			elif line[:9] == "/retryall":
				for user_path, transfer  in self.transfers["downloads"].items():
					if int(transfer[3]) in (10, 11, 12, 13, 14):
						self.SendMessage(messages.DownloadFile(transfer[1], transfer[2]))
		
			elif line[:7] == "/slots " and line[7:] != "":
				slots = None
				try:
					slots = int(line[7:])
				except:
					self.Hlog("status", "Enter an Integer")
				if slots != None:
					self.SendMessage(messages.ConfigSet("transfers", "upload_slots", str(slots)))
		
			elif line[:10] == "/privbuddy":
				if self.config["transfers"]["privilege_buddies"] == "true":
					self.SendMessage(messages.ConfigSet("transfers", "privilege_buddies", "false"))
					
				elif self.config["transfers"]["privilege_buddies"] == "false":
					self.SendMessage(messages.ConfigSet("transfers", "privilege_buddies", "true"))
					
					
			elif line[:10] == "/onlybuddy":
				if self.config["transfers"]["only_buddies"] == "true":
					self.SendMessage(messages.ConfigSet("transfers", "only_buddies", "false"))
				elif self.config["transfers"]["only_buddies"] == "false":
					self.SendMessage(messages.ConfigSet("transfers", "only_buddies", "true"))
		
			elif line[:7] == "/unhide":
				if self.display["password"] == "yes":
					self.display["password"] = "no"
				elif self.display["password"] == "no":
					self.display["password"] = "yes"
				if self.display["mode"] == "setup":
					self.ModeSetup()
			elif line[:10] == "/buddyall":
				self.Hlog("status", "Buddying ALL users currently transferring to or from you.")
				currentusersintransferlist = {}
				for userpath, values in self.transfers["uploads"].items():
					currentusersintransferlist[values[1]] = 0
				for userpath, values in self.transfers["downloads"].items():
					currentusersintransferlist[values[1]] = 0
				for username in currentusersintransferlist.keys():
					if username not in self.config["buddies"].keys():
						self.SendMessage(messages.ConfigSet("buddies", username, "Buddied by mucous"))
						
			elif line[:6] == "/nick " and line[6:] != '':
				if self.usernames["username"] != None:
					self.SendMessage(messages.ConfigSet("server", "username", line[6:]))
			elif line == "/clearsearchs":
				self.SearchClear()
			elif line[:8] == "/clearup":
				for userpath, values in self.transfers["uploads"].items():
					if values[3] in (0, 10, 11, 12, 13, 14):
						self.SendMessage(messages.TransferRemove(1, values[1], values[2]))
			elif line == "/percent":
				if self.display["t_speed"] == True:
					self.display["t_speed"] = False
				elif self.display["t_speed"] == False:
					self.display["t_speed"] = True
				self.ModeTransfers()
				
			elif line[:10] == "/cleardown":
				for userpath, values in self.transfers["downloads"].items():
					if values[3] == 0:
						self.SendMessage(messages.TransferRemove(0, values[1], values[2]))
						
			elif line[:10] == "/clearroom":
				if line[10:] == '':
					
					self.logs["rooms"][self.Spl["room"]] = []
					if self.display["mode"] == "chat":
						self.ModeChatRooms()
				elif line[10:11] == ' ' and line[11:] != '':
					if line[11:] in self.logs["rooms"].keys():
						self.logs["rooms"][line[11:]] = []
						if self.display["mode"] == "chat":
							self.ModeChatRooms()
			elif line == "/aliases":
				self.Hlog("status", "Aliases:")
				for alias in mucous_config["aliases"].keys():
					self.Hlog("status", "/"+alias+": "+str(mucous_config["aliases"][alias]))
					self.Hlog("status", "")
					
			elif line[:7] == "/alias " and line[7:] != '':
				if line[7:].find(" ") != -1:
					splited = line[7:].split(" ")
					if len(splited) > 1:
						alias = splited[0]
						splited = splited[1:]
						if splited[0] != None:
							message = ''
							for i in splited:
								if i != splited[0]:
									message += ' ' +i
								else:
									message += i
							mucous_config["aliases"][alias] = str(message)
							if alias in mucous_config["aliases"].keys():
								self.Hlog("status", "Modified alias: "+alias)
							else:
								self.Hlog("status", "Created alias: "+alias)
							if "/"+alias not in self.commandlist:
								self.commandlist.append("/"+alias)
				else: 
					return 0
				
			elif line[:9] == "/unalias " and line[9:] != '':
				alias = line[9:]
				if alias in mucous_config["aliases"].keys():
					self.Hlog("status", "Deleted alias: "+alias)
					del mucous_config["aliases"][str(alias)]
					if "/"+alias in self.commandlist:
						self.commandlist.remove("/"+alias)
						
			elif line[:1] == "/":
				is_alias = 0
				if  line[1:] in mucous_config["aliases"].keys():
					alias = line[1:]
					is_alias = 1
					if self.display["mode"] == "chat" and self.Spl["room"] != None:
						self.SayInChat("chat", self.Spl["room"], mucous_config["aliases"][alias])
						
					elif self.display["mode"] == "private" and self.usernames["private"] != None:
						self.PrivateChatSend( self.usernames["private"], mucous_config["aliases"][alias])
						
				if not is_alias:
					return 0
				
			else:
				return 1
			
				
			
		except Exception,e:
			self.Hlog("debug", 'commands: ' + str(e))
		pass
					
	## Special Function that parses the input line, if it's not a command
	# @param self is mucous
	# @param line is a text string
	def InputText(self, line):
		## Special Input Box for Downloading Manually
		# escape //
		if line[:2] == '//':
			line = line[1:]
		# Manual Download input box
		if self.Spl["title"][:10] == '% % User: ' and line != '':
			if self.usernames["download"] != None and self.usernames["download"] != '':
				path = line
				self.SendMessage(messages.DownloadFile(self.usernames["download"], path))
				self.Hlog("status", "Trying to Download: " + path+" from "+ self.usernames["download"])
		# Ticker set input box
		elif self.Spl["title"][:12] == '% Set ticker' and line != '':
			self.SendMessage(messages.RoomTickerSet(self.Spl["ticker_room"], line))
			
		elif self.Spl["title"]== '% Give Privileges to ' + str(self.usernames["privileges"]) and line != '':
			try:
				days = int(line)
				self.SendMessage(messages.GivePrivileges(self.usernames["privileges"], days))
				self.usernames["privileges"] = None
				if self.display["mode"] == "chat":
					self.set_edit_title(self.Spl["room"])
			except:
				self.Hlog("debug", "Enter the Number of days of privileges you wish to give " + self.usernames["privileges"])
	
		else:
			if line != '':
				if self.display["mode"] == "chat":
					#Normal Chat Room Message
					if self.Spl["room"]:
						self.SayInChat("chat", self.Spl["room"], line)
				elif self.display["mode"] == "private":
					#Normal Private Messaging
					if self.usernames["private"] != None:
						# Private Message
						self.PrivateChatSend(self.usernames["private"], line)
					else:
						# Set user to message
						self.usernames["private"] = self.dlang( line)
						self.set_edit_title("Send message to: " + self.usernames["private"])
						self.PrivateChatStart(self.usernames["private"])
						
						
				elif self.display["mode"] == "search":
					
					if len(line) > 2 and line != 'mp3':
						# Normal Search
						query = line
						if self.Spl["search_method"] == "globally":
							self.SendMessage(messages.Search(0, query ))
							
						# Buddies Search
						elif self.Spl["search_method"] == "buddies":
							self.SendMessage(messages.Search(1, query ))
						# Rooms Search	
						elif self.Spl["search_method"] == "rooms":	
							self.SendMessage(messages.Search(2, query ))
						elif self.Spl["search_method"] == "user":
							if self.usernames["search"] != None:
								self.SendMessage(messages.UserSearch(self.usernames["search"], query ))
						elif self.Spl["search_method"] == "wishlist":	
							self.SendMessage(messages.WishListSearch(query ))
				elif self.display["mode"] == "browse":
					# Browse User's shares
					if line[:3] == "cd ":
						self.BrowseChangeDir(line[3:])
						return 1

					elif line[:3] == "get" and line[3:] != '':
						linput = None
						if line[:4] == "get " and line[4:] != '':
							dtype = "file"
							linput = line[4:]
						elif line[:7] == "getdir "  and line[7:] != '':
							dtype = "dir"
							linput = line[7:]
						if linput != None:
							if linput.isdigit():
								self.download_path_file(dtype, linput)
							else:
								self.Hlog("status", "Enter an Integer")
							return 1
					
					
					self.BrowseUser(line)
					
					
				elif self.display["mode"] == "info":
					# Get User's UserInfo and PeerStats
					user = self.dlang(line)
					self.LogInfo("Getting information about user: " + user)
					self.requests["info"].append(user)
					self.requests["statistics"].append(user)
					self.SendMessage(messages.UserInfo(user))
					self.SendMessage(messages.PeerStats(user))
					
				elif self.display["mode"] == "lists":
					if self.display["list"] == "buddied":
						self.ModifyConfig("buddy", line, '')
					elif self.display["list"] == "banned":
						self.ModifyConfig("ban", line, '')
					elif self.display["list"] == "ignored":
						self.ModifyConfig("ignore", line, '')
					elif self.display["list"] == "trusted":
						self.ModifyConfig("trusted", line, '')
					elif self.display["list"] == "interests":
						self.InputInterests(line)
				elif self.display["mode"] == "roomlist":
					self.doJoin(line)
				elif self.display["mode"] == "setup":
					self.InputSetup(line)
				
		try:
			self.edit.reset()
		except:
			pass
	
	def doJoin(self, room):
		try:
			self.SendMessage(messages.JoinRoom( self.dlang( room ) ))
		except Exception,e:
			self.Hlog("debug", "doJoin: " + str(e))
				
	def InterestLikedAdd(self, interest):
		try:
			if not interest.isspace() and interest != "":
				self.SendMessage(messages.AddInterest(interest))
		except Exception,e:
			self.Hlog("debug", "InterestLikedAdd: " + str(e))	
			
	def InterestHatedAdd(self, interest):
		try:
			if not interest.isspace() and interest != "":
				self.SendMessage(messages.AddHatedInterest(interest))
		except Exception,e:
			self.Hlog("debug", "InterestHatedAdd: " + str(e))
				
	def InterestLikedRemove(self, interest):
		try:
			if not interest.isspace() and interest != "":
				if interest in self.config["interests.like"]:
					self.SendMessage(messages.RemoveInterest(interest))
		except Exception,e:
			self.Hlog("debug", "InterestLikedRemove: " + str(e))
				
	def InterestHatedRemove(self, interest):
		try:
			if not interest.isspace() and interest != "":
				if interest in self.config["interests.hate"]:
					self.SendMessage(messages.RemoveHatedInterest(interest))
		except Exception,e:
			self.Hlog("debug", "InterestHatedRemove: " + str(e))
			
	def InputInterests(self, line):
		try:
			interest = self.dlang(line)
			if self.display["interests"] == "likes":
				if self.Spl["interests_input"] == "add_likes":
					self.InterestLikedAdd(interest)
				elif self.Spl["interests_input"] == "del_likes":
					self.InterestLikedRemove(interest)
			elif self.display["interests"] == "hates":
				if self.Spl["interests_input"] == "add_hates":
					self.InterestHatedAdd(interest)
				elif self.Spl["interests_input"] == "del_hates":
					self.InterestHatedRemove(interest)
				
				
		except Exception,e:
			self.Hlog("debug", "InputInterests: " + str(e))
			
	def InputSetup(self, line):
		try:
			if self.Spl["setup_input"] == "interface":
				line = self.dlang(line)
				mucous_config["connection"]["interface"] = line
			elif self.Spl["setup_input"]=="interface-password":
				line = self.dlang(line)
				mucous_config["connection"]["passw"] = line
			elif self.Spl["setup_input"]=="custom-url":
				line = self.dlang(line)
				if "$" in line:
					custom = line.split("$")
					if len(custom) > 1 and len(custom) < 3:
						mucous_config["mucous"]["url custom prefix"] = custom[0]
						mucous_config["mucous"]["url custom suffix"] = custom[1]
					elif len(custom) == 1:
						mucous_config["mucous"]["url custom prefix"] = custom[0]
						mucous_config["mucous"]["url custom suffix"] = ''
			elif self.Spl["setup_input"]=="museek-interface-password":
				
				self.SendMessage(messages.ConfigSet("interfaces", "password", line))
			elif self.Spl["setup_input"]=="museek-interface-bind":
				
				self.SendMessage(messages.ConfigSet("interfaces.bind", line))
			elif self.Spl["setup_input"]=="server-host":
				
				self.SendMessage(messages.ConfigSet("server", "host", line))
			elif self.Spl["setup_input"]=="server-port":
				
				self.SendMessage(messages.ConfigSet("server", "port", line))
			elif self.Spl["setup_input"]=="soulseek-username":
				
				line = self.dlang(line)
				self.SendMessage(messages.ConfigSet("server", "username", line))
			elif self.Spl["setup_input"]=="soulseek-password":
				
				line = self.dlang(line)
				self.SendMessage(messages.ConfigSet("server", "password", line))
			elif self.Spl["setup_input"]=="download-dir":
				
				self.SendMessage(messages.ConfigSet("transfers", "download-dir", line))
			elif self.Spl["setup_input"]=="incomplete-dir":
				
				self.SendMessage(messages.ConfigSet("transfers", "incomplete-dir", line))
			elif self.Spl["setup_input"]=="userinfo":
				
				try:
					if '\\n' in line:
						line = line.replace('\\n', '\n')
					self.SendMessage(messages.ConfigSet("userinfo", "text", line))
				except Exception, e:
					self.Hlog("debug", "set userinfo: "+str( e))
			elif self.Spl["setup_input"]=="userimage":
				
				try:
					self.SendMessage(messages.ConfigSet("userinfo", "image", line))
				except:
					pass
			elif self.Spl["setup_input"]=="adddir":
				line = self.dlang(line)
				self.muscan_fuzzy = line
				self.muscan_command = ["muscan", "-s", self.muscan_fuzzy]
				self.muscan_timer.cancel()
				self.muscan_timer = threading.Timer(1.0, self.ThreadMuscan)
				self.muscan_timer.start()
				self.Hlog("status", "Adding "+line+" to normal shares. Scanning will begin.")
			elif self.Spl["setup_input"]=="rmdir":
				line = self.dlang(line)
				self.muscan_fuzzy = line
				self.muscan_command = ["muscan", "-u", self.muscan_fuzzy]
				self.muscan_timer.cancel()
				self.muscan_timer = threading.Timer(1.0, self.ThreadMuscan)
				self.muscan_timer.start()
				self.Hlog("status", "Removing "+line+" from normal shares. Please rescan or update.")
			elif self.Spl["setup_input"]=="addbuddydir":
				line = self.dlang(line)
				self.muscan_fuzzy = line
				self.muscan_command = ["muscan", "-b", "-s", self.muscan_fuzzy]
				self.muscan_timer.cancel()
				self.muscan_timer = threading.Timer(1.0, self.ThreadMuscan)
				self.muscan_timer.start()
				self.Hlog("status", "Adding "+line+" to buddy shares. Scanning will begin.")
			elif self.Spl["setup_input"]=="rmbuddydir":
				line = self.dlang(line)
				self.muscan_fuzzy = line
				self.muscan_command = ["muscan", "-b", "-u", self.muscan_fuzzy]
				self.muscan_timer.cancel()
				self.muscan_timer = threading.Timer(1.0, self.ThreadMuscan)
				self.muscan_timer.start()
				self.Hlog("status", "Removing "+line+" from buddy shares. Please rescan or update.")
			self.Spl["setup_input"] = "default"
			self.ModeSetup()
		except Exception,e:
			self.Hlog("debug", "InputSetup: " + str(e))
				
	def InputFunctions(self, key, line):
		try:
			if key == "KEY_RESIZE":
				self.line = line 
				self.stdscr.keypad(1)
				self.build()
				
			elif key == "KEY_MOUSE":
				line = self.MouseXY(line)
					
			elif key in ("KEY_UP",  "KEY_DOWN", "KEY_PPAGE", "KEY_NPAGE"):
				if self.Spl["show_menu"] == True:
					if key =="KEY_UP":
						key = "menu_up"
					elif key =="KEY_DOWN":
						key = "menu_down"
				else:
					self.key = key
					sline = self.ScrollText(line)
					#self.Hlog("debug", "scrolltext"+str(sline))
					if sline != None:
						line = sline
	
			elif key == "KEY_F(1)":
				if self.display["mode"] != "chat": self.ModeChatRooms()
				return
			elif key == "KEY_F(2)":
				if self.display["mode"] != "private": self.ModePrivate()
				return
			elif key == "KEY_F(3)":
				if self.display["mode"] != "transfer": self.ModeTransfers()
				return
			elif key == "KEY_F(4)":
				if self.display["mode"] != "search": self.ModeSearch()
				return
			elif key == "KEY_F(5)":
				if self.display["mode"] != "info": self.ModeInfo()
				return
			elif key == "KEY_F(6)":
				if self.display["mode"] != "browse": self.ModeBrowse()
				return
			elif key == "KEY_F(7)":
				if self.display["mode"] != "lists": self.ModeLists()
				return
			elif key == "KEY_F(8)":
				if self.display["mode"] != "roomlist": self.ModeRoomsList()
				return
			elif key == "KEY_F(9)":
				if self.display["mode"] != "setup": self.ModeSetupDefault()
				return
			elif key == "KEY_F(10)":
				if self.display["mode"] not in ("help", "debug", "status") : self.ModeHelp()
				return
			elif key == chr(10) or key == "KEY_ENTER":
				if line not in self.logs["history"] and line !='':
					self.logs["history"].append(line)
			elif key in ("popup"):
				if self.Spl["show_menu"] == True:
					self.MenuClear()
				else:
					self.Spl["show_menu"] = True
					if self.display["mode"] == "chat":
						if self.display["chatshape"] not in ( "noroombox", "chat-only"):
							self.MenuCreate("roombox", 0)
						else:
							return
					elif self.display["mode"] == "lists":
						self.MenuCreate("lists", 0)
					elif self.display["mode"] == "transfer":
						self.MenuCreate("transfers", 0)
					elif self.display["mode"] == "search":
						if self.Spl["current_search"] != "default__":
							self.MenuCreate("search", 0)
					elif self.display["mode"] == "browse":
						
						if self.usernames["browse"] != "default__":
							if self.display["browse"] == "files":
								self.MenuCreate("browse-files", 0)
							elif self.display["browse"] == "directories":
								self.MenuCreate("browse-dirs", 0)
			elif key in ("delete"):
				if self.display["mode"] == "lists" and self.display["list"] == "interests":
					inp = self.Spl["interests_input"]
					if inp == "add_likes":
						inp = "del_likes"
					elif inp == "del_likes":
						inp = "add_likes"
					elif inp == "del_hates":
						inp = "add_hates"
					elif inp == "add_hates":
						inp = "del_hates"
					self.Spl["interests_input"]  = inp
					self.ModeInterests()
				
			elif key == "collapse":
				if self.display["mode"] == "browse" and self.display["browse"] == "directories":
					if self.data["directories"] == []:
						return
					Dir = self.data["directories"][ self.scrolling["browsedir"] ]

					if Dir not in self.data["collapsed_dirs"][ self.usernames["browse"] ]:
						self.data["collapsed_dirs"][ self.usernames["browse"] ].append(Dir)
					else:
						self.data["collapsed_dirs"][ self.usernames["browse"] ].remove(Dir)
					self.FormatBrowse()
					
			elif key in ("switch", "KEY_HOME", "KEY_END"):
				if self.display["mode"] == "transfer":
					# Tab to switch between upload and download scrolling
					if self.display["transfers"] == "uploads":
						self.display["transfers"]="downloads"
					elif self.display["transfers"]=="downloads":
						self.display["transfers"]="uploads"
					self.ModeTransfers()
				elif self.display["mode"] in ( "help", "debug"):
					if self.display["mode"] == "help":
						self.display["mode"] = "debug"
					elif self.display["mode"] == "debug":
						self.display["mode"] = "help"
					self.ModeHelp()
				elif self.display["mode"] == "chat":
					if key in ("switch"):
# 						[ "small","big","widelist","rightlist","nostatuslog","chat-only","noroombox"]
						_list = None
						if self.display["chatshape"] == "chat-only":
							self.display["chat"] = "chatroom"
							return
						elif self.display["chatshape"] == "nostatuslog":
							_list = ["chatroom", "roombox"]
						elif self.display["chatshape"] ==  "noroombox":
							_list = ["chatroom", "roomstatus"]
						else:
							_list = ["chatroom", "roomstatus", "roombox"]
						if _list != None:
							self.display["chat"] = self.RotateList("right", _list, self.display["chat"], "no")
							self.ModeChatRooms()
						
					elif key == "KEY_END":
						if self.display["chat"] == "chatroom":
							self.scrolling["chatroom"] = -1
							self.FormatChatRoomText()
						elif self.display["chat"] == "roombox":
							self.scrolling["roombox"] = len(self.data["rooms"][self.Spl["room"]])
							self.ModeChatRooms()
					elif key == "KEY_HOME":
						if self.display["chat"] == "chatroom":
							self.scrolling["chatroom"] = 0 
							self.FormatChatRoomText()
						elif self.display["chat"] == "roombox":
							self.scrolling["roombox"] = 0
							self.ModeChatRooms()
						
				elif self.display["mode"] == "search":
					# HotKeyBar to switch types of searches
					_list = [ "globally", "buddies", "rooms", "user", "wishlist" ]
					self.Spl["search_method"] = self.RotateList("right", _list, self.Spl["search_method"], "no")
					self.ModeSearch()
				elif self.display["mode"] == "browse":	
					_list = [ "files", "directories" ]
					self.display["browse"] = self.RotateList("right", _list, self.display["browse"], "no")
					self.ModeBrowse()
				elif self.display["mode"] == "lists" and self.display["list"] == "interests":
					_list = [ "recommendations", "similar_users", "likes", "hates" ]
					self.display["interests"] = self.RotateList("right", _list, self.display["interests"], "no")
					self.ModeInterests()
					
			elif key in( "KEY_LEFT", chr(91), chr(60), "KEY_RIGHT", chr(93), chr(62), "KEY_IC"):
				if key == "KEY_LEFT" or key == chr(91) or key == chr(60):
					direction = "left"
				elif key == "KEY_RIGHT" or key == chr(93) or key == chr(62) or key == "KEY_IC":
					direction = "right"
				if self.display["mode"] == "chat":
					place = self.RotateList(direction, self.data["rooms"].keys(), self.Spl["room"], "yes" )
					if self.Spl["room"]  != place:
						self.ChatRoomChange(place)

							
				elif self.display["mode"] == "info":
					if self.usernames["info"] == None:
						self.usernames["info"] = self.activeitems["info"][0]
						self.ModeInfo()
						return
					place = self.RotateList(direction, self.activeitems["info"], self.usernames["info"], "yes" )
					if self.usernames["info"] != place:
						self.usernames["info"] = place
						self.ModeInfo()

				elif self.display["mode"] == "private":
					if self.usernames["private"] != None:
						place = self.RotateList(direction, self.logs["private"].keys(), self.usernames["private"], "yes" )
						if self.usernames["private"] != place:
							self.usernames["private"] = place

							self.PrivateChatStart(self.usernames["private"])
							self.ModePrivate()
							
				elif self.display["mode"] == "setup":
					
					self.display["setup"]  = self.RotateList(direction, self.modes["setup"], self.display["setup"], "no" )

					self.ModeSetup()
					
				elif self.display["mode"] == "transfer":
					# HotKeyBar to switch listing transfer types
					
					self.display["transfer_sort"]  = self.RotateList(direction, self.modes["transfers"], self.display["transfer_sort"], "no" )
					
	
					self.ModeTransfers()
		
				elif self.display["mode"] == "search":
					if key in( "KEY_LEFT", chr(91), chr(60), "KEY_RIGHT", chr(93), chr(62)):
						if len(self.data["search_tickets"].keys()) >= 1:
	
								
							place = self.RotateList(direction, self.data["search_tickets"].keys(), self.Spl["current_search"], "yes" )
							if self.Spl["current_search"] != place:
								self.Spl["current_search"] = place
								self.ModeSearch()

							
					elif key == "KEY_IC":
						place = self.RotateList(direction, [ "num", "user", "free", "speed", "que", "path", "size",  "file", "bitrate",  "time"], self.Spl["search_order"], "no" )
						if self.Spl["search_order"]  != place:
							self.Spl["search_order"] = place
							self.DrawSearchSortBar()
							if self.Spl["current_search"]!= "default__":
								self.Format_Search_Results(self.Spl["current_search"])
							curses.doupdate()
					
				elif self.display["mode"] == "browse":
					if len(self.activeitems["browse"]) >= 1:
						if self.usernames["browse"] == "default__":
							self.usernames["browse"] = self.activeitems["browse"][0]

							
						place = self.RotateList(direction, self.activeitems["browse"], self.usernames["browse"], "yes" )
						if place != self.usernames["browse"]:
							self.usernames["browse"] = place 

							sdirs =  self.data["browse_results"][self.usernames["browse"]].keys()
							sdirs.sort(key=str.lower)
							self.Spl["dir_browse"]=sdirs[0]
							self.scrolling["browsefile"] = self.scrolling["browsedir"] = 0
							self.ModeBrowse()
					return line	
				elif self.display["mode"]=="lists":
					
					place = self.RotateList(direction, [ "buddied", "banned", "ignored", "trusted", "interests"], self.display["list"], "no" )
					if self.display["list"]  != place:
						self.display["list"] = place
						self.ModeLists()

					
				elif self.display["mode"]=="roomlist":
					place = self.RotateList(direction, [ "alpha", "alpha-reversed", "size", "size-reversed"], mucous_config["mucous"]["rooms_sort"], "no" )
					if mucous_config["mucous"]["rooms_sort"]  != place:
						mucous_config["mucous"]["rooms_sort"] = place
						self.ModeRoomsList()
			
			if self.display["mode"] in ("chat", "lists", "transfer", "search", "browse") and self.Spl["show_menu"] == True:
				# POPUP menu up and down keys
				try:
					if self.Spl["current_menu"] == None:
							return
					if key == "menu_up":
						if self.Spl["menunumber"] >0:
							self.Spl["menunumber"] -= 1
							self.MenuDraw(self.Spl["current_menu"])
							
					elif key == "menu_down":
						if self.Spl["menunumber"] < len(self.menus[self.Spl["current_menu"]]['items'])-1:
							self.Spl["menunumber"] += 1
							self.MenuDraw(self.Spl["current_menu"])
				except Exception, e:
					pass
			
			return line
		except Exception, e:
			self.Hlog("debug", "InputFunctions: " + str(e))
	# ---^  KEYS ^
	
	def DrawChatRoomStatusText(self):
		try:
			if self.Spl["show_menu"] == True: raise  Exception,  "popup"
			s = self.windows["dimensions"]["chat"]
			tw = self.windows["text"]["roomstatus"]
			w = self.windows["dimensions"]["roomstatus"]
			if self.display["mode"] != "chat":
				return
			if self.display["chatshape"] not in ("nothing", "big", "small", "widelist", "rightlist", "noroombox"):
				return
			tw.erase()
			tw.idlok(1)
	
			if self.Spl["room"] == None or self.logs["roomstatus"][self.Spl["room"]] == []:
				tw.noutrefresh()
				return
				
		
			if self.scrolling["roomstatus"] == -1:
				self.scrolling["roomstatus"] = len(self.logs["roomstatus"][self.Spl["room"]])

			clipped_list, self.scrolling["roomstatus"], self.windows["dimensions"]["roomstatus"]["start"] = self.scrollbox(self.logs["roomstatus"][self.Spl["room"]], self.scrolling["roomstatus"], self.windows["dimensions"]["roomstatus"]["height"])
			count = 0
			try:
				for line in clipped_list:
					#self.Hlog("debug", line +str(self.scrolling["roomstatus"]))
					if len(line) > w["width"]:
						line = line [:w["width"] -len(line) ]
					else:
						line += " " * (w["width"] -len(line))
					if count + self.windows["dimensions"]["roomstatus"]["start"] == self.scrolling["roomstatus"]:
						tw.addstr(self.dlang( line) , curses.A_BOLD)
					else:
						tw.addstr(self.dlang( line ))
					count += 1

			except Exception, e:
				pass

			
			tw.noutrefresh()
		except Exception, e:
			self.Hlog("debug", e)
			pass
									
	def NowPlaying(self):
		try:
			m = mucous_config["mucous"]
			if "now-playing" not in m.keys():
				return
			if m["now-playing"] == "default":
				p = "/tmp/xmms-info"
				if os.path.exists(p):
					fsock = open(p)
					for i in range(3):  s = fsock.readline()[8:-1]
					for i in range(10):  e = fsock.readline()[7:-1]
					if "now-playing-prefix" in m.keys():
						if m["now-playing-prefix"] != 'None' and m["now-playing-prefix"] != None:
							message = ("%s %s") %(m["now-playing-prefix"], e)
						else:
							message ="Now %s: %s " % (s, e)
					else:
						message ="Now %s: %s " % (s, e)
					fsock.close()
					if self.display["mode"] == "chat":
						self.SayInChat("chat", self.Spl["room"], message)
						#self.SendMessage(messages.SayRoom(self.Spl["room"], message))
					elif self.display["mode"] == "private":
						self.PrivateChatSend(self.usernames["private"], message)
				else: self.Hlog("status", "WARNING: XMMS or BMP isn't running or the InfoPipe plugin isn't enabled")
			else:
				p = m["now-playing"]
				nowplaying = commands.getoutput(p).split('\n')
				nowplaying = nowplaying[0]
				if m["now-playing-prefix"] != None and m["now-playing-prefix"] != 'None':
					message = "%s %s" % (m["now-playing-prefix"], nowplaying)
					if self.display["mode"] == "chat" and self.Spl["room"] != None:
						self.SayInChat("chat", self.Spl["room"], message)

					elif self.display["mode"] == "private" and self.usernames["private"] != None:
						self.PrivateChatSend(self.usernames["private"], message )
				else:
					message = nowplaying
					if self.display["mode"] == "chat" and self.Spl["room"] != None:
						self.SayInChat("chat", self.Spl["room"], message)

					elif self.display["mode"] == "private" and self.usernames["private"] != None:
						self.PrivateChatSend(self.usernames["private"], message )
		except Exception, e:
			self.Hlog("debug", "NowPlaying " +str(e))
			
	# ---v  MODES v
	def DrawRoomBox(self, user, start):
		# RoomBox List Display
		try:
			w = self.windows["dimensions"]["roombox"]
			mw = self.windows["border"]["roombox"]
			tw = self.windows["text"]["roombox"]
			if self.Spl["room"] == None or self.logs["roombox"][self.Spl["room"]] == []:
				tw.addstr("No one")
				return
			try:
				if user in self.user["status"]:
					if self.user["status"][user] == 1:
						tw.addstr('* ', self.colors["yellow"]|curses.A_BOLD)
					elif  self.user["status"][user] == 2:
						tw.addstr('* ', self.colors["green"]|curses.A_BOLD)
					elif self.user["status"][user] == 0:
						tw.addstr('* ', self.colors["red"]|curses.A_BOLD)
				else:
					tw.addstr('* ', curses.A_BOLD)
					
				if user in self.config["banned"].keys():
					if self.scrolling["roombox"] == self.logs["roombox"][self.Spl["room"]].index(user):
						attrib = curses.A_BOLD | curses.A_REVERSE | self.colors["red"]
					else: attrib = self.colors["red"]
					
				elif user in self.config["ignored"].keys():
					if self.scrolling["roombox"] == self.logs["roombox"][self.Spl["room"]].index(user):
						attrib = curses.A_BOLD | curses.A_REVERSE | self.colors["yellow"]
					else: attrib = self.colors["yellow"]
					
				elif user in self.config["buddies"].keys():
					if self.scrolling["roombox"] == self.logs["roombox"][self.Spl["room"]].index(user):
						attrib = curses.A_BOLD | curses.A_REVERSE | self.colors["green"]
					else:
						attrib = self.colors["green"]
					
				else:
					if self.scrolling["roombox"] == self.logs["roombox"][self.Spl["room"]].index(user):
						attrib = curses.A_BOLD | curses.A_REVERSE 
					else:
						attrib = curses.A_NORMAL
				if len(user[:w["twidth"]-2]) < w["twidth"]-2:
					space = " " * ( w["twidth"]-2 - len(user[:w["twidth"]-2]))
				else: space =''
				tw.addstr(self.dlang(user[:w["twidth"]-2])+space, attrib)	
				
			except:
				pass
		except Exception, e:
			self.Hlog("debug", "DrawRoomBox " +str(e))	
			
			
	def DrawChatRoomBox(self):
		# RoomBox Shape Display
		try:
			
			if self.display["mode"] != 'chat' or self.display["chatshape"] == "noroombox":
				return
			# Cleanup stale windows
			if "roombox" in self.windows["text"]:
				del self.windows["text"]["roombox"]
			if "roombox" in self.windows["border"]:
				del self.windows["border"]["roombox"]
			
			if self.display["chatshape"] in ("big", "nostatuslog", "widelist", "rightlist"):
				w = self.windows["dimensions"]["chat"]
				if self.display["chatshape"] == "rightlist":
					s = self.windows["dimensions"]["roombox"] = {"height": self.h-7, "top": 2, "left": (w["width"]), "width": self.w-w["width"], "start": -1 }
				else:
					s = self.windows["dimensions"]["roombox"] = {"height": self.h-7, "top": 2, "left": 0, "width": self.w-w["width"], "start": -1 }
				# Create wi
				mw = self.windows["border"]["roombox"]  = curses.newwin(s["height"]+2, s["width"], s["top"]-1, s["left"])
				if self.display["chat"] == "roombox":
					mw.attron(self.colors["green"])

				mw.attroff(self.colors["green"])
				if self.display["chatshape"] == "rightlist":
					self.windows["dimensions"]["roombox"]["twidth"] = s["width"]-1
					self.windows["dimensions"]["roombox"]["tleft"] = s["left"]+1
				else:
					self.windows["dimensions"]["roombox"]["twidth"] = s["width"]-1
					self.windows["dimensions"]["roombox"]["tleft"] = s["left"]
				tw = self.windows["text"]["roombox"] = mw.subwin(s["height"], s["twidth"], s["top"], s["tleft"])
				
			elif self.display["chatshape"] == "small":
				s = self.windows["dimensions"]["roombox"] = {"height": 4, "top": 2, "left": 0,  "width": 15}
				
				mw = self.windows["border"]["roombox"] = curses.newwin(s["height"]+2, s["width"], s["top"]-1, s["left"])
				if self.display["chat"] == "roombox":
					mw.attron(self.colors["green"])

				mw.attroff(self.colors["green"])
				self.windows["dimensions"]["roombox"]["twidth"] = s["width"] -1
				tw = self.windows["text"]["roombox"] = mw.subwin(s["height"], s["twidth"], s["top"], s["left"])
				
			if self.display["chatshape"] in ("big", "small", "nostatuslog", "widelist", "rightlist"):
				tw.scrollok(0)
				tw.idlok(1)
			

				if self.Spl["room"] != None:
					try:
						if self.display["chat"] == "roombox":
							mw.addstr(0, 0, "Users: "+str(len(self.data["rooms"][self.Spl["room"]])), self.colors["green"]|curses.A_BOLD)
						else:

							mw.addstr(0, 0, "Users: "+str(len(self.data["rooms"][self.Spl["room"]])),  curses.A_BOLD)
						
					except:
						pass
					if "autojoin" in self.config:
						try:
							if self.display["chat"] == "roombox":
								cs  = self.colors["green"] |curses.A_BOLD
							else:
								cs  = curses.A_BOLD
							if self.Spl["room"] in self.config["autojoin"].keys():
								
								mw.addstr(self.windows["dimensions"]["roombox"]["height"]+1, 0, "[x] AutoJoined",  cs)
							else:
								mw.addstr(self.windows["dimensions"]["roombox"]["height"]+1, 0, "[ ] AutoJoined",  cs)
						except Exception, e:
							self.Hlog("debug", "AutoJoined: " + str(e))
							
				mw.noutrefresh()
			
				if self.Spl["room"] != None:
					self.logs["roombox"][self.Spl["room"]] = []
					if len( self.data["rooms"][self.Spl["room"]] ) > 0:
						self.logs["roombox"][self.Spl["room"]] = self.data["rooms"][self.Spl["room"]]
						self.logs["roombox"][self.Spl["room"]].sort(key=str.lower)
				
					try:
						if self.logs["roombox"][self.Spl["room"]] != []:
							clipped_list, self.scrolling["roombox"], self.windows["dimensions"]["roombox"]["start"] = self.scrollbox(self.logs["roombox"][self.Spl["room"]], self.scrolling["roombox"], self.windows["dimensions"]["roombox"]["height"])
								
							self.FormatChatRoomBox()
							#for lines in clipped_list:
							#	self.DrawRoomBox(lines, self.windows["dimensions"]["roombox"]["start"])
						else:
							tw.addstr("* Empty")
							tw.noutrefresh()
					except Exception, e:
						self.Hlog("debug", "RSB: " + str(e))
			#curses.doupdate()
		except Exception, e:
			self.Hlog("debug", "DrawChatRoomBox " +str(e))
			
	def ModeChatRooms(self):
		try:
			self.display["mode"] = "chat"
			self.Spl["show_menu"] = False
			
			# Arrangements: 
			cs = None
			if "roomstatus" in self.windows["text"]:
				del self.windows["text"]["roomstatus"]
			if "roomstatus" in self.windows["border"]:
				del self.windows["border"]["roomstatus"]
			
			if "chat" in self.windows["text"]:
				del self.windows["text"]["chat"]
			if "chat" in self.windows["border"]:
				del self.windows["border"]["chat"]
				
			if self.display["chatshape"] == "big":
				w = self.windows["dimensions"]["chat"] = {"height": self.h-13, "width": self.w-15, "top": 8, "left": 16}
				cs = self.windows["dimensions"]["roomstatus"] = {"height": 4, "width": w["width"]-2, "top": 2, "left": w["left"]}
			elif self.display["chatshape"] == "widelist":
				w = self.windows["dimensions"]["chat"] = {"height": self.h-13, "width": self.w-25, "top": 8, "left": 26}
				cs = self.windows["dimensions"]["roomstatus"] ={"height": 4, "width": w["width"]-2, "top": 2, "left": w["left"]}
			elif self.display["chatshape"] in ("noroombox", "small"):
				w = self.windows["dimensions"]["chat"] = {"height": self.h-13, "width": self.w, "top": 8, "left": 1}
				if self.display["chatshape"] in ("noroombox"):
					cs = self.windows["dimensions"]["roomstatus"] = {"height": 4, "width": w["width"]-2, "top": 2, "left": 1}
					#cs["height"]-2, cs["width"]-1, cs["top"]+1,cs["left"]+1
				elif self.display["chatshape"] in ("small"):
					cs = self.windows["dimensions"]["roomstatus"] = {"height": 4, "width": w["width"]-15-2, "top": 2, "left": 16}
			elif self.display["chatshape"] == "rightlist":
				w = self.windows["dimensions"]["chat"] = {"height": self.h-13, "width": self.w-15, "top": 8, "left": 1}
				cs = self.windows["dimensions"]["roomstatus"] = {"height": 4, "width": w["width"]-2, "top": 2, "left": 1}
			elif self.display["chatshape"] == "nostatuslog":
				w = self.windows["dimensions"]["chat"] = {"height": self.h-7, "width": self.w-15, "top": 2, "left": 16}
			elif self.display["chatshape"] == "chat-only":
				w = self.windows["dimensions"]["chat"] = {"height": self.h-7, "width": self.w, "top": 2, "left": 1}
			
			if cs != None:
				brw = self.windows["border"]["roomstatus"] = curses.newwin(cs["height"]+2, cs["width"]+2, cs["top"]-1, cs["left"]-1)
				btw= self.windows["text"]["roomstatus"] = brw.subwin(cs["height"], cs["width"], cs["top"],cs["left"])
				btw.scrollok(0)
					
			self.windows["dimensions"]["chat"]["start"] = 0
			try:
				mw = self.windows["border"]["chat"] = curses.newwin(w["height"]+2, w["width"], w["top"]-1, w["left"]-1)
				if self.usernames["username"] == None:
					#mw.border()
					mw.noutrefresh()
					
				tw =self.windows["text"]["chat"] = self.windows["border"]["chat"].subwin(w["height"], w["width"], w["top"], w["left"]-1)
			except Exception, e:
				self.Hlog("debug", "Chat Mode: " + str(e))

			tw.scrollok(0)
			tw.idlok(1)

			if self.logs["alert"] in ( "New Chat", "Nick Mention"):
				self.AlertStatus("")	

			self.set_room(self.Spl["room"])

			
			curses.doupdate()
		except Exception, e:
			self.Hlog("debug", "ModeChatRooms: " + str(e))
			
	def TickersStartTimer(self):
		try:
			if self.display["mode"] == "chat":

				if self.data["rooms"].keys() != []:
					self.Spl["ticker_num"] = 0
					self.ticker_timer.cancel()
					self.ticker_timer = threading.Timer(1.0, self.DrawTicker)
					self.ticker_timer.start()
		except Exception, e:
			self.Hlog("debug", "TickersStartTimer: " + str(e))
			
	def FormatChatRoomBox(self):
		try:
			w = self.windows["dimensions"]["roombox"]
			lol = self.logs["roombox"][self.Spl["room"]]
			mw = self.windows["border"]["roombox"]
			tw = self.windows["text"]["roombox"]
			tw.erase()
			clipped_list, self.scrolling["roombox"], self.windows["dimensions"]["roombox"]["start"] = self.scrollbox(lol, self.scrolling["roombox"], w["height"])
			for lines in clipped_list:
				self.DrawRoomBox(lines, w["start"])
			tw.noutrefresh()
		except Exception, e:
			self.Hlog("debug", "FormatChatRoomBox: " + str(e))
			
	def FormatChatRoomText(self):
		try:
			if self.Spl["room"] != None:
				w = self.windows["dimensions"]["chat"]
				selected_log = self.logs["rooms"][self.Spl["room"]]
				lol = self.ChatRoomLineWrap(selected_log, w)
				
				if self.scrolling["chatroom"] == -1:
					self.scrolling["chatroom"] = len(lol)
	
				clipped_list, self.scrolling["chatroom"], self.windows["dimensions"]["chat"]["start"] = self.scrollbox(lol, self.scrolling["chatroom"], w["height"])
				
				self.windows["text"]["chat"].erase()
				for lines in clipped_list:
					self.DrawChatRoomText(lines)
	
			self.DrawChatRoomWin()
			self.windows["text"]["chat"].noutrefresh()
		except Exception, e:
			self.Hlog("debug", "FormatChatRoomText: " + str(e))
			
	def ChatRoomLineWrap(self, the_list, w):
		# we wrap text here so that scrolling works properly... 
		try:
			pos = 0
			cut_list = []
			for mtype, timestamp, username, message in the_list:
				length = 0
				message = self.dlang(message)
				#mtype, timestamp, username, message = line[0], line[1], line[2], line[3]
				if mtype == "Me":
					#username = self.dlang(username)
					pre = " * %s " % username
					s = "%s" % message
					length += len(timestamp) + len(pre)
# 				elif mtype == "List":
# 					room = self.Spl["room"]
# 					pre = "Users in %s: "% room
# 					length +=  len(pre)
# 					for user, color in message:
# 						length += len(self.dlang(user))
				elif mtype in ("Mentioned", "Normal", "Status"):
					if username != "": # Universal Timestamp
						if mtype == "Status": # Mucous debugging message
							length += len(timestamp) + 2
						else: # Normal user chat
							length += len(timestamp) + 4
						
						#length += len(self.dlang(username))
						length += len(username)
		
				if "\n" in message:
					
					messagez = message.split('\n')
					# Wrap first line
					firstmsg = messagez[0]
					wit =  len(timestamp) + 4 + len(username)
					lm = len(firstmsg)
					mess = lm - ( (wit + lm ) - w["width"])
					cut_list.append( [ mtype, timestamp, username, firstmsg[:mess] ] )
					restmess = firstmsg[mess:]
					div = ( len(restmess)/w["width"] ) + 1
					spaces= (w["width"] * div) -  len(restmess)
					for seq in range(div):
						if mtype == "Me":
							cut_list.append(['cutme', '', '', restmess[:w["width"]] ])
						else:
							cut_list.append(['cut', '', '', restmess[:w["width"]] ])
						restmess = restmess[w["width"]:]

					# Prepend -- to all following lines
					m = []
					for messages in messagez[1:]:
						m.append("--"+messages)
					# Wrap each of the following lines
					for messages in m:
						lm = len(messages)
						restmess = messages
						div = ( len(restmess)/w["width"] ) + 1
						spaces= (w["width"] * div) -  len(restmess)
						for seq in range(div):
							if mtype == "Me":
								cut_list.append(['cutme', '', '', restmess[:w["width"]] ])
							else:
								cut_list.append(['cut', '', '', restmess[:w["width"]] ])
							restmess = restmess[w["width"]:]
					pos += 1
					continue	
							
					# Short message
				if length +len(message) <= w["width"]:
					cut_list.append([mtype, timestamp, username, message])
					
					# long message
				elif length +len(message) > w["width"]:
					lm = len(message)
					mess = lm - ( (length + lm ) - w["width"])
					cut_list.append( [ mtype, timestamp, username, message[:mess] ] )
					restmess = message[mess:]
					div = ( len(restmess)/w["width"] ) + 1
					spaces= (w["width"] * div) -  len(restmess)
					for seq in range(div):
						#self.Hlog("debug", str(div)+"--" + restmess[:w["width"]] )
						if mtype == "Me":
							cut_list.append(['cutme', '', '', restmess[:w["width"]] ])
						else:
							cut_list.append(['cut', '', '', restmess[:w["width"]] ])
						restmess = restmess[w["width"]:]
 						
				pos += 1
			return cut_list
		except Exception, e:
			# Exceptions are Inevitable
			self.Hlog("debug", "ChatRoomLineWrap: " + str(e))
			
	def DrawChatRoomText(self, roomlinenumber):
		try:
			room = self.Spl["room"]
			mtype, timestamp, username, message2 = roomlinenumber
			lang = mucous_config["mucous"]["language"]
			w = self.windows["dimensions"]["chat"]
			room = self.dlang(room)
			length = 0
			tw = self.windows["text"]["chat"]
			message = ""
			for m in message2:
				message += curses.unctrl(m)
			try:
				if mtype == "Me":
					# /me message
					
					tw.addstr(timestamp)
					username = self.dlang(username)
					pre = " * %s " % username
					tw.addstr(pre, self.colors["green"] | curses.A_BOLD)
					s = "%s" % self.dlang(message)
					tw.addstr(s, self.colors["green"] | curses.A_BOLD)
					length += len(timestamp) + len(pre)+ len(s)
				elif mtype == "List":
					# List of users in Room
					
					pre = "Users in %s: "% room
					self.textwi/n.addstr(pre)
					length +=  len(pre)
					for username, color in message:
						username = self.dlang(username)
						length += len(username)
						if color == "Me":
							tw.addstr(username, curses.A_BOLD)
						elif color == "Left":
							tw.addstr(username, self.colors["yellow"])
						elif color == "Banned":
							tw.addstr(username, self.colors["red"])
						elif color == "Buddies":
							tw.addstr(username, self.colors["green"])
						elif color == "NotLast":
							tw.addstr(username)
						elif color == "Normal":
							tw.addstr(username)
							
				elif mtype == "cut":
					s = self.dlang(message) 
					tw.addstr(s)
					length += len(s)
				elif mtype == "cutme":
					s = self.dlang(message) 
					tw.addstr(s, self.colors["green"] | curses.A_BOLD)
					length += len(s)
				else:
					if username != "":
						# Universal Timestamp
						tw.addstr(timestamp)
						if mtype == "Status":
							# Mucous debugging message
							pre = " "
							tw.addstr(pre)
							
						else:
							# Normal user chat
							pre = " ["
							tw.addstr(pre, curses.A_BOLD | self.colors["black"])
					length += len(timestamp) + len(pre)
					
					name = self.dlang(username)
					if username == self.usernames["username"]:
						tw.addstr(username ,  curses.A_BOLD )
					elif username not in self.data["rooms"][room]:
						tw.addstr(name, self.colors["yellow"])
					elif username in self.config["banned"].keys():
						tw.addstr(name, self.colors["red"])
					elif username in self.config["buddies"].keys():
						tw.addstr(name, self.colors["green"])
					else:
						tw.addstr(name)
					length += len(name)
					
					if username != "":
						if mtype == "Status":
							suf = " "
							tw.addstr(" ")
						else:
							suf = "] "
							tw.addstr(suf, curses.A_BOLD | self.colors["black"])
					length += len(suf)
					if mtype == "Mentioned":
						x = message.split(" ")
						for e in x:
							e = self.dlang(e)
							
							if self.usernames["username"] not in e:
								tw.addstr(e)
								length += len(e)
							elif self.usernames["username"] in e:
								tw.addstr(e, self.colors["cyan"] | curses.A_BOLD)
								length += len(e)
							if e is not  x[-1]:
								if length < w["width"]:
									tw.addstr(" ")
									length +=  1
					elif mtype == "Normal":
						
						s = self.dlang(message) 
						tw.addstr(s)
						length += len(s)
					elif mtype == "Status":
						s = self.dlang(message) 
						tw.addstr(s)
						length += len(s)
				
	
			except Exception, e:
				pass
				# Exceptions are Inevitable
			try:
				if length < w["width"]:
					tw.addstr(" " * (w["width"] - length))
			except Exception, e:
				pass
		except Exception, e:
			self.Hlog("debug", "DrawChatRoomText: " + str(e))
		
	def dlang(self, string):
		try:
			string1 = string.decode(mucous_config["mucous"]["language"], "replace")
			string1 = string1.encode(mucous_config["mucous"]["language"], "replace")
			string1 = string1.encode(mucous_config["mucous"]["language"], "replace")
			
		except Exception, e:
			pass
		try:
			z = ""
			
			for s in string1:
				if curses.ascii.isctrl(s):
					z += curses.ascii.unctrl(s)
				else:
					z += s
			return z
		except:
			return string

			
	def PrivateChatOldLogs(self, username):
		try:
			# Read from Private Chat Logs
			if "\\" in username: username = username.replace("/", "\\")
			if os.path.exists(os.path.expanduser(mucous_config["mucous"]["log_dir"])+"/private"+"/"+username):
				path = os.path.expanduser(mucous_config["mucous"]["log_dir"])+"/private"+"/"+username
				f = open(path, "r")
				a = f.read()
				f.close()
				lines = a.split("\n" )
				numlines = -30
				if len(lines) <= abs(numlines):
					numlines = 0
				for line in lines[numlines:]:
					if line == "":
						continue
					timex = line[12:20]
					user = line[22:]
					if line.find("\t") == -1:
						# old format
						user = user[:user.find("]")]
						message = line[21+len(user)+3:]
					else:
						# new format with Tab
						user = user[:user.find("\t")-1]
						message = line[line.find("\t")+1:]
						
					self.logs["private"][username].append([timex, user, message])
				
				self.logs["private"][username].append([time.strftime("%H:%M:%S"), "", "------ Old Chat Above ------"])
		except Exception,e:
			self.Hlog("debug", "PrivateChatOldLogs: " +str( e) )
			
	def ChatRoomsOldLogs(self, room):
		try:
			# Read from Chat Room Logs
			if "\\" in room: room = room.replace("/", "\\")
			if os.path.exists(os.path.expanduser(mucous_config["mucous"]["log_dir"])+"/rooms/"+room):
				path = os.path.expanduser(mucous_config["mucous"]["log_dir"])+"/rooms/"+room
				f = open(path, "r")
				a = f.read()
				f.close()
				lines = a.split("\n" )
				numlines = -30
				if len(lines) <= abs(numlines):
					numlines = 0
				for line in lines[numlines:]:
					if line == "":
						continue
					timex = line[12:20]
					if line[21] == "[":
						user = line[22:]
						if line.find("\t") == -1:
						# old format
							user = user[:user.find("]")]
							message = line[21+len(user)+3:]
						else:
							# new format with Tab
							user = user[:user.find("\t")-1]
							message = line[line.find("\t")+1:]
					else:
						user = line[21:]
						user = user[:user.find(" ")]
						message = line[21+len(user)+1:]
						
					
					if message[:4] == "/me ": 
						full_message = ["Me", timex, user, message[4:]]
					else:
						full_message = ["Normal", timex, user, message]
					self.logs["rooms"][room].append(full_message)
				self.logs["rooms"][room].append(["Status", "--------", "!!!!", "Connected to Museek"])
			
		except Exception,e:
			self.Hlog("debug", "ChatRoomsOldLogs: " +str( e) )


	def dencode_language(self, string):
		try:
			string = string.decode(mucous_config["mucous"]["language"]).decode(mucous_config["mucous"]["language"]).encode(mucous_config["mucous"]["language"])
		except:
			pass
		return string
	
	def encode_language(self, string):
		try:
			string = string.encode(mucous_config["mucous"]["language"])
		except:
			pass
		return string
	
	# Change Room Title
	def ChatRoomChange(self, r):
		self.scrolling["chatroom"] = self.scrolling["roomstatus"] = -1
		self.scrolling["roombox"] = 0
		self.set_room(r)
		
	def set_room(self, r):
		try:
			
			self.Spl["room"] = r
			self.Spl["title"]= r
			
			if self.display["mode"] == "chat":
				# Change title in edit window
				if self.display["chatshape"] not in ("chat-only", "nostatuslog"):
					self.DrawChatRoomStatusWin()
					self.DrawChatRoomStatusText()
				self.set_edit_title(self.Spl["room"])
				# Display Next-room hotspot's text
				try:
					# Encoding
					if self.Spl["room"] != None:
						if self.Spl["room"] in self.config["encoding.rooms"]:
							blah = self.config["encoding.rooms"][self.Spl["room"]]
						else:
							blah = self.config["encoding"]["network"]
						
						self.windows["border"]["input"].addstr(0, self.w-17-len(blah)-4, "<" + (" " *( len(blah) +2) )+  ">")
						self.windows["border"]["input"].addstr(0, self.w-17-len(blah)-2, blah, self.colors["cyan"] | curses.A_BOLD)
						# Previous, Next Buttons
						self.windows["border"]["input"].addstr(0, self.w-17, "<      >")
						self.windows["border"]["input"].addstr(0, self.w-15, "Prev", self.colors["cyan"] | curses.A_BOLD)
						self.windows["border"]["input"].addstr(0, self.w-9, "<      >")
						self.windows["border"]["input"].addstr(0, self.w-7,"Next", self.colors["cyan"] | curses.A_BOLD)
		
						# Clean screen
						self.windows["border"]["input"].noutrefresh()
				except:
					pass
				
				try:
					self.windows["text"]["input"].noutrefresh()
				except:
					pass
				self.DrawChatRoomBox()
				
				# Display chat log
				if self.display["chat"] == "chatroom":
					self.windows["border"]["chat"].attron(self.colors["green"])
				else:
					self.windows["border"]["chat"].attroff(self.colors["green"])
				
				self.FormatChatRoomText()
				
				# Clear Alert log
				if "%s" % self.Spl["room"] == self.logs["alert"]:
					self.AlertStatus("")
				
				self.TickersStartTimer()
			try:
				self.windows["text"]["chat"].noutrefresh()
			except:
				pass
			
			self.AlertCheck()
		except Exception, e:
			self.Hlog("debug", "set_room: " + str(e))
			
	def set_edit_title(self, title):
		try:
			if title != None:
				self.Spl["title"]= title
			else:
				self.Spl["title"] = "Join a room or something."
			ibw = self.windows["border"]["input"]
			itw = self.windows["text"]["input"]
			ibw.erase()
			ibw.border()
			if self.Spl["title"]:
				try:
					current = self.dlang(self.Spl["title"])
					ibw.addstr(0, 2, "< ")
					ibw.addstr(0, 4, current[:self.w-8], self.colors["cyan"] | curses.A_BOLD)
					ibw.addstr(0, 4+len(current[:self.w-8]), " >")
				except Exception, e:
					self.Hlog("debug", "set_edit_title: " + str(e))
			try:
				ibw.noutrefresh()
				itw.erase()
				itw.addstr(self.line)
				itw.noutrefresh()
			except:
				pass
		except Exception, e:
			self.Hlog("debug", "set_edit_title: " + str(e))
			
	def DrawLists(self, line, count, window):
		try:
			if self.display["mode"] == "lists":
				start = self.windows["dimensions"][window]["start"]
				tw = self.windows["text"][self.display["list"]]
				linenumber = line
				attributes = linenumber[0]
				username = linenumber[1]
				note = linenumber[2]
				
				tabbeduser = self.dlang(username[:20])
	
				while len(tabbeduser) < 24:
					tabbeduser += ' '
				try:
					if username in self.user["status"].keys():
						if self.user["status"][username] == 1:
							tw.addstr('* ', self.colors["yellow"]|curses.A_BOLD)
						elif self.user["status"][username] == 2:
							tw.addstr('* ', self.colors["green"]|curses.A_BOLD)
						elif self.user["status"][username] == 0:
							tw.addstr('* ', self.colors["red"]|curses.A_BOLD)
					else: 
						tw.addstr('* ',  curses.A_BOLD )	
					pos = 2
					
					if self.display["list"] == "buddied":
						attrcount = 0
						try:
							if 'trusted' in attributes:
								color = self.colors["cyan"] | curses.A_BOLD 
								tw.addstr('!', color)
							else: tw.addstr(' ')
							color = self.colors["green"] | curses.A_BOLD 
							tw.addstr('!', color)
							if 'banned' in attributes:
								color = self.colors["red"] | curses.A_BOLD 
								tw.addstr('!', color)
							else: tw.addstr(' ')
							
							if 'ignored' in attributes:
								color = self.colors["yellow"] | curses.A_BOLD 
								tw.addstr('! ', color)
							else: tw.addstr('  ')
								
						except Exception, e:
							self.Hlog("debug", "display list text" + str(e))
							pass
						
						
					elif self.display["list"] == "banned":
						
						try:
							if 'trusted' in attributes:
								color = self.colors["cyan"] | curses.A_BOLD 
								tw.addstr('!', color)
							else: tw.addstr(' ')
							
							if 'buddies' in attributes:
								color = self.colors["green"] | curses.A_BOLD 
								tw.addstr('!', color)
							else: tw.addstr(' ')
							color = self.colors["red"] | curses.A_BOLD 
							tw.addstr('!', color)
							if 'ignored' in attributes:
								color = self.colors["yellow"] | curses.A_BOLD 
								tw.addstr('! ', color)
							else: tw.addstr('  ')
							
	
						except:
							self.Hlog("debug", "display list text" + str(e))
							
					elif self.display["list"] == "trusted":
						try:
							color = self.colors["cyan"] | curses.A_BOLD 
							tw.addstr('!', color)
							
							if 'buddies' in attributes:
								color = self.colors["green"] | curses.A_BOLD 
								tw.addstr('!', color)
							else: tw.addstr(' ')
							if 'banned' in attributes:
								color = self.colors["red"] | curses.A_BOLD 
								tw.addstr('!', color)
							else: tw.addstr(' ')
							if 'ignored' in attributes:
								color = self.colors["yellow"] | curses.A_BOLD 
								tw.addstr('! ', color)
							else: tw.addstr('  ')
						except Exception, e:
							self.Hlog("debug", "display list text" + str(e))
							
					elif self.display["list"] == "ignored":
						try:
							if 'trusted' in attributes:
								color = self.colors["cyan"] | curses.A_BOLD 
								tw.addstr('!', color)
							else: tw.addstr(' ')
							if 'buddies' in attributes:
								color = self.colors["green"] | curses.A_BOLD 
								tw.addstr('!', color)
							else: tw.addstr(' ')
							if 'banned' in attributes:
								color = self.colors["red"] | curses.A_BOLD 
								tw.addstr('!', color)
							else: tw.addstr(' ')
							color = self.colors["yellow"] | curses.A_BOLD 
							tw.addstr('! ', color)
						except Exception, e:
							self.Hlog("debug", "display list text" + str(e))
					#else:
						#tw.addstr(tabbeduser)
						#stats = note = ''
					color = curses.A_NORMAL
					pos +=5
					
					if count + start == self.scrolling[self.display["list"]]:
						attrib = curses.A_BOLD | curses.A_REVERSE | color
						attrib2 = curses.A_BOLD | curses.A_REVERSE 
					else:
						attrib = curses.A_BOLD | color
						attrib2 = curses.A_BOLD 
						
					tw.addstr(tabbeduser, attrib)
								
					if username in self.user["statistics"]:
						stats = " %sKB/s" % str(self.user["statistics"][username][0]/1024)
						while len(stats) < 9:
							stats += " "
						files = str(self.user["statistics"][username][2])
						while len(files) < 7:
							files = " " + files
						stats += files
						while len(stats) < 18:
							stats += " "
						tw.addstr( stats, attrib2)
					else:
						stats  = " 0KB/s         0  "
						tw.addstr(stats, attrib2)
						
					width = len(tabbeduser) + len(stats) + len(note) + 5
					subtract = self.w - width
					if subtract < 0:
						tw.addstr(note[:len(note)+subtract], attrib2)
					else:
						tw.addstr(note, attrib2)
						
						
					pos += len(tabbeduser) + len(stats) + len(note)
					if self.windows["dimensions"][window]["width"] - pos > 0:
						spaces = " " * (self.windows["dimensions"][window]["width"] - pos)
						tw.addstr(spaces, attrib2)
				except Exception, e:
					pass
					#self.Hlog("debug", "DLT"+str(e))
		except Exception, e:
			self.Hlog("debug", "DrawLists: " + str(e))

		
	def DrawChatRoomWin(self):
		try:
			s = self.windows["dimensions"]["chat"]
			mw = self.windows["border"]["chat"]
			if self.display["chat"] == "chatroom":
				mw.attron(self.colors["green"])
				mw.hline(0, 0, curses.ACS_HLINE, s["width"]-1)
				mw.hline(s["height"]+1, 0, curses.ACS_HLINE, s["width"]-1)
				mw.addstr(0, 0, "Oo",  self.colors["green"] | curses.A_BOLD)
				mw.addstr(0, 3, "< Chat Rooms >",  self.colors["green"] | curses.A_BOLD)
				mw.addstr(0, s["width"]-1, "^",  self.colors["green"] | curses.A_BOLD)
				try:
					mw.addstr(s["height"]+1, s["width"]-1, "v",  self.colors["green"] | curses.A_BOLD)
				except: pass
				mw.addstr(s["height"]+1, 2, "< "+str(abs(self.scrolling["chatroom"]))+" >", self.colors["green"] | curses.A_BOLD)
				if self.Spl["room"] != None:
					if len(self.logs["rooms"][self.Spl["room"]]) -1 <= abs(self.scrolling["chatroom"]):
						mw.addstr(s["height"]+1, 10, "< AutoScrolling >", self.colors["green"] | curses.A_BOLD)
				
			else:
				mw.hline(0, 0, curses.ACS_HLINE, s["width"]-1)
				mw.hline(s["height"]+1, 0, curses.ACS_HLINE, s["width"]-1)
				mw.addstr(0, 0, "Oo", curses.A_BOLD)
				mw.addstr(0, 3, "< Chat Rooms >",   curses.A_BOLD)
				mw.addstr(0, s["width"]-1, "^",  curses.A_BOLD)
				try:
					mw.addstr(s["height"]+1, s["width"]-1, "v",  curses.A_BOLD)
				except: pass
# 				mw.addstr(s["height"]+1, 2, "< "+str(abs(self.scrolling["chatroom"]))+" >", curses.A_BOLD)
			mw.noutrefresh()
			
		except Exception,e :
			self.Hlog("debug", "display chat window: " + str(e))
			
	def ChatRoomAppend(self, mtype, room, user, message):
		try:
			if room == None:
				room = self.Spl["room"]
			full_message = [mtype, time.strftime("%H:%M:%S"), user, message]
			if len( self.logs["rooms"][room] ) >= 700:
				del self.logs["rooms"][room][0]
			oldlen = len(self.logs["rooms"][room])
			self.logs["rooms"][room].append(full_message)
				
			if self.display["mode"] == "chat":
				if room == self.Spl["room"] and self.display["chat"] == "chatroom":
					if self.scrolling["chatroom"] >= oldlen -1:
						self.scrolling["chatroom"] = -1
						self.FormatChatRoomText()
				elif room == self.Spl["room"] and self.display["chat"] == "roombox":
					temp = self.scrolling["chatroom"]
					self.scrolling["chatroom"] = -1
					self.FormatChatRoomText()
					self.scrolling["chatroom"] = temp
		except Exception,e :
			self.Hlog("debug", "ChatRoomAppend: " + str(e))


	def DrawChatRoomStatusWin(self):
		try:
			w = self.windows["dimensions"]["chat"]
			bw = self.windows["border"]["roomstatus"]
			
			if self.Spl["show_menu"] == True: raise  Exception,  "popup"
			
			if self.display["chatshape"] in ("noroombox", "big", "small", "rightlist", "widelist"):
				if self.display["chat"] == "roomstatus":
					bw.attron(self.colors["green"])
				else:
					bw.attroff(self.colors["green"])
				bw.border()
				bw.addstr(0, 3, "<")
				bw.addstr(0, 4, " Status Log ", self.colors["blue"] | curses.A_BOLD)
				bw.addstr(0, 16, ">")
				bw.noutrefresh()
		except:
			pass
		
	def ChatRoomLayout(self):
		try:
# 			[ "small","big","widelist","rightlist","nostatuslog","chat-only","noroombox"]

			if self.display["chatshape"] == "noroombox":
				self.display["chatshape"] = "small"
				self.display["chat"]  = "roombox"
			elif self.display["chatshape"] == "small":
				self.display["chatshape"] = "big"
				self.display["chat"]  = "roombox"
			elif self.display["chatshape"] == "big":
				self.display["chatshape"] = "widelist"
				self.display["chat"]  = "roombox"
			elif self.display["chatshape"] == "widelist":
				self.display["chatshape"] = "rightlist"
				self.display["chat"]  = "roombox"
			elif self.display["chatshape"] == "rightlist":
				self.display["chatshape"] = "nostatuslog"
				self.display["chat"]  = "chatroom"
			elif self.display["chatshape"] == "nostatuslog":	
				self.display["chatshape"] = "chat-only"
				self.display["chat"]  = "chatroom"
			elif self.display["chatshape"] == "chat-only":
				self.display["chatshape"] = "noroombox"
				self.display["chat"]  = "chatroom"
				
			mucous_config["mucous"]["roombox"] = self.display["chatshape"]
			self.ModeChatRooms()
		except Exception, e:
			self.Hlog("debug", "ChatRoomLayout: " + str(e))

			
	def ModePrivate(self):
		self.display["mode"] = "private"
		self.Spl["show_menu"] = False
		try:
			# Cleanup stale windows
			if "private" in self.windows["text"]:
				del self.windows["text"]["private"]
				
			w = self.windows["dimensions"]["private"] = {"height": self.h-8, "width": self.w, "top": 4, "left": 0}

			tw =  self.windows["text"]["private"] = curses.newwin(w["height"], w["width"], w["top"], w["left"])				

			
			tw.scrollok(0)
			tw.idlok(1)
			ibw = self.windows["border"]["input"]
			self.scrolling["private"] = -1 
			self.DrawPrivateChat()
			if self.usernames["private"] != None:
				self.set_edit_title("Send message to: " + self.usernames["private"])
				try:
					blah = None
					if "encoding.users" in self.config:
						if self.usernames["private"] in self.config["encoding.users"]:
							blah = self.config["encoding.users"][self.usernames["private"]]
						else:
							blah = self.config["encoding"]["network"]
					if blah != None:
						ibw.addstr(0, self.w-17-len(blah)-4, "<" + (" " *( len(blah) +2) )+  ">")
						ibw.addstr(0, self.w-17-len(blah)-2, blah, self.colors["cyan"] | curses.A_BOLD)
					ibw.addstr(0, self.w-10, "< ")
					ibw.addstr(0, self.w-8, "Close ", self.colors["cyan"] | curses.A_BOLD)
					ibw.addstr(0, self.w-2, ">")
				except:
					pass
				ibw.noutrefresh()
				self.windows["text"]["input"].noutrefresh()
				self.AlertCheck()
	
			else:
				self.set_edit_title("Set a user to Private Message")
				self.HotKeyBar()
	
			if self.logs["alert"] == "New PM" or self.logs["alert"][:5] =="PM: ":
				self.AlertStatus("")
			pmusers = self.logs["private"].keys()
			pmusers.sort(key=str.lower)
			self.DrawTabs(pmusers, self.usernames["private"])
			
			
		except Exception, e:
			self.Hlog("debug", "ModePrivate" +str(e))
		curses.doupdate()
		
	def wrap_n_clip(self, the_list, w, scrolltext):
		try:
			wrapped_lines = []
			for lines in the_list:
				#lines = str(lines)
				lines1 = ""
				for a in lines:
					if curses.ascii.isctrl(a):
						a = curses.ascii.unctrl(a)
					lines1 += a
					#lines = lines.replace("^A", "\^A")
					#self.Hlog("debug", lines +" "+ str(len(lines))+curses.ascii.ctrl("a"))
				list_of_strings = self.StringCutWidth(lines1, w)
				for string in list_of_strings:
					wrapped_lines.append(string)
			if self.scrolling[scrolltext] == -1:
				self.scrolling[scrolltext] = len(wrapped_lines)
			clipped_list, self.scrolling[scrolltext], w["start"] = self.scrollbox(wrapped_lines, self.scrolling[scrolltext], w["height"])
			return clipped_list, self.scrolling[scrolltext], w["start"]
		except Exception, e:
			self.Hlog("debug", "wrap_n_clip " +str(e))
	
	def PrivateWrap(self, the_list, w, scrolltext):
		try:
			wrapped_lines = []
			for timestamp, user, message in the_list:
				
				lines1 = ""
				for a in lines:
					if curses.ascii.isctrl(a):
						a = curses.ascii.unctrl(a)
					lines1 += a
					#lines = lines.replace("^A", "\^A")
					#self.Hlog("debug", lines +" "+ str(len(lines))+curses.ascii.ctrl("a"))
				list_of_strings = self.StringCutWidth(lines1, w)
				for string in list_of_strings:
					wrapped_lines.append(string)
			if self.scrolling[scrolltext] == -1:
				self.scrolling[scrolltext] = len(wrapped_lines)
			clipped_list, self.scrolling[scrolltext], w["start"] = self.scrollbox(wrapped_lines, self.scrolling[scrolltext], w["height"])
			return clipped_list, self.scrolling[scrolltext], w["start"]
		except Exception, e:
			self.Hlog("debug", "wrap_n_clip " +str(e))
			
	def DrawPrivateChat(self):
		try:
			scrolltext = "private"
			w = self.windows["dimensions"]["private"]
			tw = self.windows["text"]["private"]
			tw.erase()
			tw.noutrefresh()
			if self.usernames["private"] == None:
				# Instructions
				for lines in self.pminfolog:
					try:
						lines, ls = self.StringAddBlanks(lines, w)
						tw.addstr(self.dlang(lines))
					except Exception, e:
						self.Hlog("debug", "private display: " + str(e))
				return
					
			# Private chat log
			if self.usernames["private"] not in self.logs["private"]:
				return

			listcolors = {}
			wrapped_lines = []
			merged_lines = []
			for timestamp, user, message in self.logs["private"][self.usernames["private"]]:
				message_clean = ""
				for a in message:
					if curses.ascii.isctrl(a):
						a = curses.ascii.unctrl(a)
					message_clean += a
				message = self.dlang(message_clean)
				if message[:4] == "/me ":
					color = self.colors['green']
					merged_lines = "%s * %s %s"% (timestamp, user, message[4:]) 
				elif user == '':
					color = self.colors['cyan']
					merged_lines = "%s %s"% (timestamp, message)
				else:
					color = curses.A_NORMAL
					merged_lines = "%s [%s] %s"% (timestamp, user, message) 
				list_of_strings = self.StringCutWidth(merged_lines, w)
				for line in list_of_strings:
					wrapped_lines.append(line)
					listcolors[line] = color
			del merged_lines
			del list_of_strings
			
			if self.scrolling[scrolltext] == -1:
				self.scrolling[scrolltext] = len(wrapped_lines)	
			
			clipped_list, self.scrolling[scrolltext], w["start"] = self.scrollbox(wrapped_lines, self.scrolling[scrolltext], w["height"])
			
			
			attrs = curses.A_BOLD #| curses.A_UNDERLINE
			attr = curses.A_NORMAL
			count = 0
			for lines in clipped_list:
				color = listcolors[lines]
				try:
					lines, ls = self.StringAddBlanks(lines, w)
					if count + w["start"] == self.scrolling["private"]:
						tw.addstr(self.dlang(lines), attrs | color )
					else:
						tw.addstr(self.dlang(lines), attr | color )
					count += 1
				except Exception, e:
					#self.Hlog("debug", "private display: " + str(e))
					pass
			tw.noutrefresh()
		except Exception, e:
			self.Hlog("debug", "DrawPrivateChat: " + str(e))
			
	def DrawListsWindows(self, window):
		try:
			
			
			if self.display["mode"] ==  "roomlist":
				# Cleanup stale windows
				if "roomlist" in self.windows["text"]:
					del self.windows["text"]["roomlist"]
				if "roomlist" in self.windows["border"]:
					del self.windows["border"]["roomlist"]
					
				s = self.windows["dimensions"][window]
				mw = self.windows["border"]["roomlist"] = curses.newwin(s["height"]+2, s["width"]+2, s["top"]-1, s["left"]-1)
				mw.attron(self.colors["green"])
				mw.border()
				mw.attroff(self.colors["green"])
				
				mw.addstr(0, 3, "< Room List >",  self.colors["green"] | curses.A_BOLD)
				pos = 3
				sorta = "< "
				sort = "Sort by:"
				sortnaz = " Name A-Z"
				sortnza = " Name Z-A"
				sorts90 =" Size 9-0"
				sorts09 =" Size 0-9"
				quick = mucous_config["mucous"]["rooms_sort"]
				sortnaz_color = sortnza_color = sorts90_color = sorts09_color = curses.A_NORMAL
				if quick == "size":
					sorts90_color = self.colors["green"]
				elif quick == "size-reversed":
					sorts09_color = self.colors["green"]
				elif quick == "alpha-reversed":
					sortnza_color = self.colors["green"]
				elif quick == "alpha":
					sortnaz_color = self.colors["green"]
				mw.addstr(self.h-6, pos, sorta,  self.colors["green"] | curses.A_BOLD)
				pos += 2
				mw.addstr(self.h-6, pos, sort,  curses.A_BOLD)
				pos += len(sort)
				mw.addstr(self.h-6, pos, sortnaz,  sortnaz_color | curses.A_BOLD)
				pos += len(sortnaz)
				mw.addstr(self.h-6, pos, " |",  self.colors["green"] | curses.A_BOLD)
				pos += 2
				mw.addstr(self.h-6, pos, sortnza,  sortnza_color | curses.A_BOLD)
				pos += len(sortnza)
				mw.addstr(self.h-6, pos, " |",  self.colors["green"] | curses.A_BOLD)
				pos += 2
				mw.addstr(self.h-6, pos, sorts90, sorts90_color | curses.A_BOLD)
				pos += len(sorts90)
				mw.addstr(self.h-6, pos, " |",  self.colors["green"] | curses.A_BOLD)
				pos += 2
				mw.addstr(self.h-6, pos, sorts09,  sorts09_color | curses.A_BOLD)
				pos += len(sorts09)
				mw.addstr(self.h-6, pos, " >",  self.colors["green"] | curses.A_BOLD)
				mw.addstr(self.h-6, self.w-15, "< Refresh >",  self.colors["green"] | curses.A_BOLD)
				self.set_edit_title("Join a Room")
			
				mw.noutrefresh()
				tw = self.windows["text"]["roomlist"] =  mw.subwin(s["height"], s["width"], s["top"], s["left"])
				tw.attron(self.colors["green"])
				tw.border()
				tw.attroff(self.colors["green"])
				

			elif self.display["mode"] == "lists":
				# Cleanup stale windows
				if self.display["list"] in self.windows["text"]: 
					del self.windows["text"][self.display["list"]]
				if self.display["list"] in self.windows["border"]:
					del self.windows["border"][self.display["list"]]
					
				s = self.windows["dimensions"][self.display["list"]]
				mw = self.windows["border"][self.display["list"]] = curses.newwin(s["height"]+2, s["width"]+2, s["top"]-1, s["left"]-1)
				mw.attron(self.colors["green"])
				mw.border()
				mw.attroff(self.colors["green"])

				if self.display["list"] =="buddied":
					mw.addstr(0, 3, "< Buddied >",  self.colors["green"] | curses.A_BOLD)
					mw.addstr(0, 16, "< Banned >", self.colors["green"])
					mw.addstr(0, 28, "< Ignored >", self.colors["green"])
					mw.addstr(0, 40, "< Trusted >", self.colors["green"])
					mw.addstr(0, 52, "< Interests >", self.colors["green"])
					
					self.set_edit_title("Add Buddy:")
				elif self.display["list"] =="banned":
					mw.addstr(0, 3, "< Buddied >",  self.colors["green"] )
					mw.addstr(0, 16, "< Banned >", self.colors["green"]| curses.A_BOLD)
					mw.addstr(0, 28, "< Ignored >", self.colors["green"])
					mw.addstr(0, 40, "< Trusted >", self.colors["green"])
					mw.addstr(0, 52, "< Interests >", self.colors["green"])
					self.set_edit_title("Ban User:")
				elif self.display["list"] =="ignored":
					mw.addstr(0, 3, "< Buddied >",  self.colors["green"] )
					mw.addstr(0, 16, "< Banned >", self.colors["green"])
					mw.addstr(0, 28, "< Ignored >", self.colors["green"]| curses.A_BOLD)
					mw.addstr(0, 40, "< Trusted >", self.colors["green"])
					mw.addstr(0, 52, "< Interests >", self.colors["green"])
					self.set_edit_title("Ignore User:")
				elif self.display["list"] =="trusted":
					mw.addstr(0, 3, "< Buddied >",  self.colors["green"] )
					mw.addstr(0, 16, "< Banned >", self.colors["green"])
					mw.addstr(0, 28, "< Ignored >", self.colors["green"])
					mw.addstr(0, 40, "< Trusted >", self.colors["green"] | curses.A_BOLD)
					mw.addstr(0, 52, "< Interests >", self.colors["green"])
					self.set_edit_title("Add Trusted:")
			
				mw.noutrefresh()
				tw = self.windows["text"][self.display["list"]] = mw.subwin(s["height"], s["width"], s["top"], s["left"])
				tw.scrollok(0)
				tw.idlok(1)
				
				
			elif self.display["mode"] == "transfer":
				# Cleanup stale windows
				if window in self.windows["border"]:
					del self.windows["border"][window]
				s = self.windows["dimensions"][window]
				win = self.windows["border"][window] = curses.newwin(s["height"]+2, s["width"]+2, s["top"]-1, s["left"]-1)
				
				if mucous_config["mucous"]["transbox"] == "tabbed":
					win.attron(self.colors["green"])
					win.border()
					if window == "uploads":
						uattr = self.colors["green"] | curses.A_BOLD
						uuattr = self.colors["green"] | curses.A_BOLD | curses.A_UNDERLINE
						duattr = self.colors["green"] | curses.A_UNDERLINE
						dattr = self.colors["green"]
							
						
					elif window == "downloads":
						uattr = self.colors["green"] 
						uuattr = self.colors["green"] | curses.A_UNDERLINE
						duattr = self.colors["green"] | curses.A_BOLD  | curses.A_UNDERLINE
						dattr = self.colors["green"] | curses.A_BOLD
						
					pos = 3
					win.addstr(0, pos, "<", dattr)
					pos += 1
					u = " Uploading Transfers "
					win.addstr(0, pos, u,  uuattr)
					pos += len(u)
					win.addstr(0, pos, ">", dattr)
					pos += 2
					win.addstr(0, pos, "<", dattr)
					pos += 1
					d = " Downloading Transfers "
					win.addstr(0, pos, d,  duattr)
					pos += len(d)
					win.addstr(0, pos, ">", dattr)
					
				else:
					if self.display["transfers"] == "uploads" and window == "uploads":
						win.attron(self.colors["green"])
						win.border()
						win.addstr(0, 3, "< Uploading Transfers >", curses.A_BOLD|self.colors["green"])
					elif self.display["transfers"] == "uploads" and window == "downloads":
						win.border()
						win.addstr(0, 3, "< Downloading Transfers >", curses.A_BOLD)
						
					elif self.display["transfers"] == "downloads" and window == "downloads":
						win.attron(self.colors["green"])
						win.border()
						win.addstr(0, 3, "< Downloading Transfers >", curses.A_BOLD|self.colors["green"])
					elif self.display["transfers"] == "downloads" and window == "uploads":
						win.border()
						win.addstr(0, 3, "< Uploading Transfers >", curses.A_BOLD)
					win.addch(0, 29, curses.ACS_TTEE )
					win.addch(0, 29, curses.ACS_TTEE )
					win.addch(0, 40, curses.ACS_TTEE )
					if window == "downloads":
						win.addch(0, 45, curses.ACS_TTEE )
					
	
	
			self.scrolling[self.display["list"]] = 0
		except Exception, e:
			self.Hlog("debug", "DrawListsWindows: " + str(e))
		

	def ModeTransfers(self):
		self.display["mode"] = "transfer"
		self.Spl["show_menu"] = False

		try:
			# Cleanup stale windows
			if "uploads" in self.windows["text"]:
				del self.windows["text"]["uploads"]
			if "uploads" in self.windows["border"]:
				del self.windows["border"]["uploads"]
			if "downloads" in self.windows["text"]:
				del self.windows["text"]["downloads"]
			if "downloads" in self.windows["border"]:
				del self.windows["border"]["downloads"]
				
			if mucous_config["mucous"]["transbox"] == "split":
				
					
				u = self.windows["dimensions"]["uploads"] = {"height": self.h/2-4, "width": self.w-2, "top": 2, "left": 1}
				d = self.windows["dimensions"]["downloads"] = {"height": self.h-5-u["height"]-4, "width": self.w-2, "top": self.h/2, "left": 1}
				self.DrawListsWindows("uploads")
				self.DrawListsWindows("downloads")
				
				# Draw download and upload windows
				uw = self.windows["border"]["uploads"]
				uw.noutrefresh()
				dw = self.windows["border"]["downloads"]
				dw.noutrefresh()
				
				utw = self.windows["text"]["uploads"] = uw.subwin( u["height"], u["width"], u["top"], u["left"])
				utw.scrollok(0)
				utw.idlok(1)
				utw.noutrefresh()
				
				dtw = self.windows["text"]["downloads"] = dw.subwin(d["height"],d["width"], d["top"],d["left"])
				dtw.scrollok(0)
				dtw.idlok(1)
				dtw.noutrefresh()
				
			elif mucous_config["mucous"]["transbox"] == "tabbed":
				if self.display["transfers"] == "uploads":
					# Draw upload window
					u = self.windows["dimensions"]["uploads"] = {"height": self.h-7, "width": self.w-2, "top": 2, "left": 1}
					self.DrawListsWindows("uploads")
					
					uw = self.windows["border"]["uploads"]
					uw.refresh()
					utw = self.windows["text"]["uploads"] = uw.subwin( u["height"], u["width"], u["top"], u["left"])
					utw.scrollok(0)
					utw.idlok(1)
					utw.noutrefresh()
				else:
					# Draw download window
					d = self.windows["dimensions"]["downloads"] = {"height": self.h-7, "width": self.w-2, "top": 2, "left": 1}
					self.DrawListsWindows("downloads")

					dw = self.windows["border"]["downloads"]
					dw.refresh()
					# Draw download window
					dtw = self.windows["text"]["downloads"] = dw.subwin(d["height"],d["width"], d["top"],d["left"])
					dtw.scrollok(0)
					dtw.idlok(1)
					dtw.noutrefresh()
			
		except Exception, e:
			self.Hlog("debug", "transfer mode: " + str(e))
			
		try:
			self.TransferBar()
						
			self.set_edit_title("Modify Transfers")
			if mucous_config["mucous"]["transbox"] == "split":
				self.TransfersManagerUpload()
				self.TransfersManagerDownload()
				curses.doupdate()
			else:
				if self.display["transfers"] == "uploads":
					self.TransfersManagerUpload()
					curses.doupdate()
				if self.display["transfers"] == "downloads":
					self.TransfersManagerDownload()
					curses.doupdate()
					
			self.last_transferscroll = self.display["transfers"]
		except Exception, e:
			self.Hlog("debug", "transfer panel: " + str(e))


		self.HotKeyBar()
		curses.doupdate()
	
	def TArrows(self, window, height, pos, string):
		try:
			window.addstr(height, pos, "< ")
			window.addstr(height, pos+2, string.capitalize(), self.colors["green"] | curses.A_BOLD)
			window.addstr(height, pos+2+len(string), " >")
		except Exception, e:
			self.Hlog("debug", "TArrows: " + str(e))
	
	def TransferBar(self):
		try:
			s = self.windows["dimensions"][self.display["transfers"] ]
			window = self.windows["border"][ self.display["transfers"] ]
			pos = 2
			 
			self.TArrows(window, s["height"]+1, pos, mucous_config["mucous"]["transbox"])
			
			if self.display["transfer_sort"] == 'all':
				
				pos = 20
				self.TArrows(window, s["height"]+1, pos, self.display["transfer_sort"])
			else:
				window.addstr(s["height"]+1, 20, "< All >")

			if self.display["transfer_sort"] == 'active':
				pos = 28
				self.TArrows(window, s["height"]+1, pos, self.display["transfer_sort"])
			else:
				window.addstr(s["height"]+1, 28, "< "+'Active'+" >")

			if self.display["transfer_sort"] == 'queued':
				pos = 39
				self.TArrows(window, s["height"]+1, pos, self.display["transfer_sort"])
			else:
				window.addstr(s["height"]+1, 39, "< "+'Queued'+" >")
			if self.display["transfer_sort"] == 'finished':
				pos = 50
				self.TArrows(window, s["height"]+1, pos, self.display["transfer_sort"])
			else:
				window.addstr(s["height"]+1, 50, "< "+'Finished'+" >")
			if self.display["transfer_sort"] == 'failed':
				pos = 63
				self.TArrows(window, s["height"]+1, pos, self.display["transfer_sort"])
			else:
				window.addstr(s["height"]+1, 63, "< "+'Failed'+" >")
			window.refresh()
		except Exception, e:
			self.Hlog("debug", "TransferBar: " + str(e))
		
			
	def ModeBrowse(self):
		try:
			self.display["mode"] = "browse"
			self.Spl["show_menu"] = False

			# Cleanup stale windows
			if "browse" in self.windows["text"]:
				del self.windows["text"]["browse"]
			if "browse" in self.windows["border"]: 
				del self.windows["border"]["browse"]
			if "dirwin" in self.windows["text"]:
				del self.windows["text"]["dirwin"]
			if "dirborder" in self.windows["border"]:
				del self.windows["border"]["dirborder"]
			if "browsebar" in self.windows["text"]:
				del self.windows["text"]["browsebar"]
			
			w = self.windows["dimensions"]["browse"] = {"height": self.h-11, "width": self.w-mucous_config["mucous"]["browse_width"], "top": 5, "left": mucous_config["mucous"]["browse_width"]-1, "start": 0}
			# Files Border	
			wbb = self.windows["border"]["browse"] = curses.newwin(w["height"]+2, w["width"]+2, w["top"]-1, w["left"]-1)
			# Directories Border
			self.windows["border"]["dirborder"] = curses.newwin(w["height"]+2, self.w-w["width"]-2, w["top"]-1, 0)
			self.DrawBrowseWin()
			# Files Text
			tbb = self.windows["text"]["browse"] = wbb.subwin(w["height"], w["width"], w["top"], w["left"])
			tbb.scrollok(0)
			tbb.idlok(1)
			tbb.noutrefresh()

			d = self.windows["dimensions"]["directories"] = {"height": w["height"], "width": self.w-w["width"]-4, "top": w["top"], "left":1}
			# Directories Text
			dw = self.windows["text"]["dirwin"] = self.windows["border"]["dirborder"].subwin(d["height"], d["width"], d["top"], d["left"])
			dw.erase()
			dw.noutrefresh()
	
# 			self.scrolling["browsefile"] = self.scrolling["browsedir"] = 0
			# Vars

			self.data["files"] = []
			self.data["directories"] = []
			
			self.windows["text"]["browsebar"] = curses.newwin(1, self.w, w["top"]+w["height"]+1, 0)
			self.windows["text"]["browsebar"].erase()
			self.windows["text"]["browsebar"].noutrefresh()
			
			self.AlertCheck()
			self.HotKeyBar()
			self.FormatBrowse()
			curses.doupdate()
			del w
		except Exception, e:
			self.Hlog("debug", "ModeBrowse: " + str(e))
			
	def DrawBrowseWin(self):
		try:
			w = self.windows["dimensions"]["browse"]
			mw = self.windows["border"]["browse"]
			if self.display["browse"] == "files":
				mw.attron(self.colors["green"])
			else:
				mw.attroff(self.colors["green"])
			mw.border()
	
			try:
				if self.display["browse"] == "files":
					attr = self.colors["green"] | curses.A_BOLD
				else:
					attr = curses.A_BOLD
				if self.usernames["browse"] == "default__":
					mw.addstr(0, 3, "< Browse users >",  attr)
				else:
					mw.addstr(0, 1, "<Num",  attr)
					mw.addch(curses.ACS_VLINE, attr)
					mw.addstr(" Size  ",  attr)
					mw.addch(curses.ACS_VLINE, attr)
					mw.addstr(" Filename >",  attr)
			except:
				pass
			mw.noutrefresh()
			
			self.windows["border"]["dirborder"].erase()
			if self.display["browse"] == "directories":
				self.windows["border"]["dirborder"].attron(self.colors["green"])
				attr = self.colors["green"] | curses.A_BOLD
			else:
				attr = curses.A_BOLD
			self.windows["border"]["dirborder"].border()
			self.windows["border"]["dirborder"].attroff(self.colors["green"] )
			self.windows["border"]["dirborder"].addstr(0, 1, "< Directories >",  attr)
			self.windows["border"]["dirborder"].addstr(w["height"]+1, 1, "< Width - %s + >"  % mucous_config["mucous"]["browse_width"],  attr)
			self.windows["border"]["dirborder"].noutrefresh()

			if self.usernames["browse"] == "default__":
				self.scrolling["browsedir"] = 0
				self.set_edit_title("Choose a user to Browse Shares")
				self.DrawInstructionsButtons()
			else:
				self.DrawInstructionsButtons()
				#s = "Browse "+self.usernames["browse"]+"'s files in "
				#ls = len(s)
				#self.set_edit_title(s  + self.Spl["dir_browse"][:self.w-ls-8] )
				self.set_edit_title( self.Spl["dir_browse"][:self.w-8] )
		except Exception, e:
			self.Hlog("debug", "DrawBrowseWin: " + str(e))
			
	def FormatBrowseDirs(self):
			 
			d = self.windows["dimensions"]["directories"]
			w = self.windows["dimensions"]["browse"] 
			tw = self.windows["text"]["browse"]

                        # If the default help isn't displayed
			if self.usernames["browse"] != "default__":
				
				tempdirs = self.data["browse_results"][self.usernames["browse"]]["dirs"]
				#tempdirs.sort(key=str.lower)
                                # List, Directory, Scroll position
				collapsed = self.data["collapsed_dirs"][self.usernames["browse"]]
				num = 0
				dirswithtree = []
				self.data["directories"] = []
				parents = []
				for directory in tempdirs:
					parent = "\\".join(directory.split("\\")[:-1])
					if parent in tempdirs and parent not in parents:
						parents.append(parent)
	
				for directory in tempdirs:
					try:
						parent = "\\".join(directory.split("\\")[:-1]) 
						a = 0
						for dirs in collapsed:
							if parent.startswith(dirs+"\\") or parent == dirs:
								a = 1
								break
						if a == 1:
							num += 1
							continue
						if directory in parents:
							if directory in collapsed:
								dirswithtree.append([directory, 2])
								self.data["directories"].append(directory)
							else:
								for dir in collapsed:
									if dir in directory:
										pass
								else:
									dirswithtree.append([directory, 1])
									self.data["directories"].append(directory)
						else:
							for dir in collapsed:
								if dir in directory:
									pass
							else:
								dirswithtree.append([directory, 0])
								self.data["directories"].append(directory)
					except Exception, e:
						for dir in collapsed:
							if dir in directory:
								pass
						else:
							dirswithtree.append([directory, 0])
							self.data["directories"].append(directory)
					num += 1 
				
				if self.display["browse"] == "directories":
					clipped_list, self.scrolling["browsedir"], start = self.scrollbox(dirswithtree, self.scrolling["browsedir"], d["height"])
				else:
					clipped_list, self.scrolling["browsedir"], start = self.scrollbox(dirswithtree, self.scrolling["browsedir"], d["height"])
				#self.Hlog("debug", self.scrolling["browsedir"])
				self.windows["dimensions"]["directories"]["start"] = start
				count = 0
				self.windows["text"]["dirwin"].erase()
                                # Display directory tree
				for s, has_child in clipped_list:
					try:
						dir = s.split("\\")
						if has_child == 1:
							modifier = "[-]"
						elif has_child == 2:
							modifier = "[+]"
						else: 
							modifier = "|\\"
                                                # Spaces before directory, to make it look like a tree
						string = (" " * (len(dir)-2)) + modifier
						string += self.dlang(dir[-1][:d["width"]-len(string)])
						string += " " * ( d["width"] -len(string) )
						if count +d["start"] == self.scrolling["browsedir"]:
							self.windows["text"]["dirwin"].addstr(string, self.colors["green"])
						else:
							self.windows["text"]["dirwin"].addstr(string)
						count += 1
					except Exception, e:
						pass
						#self.Hlog("debug", str(e))
				del clipped_list
			
			elif self.usernames["browse"] == "default__":
                                # Clear windows, display browse help
				self.windows["text"]["dirwin"].erase()
				self.windows["text"]["dirwin"].noutrefresh()
				tw.erase()
				count = 0
				
				for lines in self.logs["browse"][self.usernames["browse"]]:

					try:
						self.DrawBrowseFileText(lines, count , self.scrolling["browsefile"])
		
					except Exception, e:
						self.Hlog("debug", "Browse mode" + str(e))
			tw.noutrefresh()
			
	def FormatBrowse(self, FormatDirs=1):
		try:
			if "directories" not in self.windows["dimensions"]:
				return
			if FormatDirs:
				self.FormatBrowseDirs()
			if self.usernames["browse"] != "default__":
				self.Spl["dir_browse"] = self.data["directories"][self.scrolling["browsedir"]]
				self.set_edit_title(self.Spl["dir_browse"] )
			
				self.BrowseFiles( self.usernames["browse"], self.Spl["dir_browse"])
			
				self.BrowseFileBar( self.usernames["browse"], self.Spl["dir_browse"])
			
			self.windows["text"]["dirwin"].noutrefresh()
		
			
			
			self.DrawTabs(self.activeitems["browse"], self.usernames["browse"])

			
		except Exception, e:
			self.Hlog("debug", "FormatBrowse: " + str(e))
			
	def BrowseUser(self, user):
		try:
			if user not in self.requests["browse"]:
				self.requests["browse"].append(user)
			self.SendMessage(messages.UserShares(user))
		except Exception, e:
			self.Hlog("debug", "BrowseUser" + str(e))
			
	def DrawBrowseFileText(self,  line, count, sup):
		try:
			w = self.windows["dimensions"]["browse"]
			tw = self.windows["text"]["browse"]
			this_line = self.dlang( line )
			if len(this_line) > self.windows["dimensions"]["browse"]["width"]:
				crop = len(this_line) - self.windows["dimensions"]["browse"]["width"]
				this_line = this_line[:-crop]
				
			if count + w["start"] == sup:
				attr = self.colors["blafgcyabg"] |curses.A_REVERSE|curses.A_BOLD	
				nattr = self.colors["cyan"] |curses.A_REVERSE|curses.A_BOLD
			else:
				attr = curses.A_NORMAL
				nattr = self.colors["cyan"] 
			if self.usernames["browse"] == "default__":
				tw.addstr(this_line, attr )
			else:
				tw.addstr(this_line[:4], attr )
				tw.addch(curses.ACS_VLINE, attr)
				tw.addstr(this_line[5:12], nattr )
				tw.addch(curses.ACS_VLINE, attr)
				tw.addstr(this_line[13:], attr )
			z = w["width"]-len(this_line)
			space = " " * ( z )
			tw.addstr(space, attr)
			
		except:
			pass
			

	def ModeSearch(self):
		try:
			self.display["mode"] = "search"
			self.Spl["show_menu"] = False
			
			# Cleanup stale windows
			if "search" in self.windows["text"]:
				del self.windows["text"]["search"]
			if "search" in self.windows["border"]:
				del self.windows["border"]["search"]
			if "searchstats" in self.windows["border"]:
				del self.windows["border"]["searchstats"]
				
			w = self.windows["dimensions"]["search"] = {"height": self.h-11, "width": self.w-2, "top": 5, "left": 1, "start": 0}
			mw = self.windows["border"]["search"] = curses.newwin(w["height"]+2, w["width"]+2, w["top"]-1, w["left"]-1)
			mw.attron(self.colors["green"])
			mw.border()
			mw.attroff(self.colors["green"])
			try:
				mw.addstr(0, 3, "< Search >",  self.colors["green"] | curses.A_BOLD)
			except:
				pass
			
			if self.sfilter != None:
				sfilter = "Filter: " +self.sfilter
				
			else:
				sfilter = "Filter: Disabled"
			lfil = len(sfilter)
			mw.addstr(0,15, "< ", self.colors["green"])
			if self.sfilter != None:
				mw.addstr(0,17, self.dlang(sfilter), self.colors["cyan"] | curses.A_BOLD)
			else:
				mw.addstr(0,17, self.dlang(sfilter), self.colors["red"] | curses.A_BOLD)
			mw.addstr(0,17+lfil, " >", self.colors["green"])
			
			self.DrawSearchSortBar()
			tw = self.windows["text"]["search"] = mw.subwin(w["height"], w["width"], w["top"], w["left"])
			tw.scrollok(0)
			tw.idlok(1)
			
			self.windows["border"]["searchstats"] = curses.newwin(1, self.w, self.h-5, 0)
			self.windows["border"]["searchstats"].erase()
			self.windows["border"]["searchstats"].noutrefresh()
			
			self.FormatSearches()
			
			
			if self.Spl["search_method"] != None:
				if self.Spl["search_method"] == "user":
					if self.usernames["search"] != None:
						self.set_edit_title("Search (Alt-t) "+self.Spl["search_method"].capitalize()+" "+self.usernames["search"]+"'s shares")
					else:
						self.set_edit_title("Search (Alt-t) "+self.Spl["search_method"].capitalize()+" (Pick a user with /searchuser)")
				else:
					self.set_edit_title("Search (Alt-t) "+self.Spl["search_method"].capitalize()+" for:")
			self.DrawTabs(self.data["search_tickets"].keys(), self.Spl["current_search"])

			if self.Spl["current_search"] != "default__":
				self.DrawInstructionsButtons()
				self.AlertCheck()
			else:
				self.HotKeyBar()
			curses.doupdate()
		except Exception,e:
			self.Hlog("debug", "ModeSearch: "+str(e))
			
	def DrawSearchSortBar(self):
		try:
			w = self.windows["dimensions"][self.display["mode"]]
			ls = ("Num", "User", "Free", "Speed", "Que", "Path", "Size", "File", "Bitrate", "Time")
			mw = self.windows["border"]["search"]
			mw.addstr(w["height"]+1, 1, "<    |    |    |     |   |    |    |    |       |     >", self.colors["green"])
			pos  = 0
			for i in ls:
				if i == self.Spl["search_order"].capitalize():
					mw.addstr(w["height"]+1, 3+pos, self.Spl["search_order"].capitalize(), self.colors["green"]| curses.A_BOLD)
				else:
					mw.addstr(w["height"]+1, 3+pos, i, self.colors["red"] | curses.A_BOLD)
				pos += len(i) + 1
	
			pos = 56
			mw.addstr(w["height"]+1, pos, "<         >", self.colors["green"])
			pos = 58
			if self.Spl["search_reverse"]:
				
				mw.addstr(w["height"]+1, pos, "Reverse", self.colors["green"]| curses.A_BOLD)
			else:
				mw.addstr(w["height"]+1, pos, "Reverse", self.colors["red"]| curses.A_BOLD)
	
			mw.noutrefresh()
			
		except Exception,e:
			self.Hlog("debug", "DrawSearchSortBar: "+str(e))
					
	def FormatSearches(self):
		try:
			
			if self.Spl["current_search"]== "default__":
				tw = self.windows["text"]["search"]
				tw.erase()
				w=self.windows["dimensions"]["search"]
				for lines in self.logs["search"][self.Spl["current_search"]]:
					try:
						lines, ls = self.StringAddBlanks(lines, w)
						tw.addstr(self.dlang(lines))
					except:
						pass
				tw.noutrefresh()
				
			else:
				try:
					if self.Spl["show_menu"] == True: raise  Exception,  "popup"
					self.Format_Search_Results(self.Spl["current_search"])
				except:
					pass
			
		except Exception,e:
			self.Hlog("debug", "FormatSearches: "+str(e))
			
	def DrawInstructionsButtons(self):
		try:
			if self.display["mode"] == "search":
				gi = "Instructions"
			elif self.display["mode"] == "browse":
				gi = "Instructions"
			elif self.display["mode"] == "info":
				gi = "Instructions"

			w = self.windows["dimensions"][self.display["mode"]]
			pos = w["width"]-3-len(gi)
			if self.display["mode"] != "lists":
				mw = self.windows["border"][ self.display["mode"] ]
			else:
				mw = self.windows["border"][ self.display["list"] ]
			mw.addstr(0,pos, "< ")
			mw.addstr(0,pos+2, gi, self.colors["cyan"] | curses.A_BOLD)
			mw.addstr(0,pos+2+len(gi), " >")
			vertex = w["height"]+1
			if self.display["mode"] == "search":
				mw.addstr(vertex,self.w-11, "< ", self.colors["green"])
				mw.addstr(vertex,self.w-9, "Close ", self.colors["cyan"] | curses.A_BOLD)
				mw.addstr(vertex,self.w-3, ">", self.colors["green"])
			if self.display["mode"] == "browse":
				blah = None
				if "encoding.users" in self.config:
					if self.usernames["browse"] in self.config["encoding.users"]:
						blah = self.config["encoding.users"][self.usernames["browse"]]
					else:
						blah = self.config["encoding"]["filesystem"]
				if blah != None:
					mw.addstr(vertex,w["width"]-17-len(blah)-4, "<" + (" " *( len(blah) +2) )+  ">")
					mw.addstr(vertex,w["width"]-17-len(blah)-2, blah, self.colors["cyan"] | curses.A_BOLD)
				mw.addstr(vertex,w["width"]-11, "< ")
				mw.addstr(vertex,w["width"]-9, "Close ", self.colors["cyan"] | curses.A_BOLD)
				mw.addstr(vertex,w["width"]-3, ">")
			elif self.display["mode"] == "info":
				isw = self.windows["border"]["infostats"]
				isw.addstr(vertex,3, "< ")
				isw.addstr(vertex,5, "Close ", self.colors["cyan"] | curses.A_BOLD)
				isw.addstr(vertex,11, ">")
				isw.noutrefresh()
			mw.noutrefresh()
		except Exception, e:
			self.Hlog("debug", "TemporaryClickText " + str(e))
	
	def DrawTabs(self, tab_box_list, selected_tab):
		try:
			if tab_box_list == [None]:
				return
			lang = mucous_config["mucous"]["language"]

			if "bar" in self.windows["tab"]:
				del self.windows["tab"]["bar"]
			tbar = self.windows["tab"]["bar"] = curses.newwin(3, self.w, 1, 0)
			tbar.hline(1, 1, curses.ACS_HLINE, self.w-2)
			self.activeitems["positions"]= {}
			tbar.addstr(1,0, "<")
			tbar.addstr(1,self.w-1, ">")
		
			tbar.noutrefresh()
			if tab_box_list == []:
				return
			pos = 1
			for string in tab_box_list:

				if self.display["mode"]=="search":
					sting = self.data["search_tickets"][string][:13]
				
				else:
					sting = string[:13]
					
				move = len(sting)+2
				
				sting = self.dlang(sting)
				self.activeitems["positions"][string] = pos, move+pos
				
				if pos + move >= self.w -2:
					return
				
				tb = curses.newwin(3, len(sting)+2, 1, pos)
				tb.border()
				tb.noutrefresh()
				tl = tb.subwin(1,len(sting),2,pos+1)
				
				try:
					
					if self.display["mode"] == "search":
						if string == self.Spl["current_search"]:
							tl.addstr(sting, self.colors["green"] | curses.A_BOLD)
						else:
							tl.addstr(sting, curses.A_BOLD)

						continue
					
					username = string
					if string == selected_tab:
						if string in self.user["status"]:
							attr = curses.A_BOLD
							if self.user["status"][username] == 1:
								attr = self.colors["yellow"] | curses.A_BOLD
								
							elif self.user["status"][username] == 2:
								attr = self.colors["green"] | curses.A_BOLD
							elif self.user["status"][username] == 0:
								attr = self.colors["red"] | curses.A_BOLD
							tl.addstr(sting, attr)
						else:
							tl.addstr(sting, self.colors["red"] | curses.A_BOLD)
					else:
						if string in self.user["status"]:
							attr = curses.A_NORMAL
							if self.user["status"][username] == 1:
								attr = self.colors["yellow"]
							elif self.user["status"][username] == 2:
								attr = self.colors["green"]
							elif self.user["status"][username] == 0:
								attr = self.colors["red"]
							tl.addstr(sting, attr)
						else:
							tl.addstr(sting, self.colors["red"])  
					
				except:
					# Always get errors, because text is the same size as window
					pass
				pos += len(sting)+2
				tl.noutrefresh()
				# Cleanup stale windows
				del tl
				del tb
				
		except Exception, e:
			self.Hlog("debug", "DrawTabs: " + str(e))
			
	def ModeInfo(self):
		try:
			self.display["mode"] = "info"
			self.Spl["show_menu"] = False
			# Cleanup stale windows
			if "info" in self.windows["text"]:
				del self.windows["text"]["info"]
			if "info" in self.windows["border"]: 
				del self.windows["border"]["info"]
			if "infostats" in self.windows["text"]:	
				del self.windows["text"]["infostats"]
			if "infostats" in self.windows["border"]:
				del self.windows["border"]["infostats"]
			
			w = self.windows["dimensions"]["info"] = {"height": self.h-10, "width": self.w-20, "top": 5, "left": 1}
			mw = self.windows["border"]["info"] = curses.newwin(w["height"]+2, w["width"]+2, w["top"]-1, w["left"]-1)
			mw.attron(self.colors["green"])
			mw.border()
			mw.attroff(self.colors["green"])
			try:
				mw.addstr(0, 3, "< Info Mode >",  self.colors["green"] | curses.A_BOLD)
			except:
				pass
	
			tw =  self.windows["text"]["info"] = mw.subwin(w["height"], w["width"], w["top"], w["left"])
			tw.scrollok(0)
			tw.idlok(1)
			
			self.scrolling["info"] = -1
	
			self.set_edit_title("Get info about user:")
			
			sw = self.windows["dimensions"]["infostats"]= {"height": self.h-10, "width": 16, "top": 5, "left": self.w-17}
			isw = self.windows["border"]["infostats"] = curses.newwin(sw["height"]+2, sw["width"]+2, sw["top"]-1, sw["left"]-1)
			isw.border()
			isw.addstr(0, 2, "< Stats >")
			isw.noutrefresh()
			itw = self.windows["text"]["infostats"] = isw.subwin(sw["height"], sw["width"], sw["top"], sw["left"])
			itw.scrollok(1)
	
			mw.noutrefresh()
			
			self.DrawUserInfoText()
			itw.noutrefresh()
			# queue, uploads, speed, downloads, files, directories, freeslots

			self.DrawTabs(self.activeitems["info"], self.usernames["info"])
			self.DrawUserInfoStats()
			self.AlertCheck()
			curses.doupdate()
			#self.HotKeyBar()
		except Exception, e:
			self.Hlog("debug", "ModeInfo: " + str(e))
			
	def DrawUserInfoText(self):
		try:
			scrolltext = "info"
			w = self.windows["dimensions"]["info"] 
			lang = mucous_config["mucous"]["language"]
			tw = self.windows["text"]["info"]
			if self.usernames["info"] != None:
				self.DrawInstructionsButtons()
				# Display Userinfo & Stats
				clipped_list, self.scrolling["info"], w["start"] = self.wrap_n_clip(self.logs["info"][self.usernames["info"]][0], w, scrolltext )
				
			else:
				# Display instructions, IP info, and stats
				clipped_list, self.scrolling["info"], w["start"] = self.wrap_n_clip( self.infolog, w, scrolltext )
	
			attrs = curses.A_BOLD; attr = curses.A_NORMAL
			count = 0
			tw.erase()
			for lines in clipped_list:
				try:
					lines, ls = self.StringAddBlanks(lines, w)
					if count + w["start"] == self.scrolling["info"]:
						tw.addstr(self.dlang(lines), attrs)
					else:
						tw.addstr(self.dlang(lines), attr)
					count += 1
				except Exception, e:
					pass
			tw.noutrefresh()
		except Exception, e:
			self.Hlog("debug", "DrawUserInfoText: " + str(e))
		
	def ModeHelp(self):
		try:
			# Cleanup stale windows
			if "help" in self.windows["text"]:
				del self.windows["text"]["help"]
			if "help" in self.windows["border"]:
				del self.windows["border"]["help"]
				
			if self.display["mode"] not in ("help", "debug"):
				self.display["mode"] = "debug"
			if self.display["mode"] == "help":
				logfile = self.helplog
			elif self.display["mode"] == "debug":
				logfile = self.helpdebuglog
			self.Spl["show_menu"] = False
			
			s = self.windows["dimensions"]["help"] = {"height": self.h-7, "width": self.w-2, "top": 2, "left": 1, "start": 0}
			mw = self.windows["border"]["help"] = curses.newwin(s["height"]+2, s["width"]+2, s["top"]-1, s["left"]-1)
			mw.attron(self.colors["green"])
			mw.border()
			mw.attroff(self.colors["green"])
			try:
				if self.display["mode"] == "help":
					mw.addstr(0, 3, "< Help Mode >",  self.colors["green"] | curses.A_BOLD)
					mw.addstr(0, 18, "<            >",  self.colors["green"])
					mw.addstr(0, 20, "Debug Mode",  curses.A_BOLD)
				elif self.display["mode"] == "debug":
					mw.addstr(0, 3, "<           >",  self.colors["green"] )
					mw.addstr(0, 5, "Help Mode",  curses.A_BOLD)
					mw.addstr(0, 18, "< Debug Mode >",  self.colors["green"] | curses.A_BOLD)
			except:
				pass
			mw.refresh()
			tw = self.windows["text"]["help"]  = mw.subwin(s["height"], s["width"], s["top"], s["left"])
			tw.scrollok(0)
			tw.idlok(1)
			
			self.scrolling["help"] = -1
			self.scrolling["debug"] = -1
			self.FormatHelp()
			
			self.set_edit_title("Use /help")
			#if self.logs["alert"] in ("New Help", "New Bug", "New Status"):
			#	self.AlertStatus("")
				
			
			self.AlertCheck()
			curses.doupdate()
		except Exception, e:
# 			self.Hlog("debug", ": " + str(e))
			pass
			
	def FormatHelp(self):
		try:
			w = self.windows["dimensions"]["help"]
			tw = self.windows["text"]["help"]
			size = w["height"] * w["width"]
			if self.display["mode"] == "help":
				logfile = self.helplog
			elif self.display["mode"] == "debug":
				logfile = self.helpdebuglog
			# DEBUGGING
			wrapped_lines = []
			for lines in logfile:
				list_of_strings = self.StringCutWidth(lines, w)
				for string in list_of_strings:
					wrapped_lines.append(string)
			if self.scrolling[self.display["mode"]] == -1:
				self.scrolling[self.display["mode"]] = len(wrapped_lines)
				
			clipped_list, self.scrolling[self.display["mode"]], w["start"] = self.scrollbox(wrapped_lines, self.scrolling[self.display["mode"]], w["height"])
			del wrapped_lines
			count = 0
			
			blanked_lines = []
			for lines in clipped_list:
				s, ls = self.StringAddBlanks(lines, w) 
				blanked_lines.append(s)
				
			clipped_list = blanked_lines
			del blanked_lines
			count = 0
			total_lines = 0
			tw.erase()
			for line in clipped_list:
				try:
					if line is clipped_list[-1]:
						line = line[:-1]
					self.DrawHelp(self.display["mode"], line, count)
					count += 1
				except Exception, e:
					self.ChatRoomAppend("Status", self.Spl["room"], 'ERR', str(e) )
			tw.refresh()
			
		except Exception, e:
			self.ChatRoomAppend("Status", self.Spl["room"], "FormatHelp: ", str(e))
			
	def Hlog(self, htype, s):
		try:
			s = str(s)
			
			if htype == "help":
				if "\n" in s:
					lis = s.split("\n")
					for line in lis:
						self.helplog.append("%s" %line )
				else:
					self.helplog.append("%s" %s )
			elif htype in ("status", "debug"):
				timestamp = time.strftime("%H:%M:%S")
				if htype == "status":
					ex = ''
				else: ex = "BUG " 
				if "\n" in s:
					lis = s.split("\n")
					for line in lis:
						if line is lis[0]:
							self.helpdebuglog.append("%s %s%s" % (timestamp,ex,line))
						else:
							self.helpdebuglog.append("%s%s" % (ex,line))
				else:
					self.helpdebuglog.append("%s %s%s" %(timestamp, ex,s))
				
			if self.display["mode"] in ( "help", "debug", "status"):
				#self.DrawHelp( htype, s, 0)
				self.scrolling[self.display["mode"]] = -1
				self.FormatHelp()
				#self.AlertCheck()
			else:
				if htype not in self.alert["HELP"]:
					if htype == "help":
						self.alert["HELP"].append("help")
					elif htype == "status":
						self.alert["HELP"].append("status")
					elif htype == "debug":
						self.alert["HELP"].append("debug")
				
				self.AlertCheck()
		except Exception, e:
			pass
					
	def HelpPages(self):
						
		self.pminfolog = ["Global Private Messaging commands:",\
"To start a Private Message:",\
"1) Type in the username you wish to PM below",\
"2) Press <Enter>",\
"3) Type your messages",
"Use the commands below:",\
"/pm      <user>        (Start PM or switch to user)",\
"/close   <user>        (Close user's PM) ",\
"/close                 (Close current PM)",\
"/ip                    (Get the IP of current user)",\
"/msg <message>         (Send message to previous chosen user)"]

		

		self.infolog = ["Global User Information commands:",\
"/userinfo <user>",\
"/stat     <user>",\
"/ip       <user>",\
"Or type the user name that you wish get recieve userinfo from, below.",\
 "--"]
		
		self.help_chat = ["----[Chat Commands]----", \
"/join <room>   /part <room>  /leave <room>",\
"/j <room>      /talk <room>  /say <room> <message>",\
"/users <room>          (lists of users in room)",\
"/autojoin <room>       (Toggle Autojoining room)",\
"/roomlistrefresh       (redownload roomlist from server)",\
"/inrooms               (list of joined rooms)",\
"/clearroom <room>      (clear <room>, or current room)",\
"/pm <user>             (Private Message user)",\
"/msg <message>         (send message to last user)",\
"/url          /urlcustom (command$command)    (Requires X11)",\
"/urlreader (lynx|links|elinks|firefox|custom) (Requires X11)",\
"/np                    (XMMS/BMP Now playing script)",\
"/npcheck               (display Now playing script command)",\
"/npset <command>       (Set Now playing script to command)",\
"/npprefix <text>       (set to np: or /me is now playing:)",\
"/alias <alias> <text>  /unalias <alias>"]

		self.help_ticker = ["----<Ticker Commands>---- ",\
"/showtickers           (Hide/Show tickers)",\
"/tickers               (Scroll or Cycle through tickers)",\
"/listtick <room>       (List tickers in the Info mode)",\
"/tickroom <room>       (Choose room for setting tickers)",\
"/settick <message>     (Set ticker to message, and save it)",\
"/defaulttick <message> (Set & save default ticker)",\
"/settemptick <message> (Set ticker only for this session)"]

		self.help_connect = ["Connection Configuration",\
"/interface </tmp/museekd.[username]> or <host:port>",\
"/password <interface password>",\
"/connect               (Attempts to connect to Museekd)",\
"/disconnect            (Disconnects from Museekd)",\
"/login                 (Login to Soulseek Server)",\
"/logout                (Logout from Soulseek Server)",\
"/save                  (Writes settings to config)"]

		self.help_setup = ["Setup",\
"/autobuddy    (Auto-buddy users you download from)",\
"/autoclear    (auto-clear finished uploads)",\
"/autoretry    (auto-retry failed/errored transfers)",\
"/password     (Mucous' Interface password)",\
"/privbuddy    (Toggle Privileging buddies)",\
"/onlybuddy    (Toggle Only sharing to buddies)",\
"/slots <num>  (Set upload slots)",\
"/unhide       (Toggle showing password)",\
"/rescan       (Rescan Normal Shares)",\
"/rescanbuddy  (Rescan Buddy-only Shares)",\
"/reload       (Reload Shares - make changes take effect)",\
"/extra        (Auto-Send Version info via PM if requested)",\
"/logdir /path (Set Logs Directory)",\
"/logging      (Toggle Logging)"]

		self.help_user = ["----[User Commands]---- ",\
"/buddy    <user>    /unbuddy   <user>",\
"/ban      <user>    /unban     <user> (Cannot access your files)",\
"/ignore   <user>    /unignore  <user> (No messages in chat)",\
"/nuke     <user>    /unnuke    <user> (Ban+Ignore)",\
"/trust    <user>    /distrust  <user> (Can Upload to you)",\
"/stat     <user>    /ip        <user>",\
"/userinfo <user>    /giveprivs <user> (Input days next)",\
"/away (Toggle your Online/Away Status)",\
"/autoaway (Go away after 900 seconds of inactivity)"]

		self.help_transfer = ["----[Transfer Commands]---- ",\
"/abortu  <num> /abortup    <num> (Abort Upload)",\
"/abortd  <num> /abortdown  <num> (Abort Download)",\
"/removeu <num> /removeup   <num> (Remove Upload)",\
"/removed <num> /removedown <num> (Remove Download)",\
"/retry   <num>                   (Retry Download)",\
"/retryall                        (Retry all Downloads)",\
"/clearup                         (Clear failed/finished Uploads)",\
"/cleardown                       (Clear finished Download)",\
"/percent                         (Toggle Percent/Speed",\
"/transbox                        (Toggle Split/Tabbed Mode))"]
		self.ModeHelp_text = ["----[Mode Commands]---- ",\
"/chat          (Chat Mode)",\
"/transfer      (Transfer Mode)",\
"/info          (Info Mode)",\
"/browse        (Browse Mode)",\
"/private       (Private Message Mode)",\
"/search        (Search Mode)",\
"/buddylist     (Buddylist Mode)",\
"/banlist       (Banlist Mode)",\
"/ignorelist    (Ignorelist Mode)",\
"/roomlist      (Roomlist Mode)",\
"/setup         (Setup Mode)",\
"/help /debug   (Help & Debug Mode)"]

		self.help_help = ["----<Help Commands>---- ",\
"/help          (This Message)",\
"/help connect  (Connection Commands)",\
"/help setup    (Setup Commands)",\
"/help mode     (Mode Commands)",\
"/help chat     (Chatroom Commands)",\
"/help ticker   (Ticker Commands)",\
"/help user     (User Commands)",\
"/help transfer (Transfer Commands)",\
"/help browse   (Browse Commands)",\
"/help search   (Search Commands)",\
"/help download (Download Commands)",\
"/help keys     (Special Keys)",\
"/quit          (Close Mucous)"]
		
		
		self.help_search2 = [\
"/search                (Switch to Search Mode)",\
"/searchfor   <query>   (Global Search)",\
"/searchbuddy <query>   (Buddy Search)",\
"/searchroom  <query>   (Room Search)",\
"/searchuser  <user>    (Search only one user's shares)",\
"/download <number>     (Download File with number)",\
"/downdir  <number>     (Download directory of File)",\
"/close                 (Close current search)",\
"/clearsearchs          (Removes all searches)",\
"/filter <string>       (limit displayed files)",\
"Mouse: Right-Click     (popup menu)",\
"Press Insert to toggle sorting methods.",\
"Press Alt-T to toggle Global/Buddy/Room searches",\
"Press Insert to toggle sorting methods."]

		self.help_search = ["----<Search Commands>----"] + self.help_search2
		self.logs["search"]["default__"] = ["Search commands:"] + self.help_search2 + ["Or, type in the query, below."]


		self.help_browse = ["----<Browse Commands>----",\
"/browse                (Switch to Browse Mode)",\
"/buser    <user>       (Browse User)",\
"/bsearch  <query>      (Search thru Shares)",\
"/download <number>     (Download file with this number)",\
"/close                 (close current shares)",\
"Press Insert to toggle between shares.",\
"Alt-X                  (Expand/Collapse directory)",\
"/browsewidth <number>  (Resize Directories window)",\
"--File System browsing commands--",\
"cd (change dir) get, getdir (download)",\
"First, type in the user you wish to browse, below.", \
"Right-click on directories or files to display the popup menu."]

		self.logs["browse"]["default__"] = self.help_browse
		
		self.help_download = ["----<Manual Download Commands>----",\
"/downuser <user>    (Set download user)",\
"/downpath <path>    (Download file from user)",\
"/downpathdir <path> (Download dir from user)"]

		self.help_keys =["------<Keys>------ ",\
"No guarantees that these HotKeyBar work with your terminal",\
"ESC or Alt + [, ], <-, ->  (Change Room / Transfer display mode)",\
"Insert                     (Same as above)",\
"Tab                        (Completes nicks)",\
"Home/End                   (switches Upload & Download scrolling)",\
"Up, PageUp                 (Scroll Up a line, a page)",\
"Down, PageDown             (Scroll Down a line, a page)",\
"F1->Chat Rooms           F6->Browse Users",\
"F2->Private Messages     F7->User Lists/Interests",\
"F3->Transfers            F8->Rooms List",\
"F4->Search               F9->Setup",\
"F5->Info                 F10->Help"]
		self.helpdebuglog = []
		self.helplog =[\
"  _____  __ __   ____  ____  __ __  ______",\
" /     \|  |  \_/ ___\/  _ \|  |  \/  ___/",\
"|  Y Y  \  |  /\  \__(  <_> )  |  /\___ \ ",\
"|__|_|  /____/  \___  >____/|____//____  >",\
"      \/            \/                 \/",\
"/help          (This Message)         /quit          (Shut down Mucous)",\
"/help connect  (Connection Commands)  /help setup    (Setup Commands)",\
"/help mode     (Mode Commands)        /help user     (User Commands)",\
"/help chat     (Chatroom Commands)    /help ticker   (Ticker Commands)",\
"/help transfer (Transfer Commands)    /help download (Download Commands)",\
"/help browse   (Browse Commands)      /help search   (Search Commands)",\
"/help keys     (Special Keys)"]	

	def StringCutWidth(self, s, w):
		try:
			s = str(s); ls = len(s)
			list_of_strings = []
			if ls > w["width"]:
				div = (ls/w["width"]) + 1
				# Cut long lines into multiple lines
				for seq in range(div):
					list_of_strings.append(s[:w["width"]])
					s = s[w["width"]:]
			else:
				# Short line added to list
				list_of_strings.append(s)
			return list_of_strings
		except Exception, e:
			self.Hlog("debug", ": " + str(e))
		
	def StringAddBlanks(self, s, w):
		try:
			#, total_lines
			# s == string
			# w == window_dimensions dict
			s = str(s); ls = len(s)
			if ls > w["width"]:
				# Add spaces if longer than a single line
				div = (ls/w["width"]) + 1
				length = (w["width"] * div) -  ls 
				if length != 0:
					s += (length * " ")
				#total_lines += div
	
			else:
				# Add spaces till end of first and only line
				s += " " * (w["width"] - ls)
			return s, ls #, total_lines
		except Exception, e:
			self.Hlog("debug", "StringAddBlanks: " + str(e))
			
	def DrawHelp(self, htype, s, count):
		try:
			
			if self.display["mode"] in ( "help", "debug", "status"):
				tw = self.windows["text"]["help"]
				w = self.windows["dimensions"]["help"]
				if count + w["start"] == self.scrolling[self.display["mode"]]:
					attr = curses.A_BOLD
				else:
					attr = curses.A_NORMAL
				
				if self.display["mode"] == "help" and htype == "help":
					tw.addstr(self.dlang(s), attr)
				elif self.display["mode"] == "debug" and htype in( "status", "debug"):
					tw.addstr(self.dlang(s), attr)
				else:
					self.AlertStatus("New Help")
			else:
				self.AlertStatus("New Help")
		except: # Exception, e:
			#self.ChatRoomAppend("Status", self.Spl["room"], "DrawHelp: ", str(e))
			pass
		return #total_lines
					
	def ModeInterests(self):
		try:
			self.display["list"] = "interests"
			self.Spl["show_menu"] = False
# 			self.scrolling[ "recommendations" ] = self.scrolling[ "likes" ] = self.scrolling[ "hates" ] = self.scrolling[ "similar_users" ] = 0
			self.windows["dimensions"]["recommendations"] = s = self.windows["dimensions"][self.display["list"]] = {"height": self.h-8, "top": 3, "left": 21, "width": self.w-42, "start": 0}
			self.windows["dimensions"]["likes"] = l  = self.windows["dimensions"][self.display["list"]] = {"height": self.h/2-5, "top": 3, "left": 1, "width": 18, "start": 0}
			self.windows["dimensions"]["hates"] = h = self.windows["dimensions"][self.display["list"]] = {"height": self.h-8-(l["height"])-2, "top": 5+l["height"], "left": 1, "width": 18, "start": 0}
			self.windows["dimensions"]["similar_users"] = u = self.windows["dimensions"][self.display["list"]] = {"height": self.h-8, "top":3 , "left": self.w-19, "width": 18, "start": 0}
			
			mw = curses.newwin(3, self.w,  1, 0)
			mw.attron(self.colors["green"])
# 			win = curses.newwin(w["height"]+2, w["width"]+2, w["top"]-1, w["left"]-1)
			mw.erase()
			mw.border()
			mw.addstr(0, 3, "< Buddied >",  self.colors["green"])
			mw.addstr(0, 16, "< Banned >", self.colors["green"])
			mw.addstr(0, 28, "< Ignored >", self.colors["green"])
			mw.addstr(0, 40, "< Trusted >", self.colors["green"] )
			mw.addstr(0, 52, "< Interests >", self.colors["green"]  | curses.A_BOLD)
			mw.noutrefresh()
			# Cleanup stale windows
			del mw
	

			if self.display["interests"] == "likes":
				if self.Spl["interests_input"] not in ("add_likes", "del_likes"):
					self.Spl["interests_input"] = "add_likes"
				if self.Spl["interests_input"] == "add_likes":
					self.set_edit_title("Add Liked (Alt-D to Toggle to Delete)")
				elif self.Spl["interests_input"] == "del_likes":
					self.set_edit_title("Delete Liked (Alt-D to Toggle to Add)")
			elif self.display["interests"] == "hates":
				if self.Spl["interests_input"] not in ("add_hates", "del_hates"):
					self.Spl["interests_input"] = "add_hates"
				if self.Spl["interests_input"] == "add_hates":
					self.set_edit_title("Add Hated (Alt-D to Toggle to Delete)")
				elif self.Spl["interests_input"] == "del_hates":
					self.set_edit_title("Delete Hated (Alt-D to Toggle to Add)")
			elif self.display["interests"] == "recommendations":
				self.set_edit_title("Recommendations:")
			elif self.display["interests"] == "similar_users":
				self.set_edit_title("Similar Users:")
			self.InterestsWindows(s, "recommendations")
			self.InterestsWindows(l, "likes")
			self.InterestsWindows(h, "hates")
			self.InterestsWindows(u, "similar_users")
			self.DrawInterests()

			
			self.HotKeyBar()
			curses.doupdate()
		except Exception, e:
			self.Hlog("debug", "ModeInterests: " + str(e))
			
	def DrawInterests(self):
		self.DrawLikedInterests()
		self.DrawHatedInterests()
		self.DrawRecommendations()
		self.DrawSimilarUsers()
		
	def DrawRecommendations(self):
		try:
			mode  = "recommendations"
			self.windows["text"][mode].erase()
			w = self.windows["dimensions"][mode]
			self.logs[mode] = []
			sup = self.scrolling[ mode ]
			if self.data[mode] != {}:
				if self.Spl["recommend_sort"] == "alpha":
					dict = self.data[mode].keys()
					dict.sort(key=str.lower)
					for item in dict:
						self.logs[mode].append( [item, self.data[mode][item] ])

				elif self.Spl["recommend_sort"] == "size":
					dict = self.sortbyvalue(self.data[mode])
					dict.reverse()
					for item, num in dict:
						self.logs[mode].append( [item, num])
				
					
			else:
				self.logs[mode] = [["EMPTY RECOMMENDATIONS", 0]]
			count = 0
			clipped_list, sup, self.windows["dimensions"][mode]["start"] = self.scrollbox(self.logs[mode], sup, w["height"])
			self.scrolling[mode] = sup
			start = self.windows["dimensions"][mode]["start"]
			for item, num in clipped_list:
				length = len( item+( " " * (w["width"] - len(item)-len(str(num))))+str(num ) )
				if length > w["width"]:
					item = item [:w["width"] - length  ]
				if count + start == sup:
					self.windows["text"][mode].addstr(item +( " " * (w["width"] - len(item)-len(str(num))))+str(num ), curses.A_BOLD)
				else:
					self.windows["text"][mode].addstr(item +( " " * (w["width"] - len(item)-len(str(num))))+str(num ))
				count += 1
			self.windows["text"][mode].refresh()
		except Exception, e:
			self.windows["text"][mode].refresh()
 			#self.Hlog("debug", "DrawRecommendations: " + str(e))

	def DrawSimilarUsers(self):
		try:
			mode  = "similar_users"
			self.windows["text"][mode].erase()
			sup = self.scrolling[ mode ]
			w = self.windows["dimensions"][mode]
			if self.data[mode] != {}:
				self.logs[mode] = []
				
				users = self.data[mode].keys()
				users.sort(key=str.lower)
				for user in users:
					self.logs[mode].append( [user, self.data[mode][user] ])
				
				 
				
				clipped_list, sup, start = self.scrollbox(self.logs[mode], sup, w["height"])
				self.windows["dimensions"][mode]["start"] = start
				self.scrolling[mode] = sup
			else:
				clipped_list = [["NO SIMILAR USERS", 0]]
				start = 0
			count = 0
			for user, status in clipped_list:
				if count + start == sup:
					attr = curses.A_BOLD
				else: 
					attr = curses.A_NORMAL
				if status == 1:
					self.windows["text"][mode].addstr("* ", self.colors["yellow"] | attr)
				elif status == 2:
					self.windows["text"][mode].addstr("* ", self.colors["green"] | attr)
				else:
					self.windows["text"][mode].addstr("* " , attr)
				if len (user )+2 > w["width"]:
					user = user[ :w["width"]-2-len(user) ]
				self.windows["text"][mode].addstr(user + " " * (w["width"] - len(user)-2),   attr)
				count +=1
				
			
			self.windows["text"][mode].refresh()
		except Exception, e:
			self.Hlog( "debug", "DrawSimilarUsers " + str(e) + str(self.scrolling["similar_users" ]))
			self.windows["text"]["similar_users"].refresh()
	
	def DrawHatedInterests(self):
		try:
			mode = "hates"

			self.windows["text"][mode].erase()
			w = self.windows["dimensions"][mode]
			self.logs[mode] = []
			sup = self.scrolling[ mode ]
			if "interests.hate" in self.config.keys():
				for item in self.config["interests.hate"]:
					
					self.logs[mode].append( item)
	
			count = 0
			clipped_list, sup, self.windows["dimensions"][mode]["start"] = self.scrollbox(self.logs[mode], sup, w["height"])
			self.scrolling[mode] = sup
			start = self.windows["dimensions"][mode]["start"]
			for line in clipped_list:
				length = len( line+( " " * (w["width"] - len(line) ) ) )
				if length > w["width"]:
					line = line [:w["width"] - length  ]
				if count + start == sup:
					self.windows["text"][mode].addstr(line + " " * (self.windows["dimensions"]["hates"]["width"] - len(line)), curses.A_BOLD)
				else:
					self.windows["text"][mode].addstr(line + " " * (self.windows["dimensions"]["hates"]["width"] - len(line)))
				count += 1
			self.windows["text"][mode].refresh()
		
		except Exception, e:
			#self.Hlog( "debug", "DrawHatedInterests " + str(e))
			self.windows["text"]["hates"].refresh()
			
	def DrawLikedInterests(self):
		try:
			mode = "likes"
			self.windows["text"][mode].erase()
			w = self.windows["dimensions"][mode]
			self.logs[mode] = []
			sup = self.scrolling[ mode ]
			if "interests.hate" in self.config.keys():
				for item in self.config["interests.like"]:

					self.logs[mode].append( item)
	
			count = 0
			clipped_list, sup, self.windows["dimensions"][mode]["start"] = self.scrollbox(self.logs[mode], sup, w["height"])
			self.scrolling[mode] = sup
			start = self.windows["dimensions"][mode]["start"]
			for line in clipped_list:
				length = len( line+( " " * (w["width"] - len(line) ) ) )
				if length > w["width"]:
					line = line [:w["width"] - length  ]
				if count + start == sup:
					self.windows["text"][mode].addstr(line + " " * (w["width"] - len(line)), curses.A_BOLD)
				else:
					self.windows["text"][mode].addstr(line + " " * (w["width"] - len(line)))
				count += 1
			self.windows["text"][mode].refresh()
		except:
			self.windows["text"][mode].refresh()
			

	def InterestsWindows(self, w, mode):
		try:
			# Cleanup stale windows
			if mode in self.windows["text"]:
				del self.windows["text"][mode]
			if mode in self.windows["border"]:
				del self.windows["border"][mode]
				 
			self.windows["border"][mode] = win = curses.newwin(w["height"]+2, w["width"]+2, w["top"]-1, w["left"]-1)
			if self.display["interests"] == mode:
				win.attron(self.colors["green"])
			win.border()
			if mode == "recommendations":
				title = "Recommendations"
				rs = len(self.Spl["recommend_sort"])
				win.addstr(0, w["width"]-rs-4, "< %s >" % (" "*rs))
				win.addstr(0, w["width"]-rs-2, self.Spl["recommend_sort"].capitalize(),  curses.A_BOLD | self.colors["cyan"])
				win.addstr(w["height"]+1, 1, "<          >")
				win.addstr(w["height"]+1, 3, "PERSONAL",  curses.A_BOLD | self.colors["cyan"])
				win.addstr(w["height"]+1, w["width"]-10, "<        >")
				win.addstr(w["height"]+1, w["width"]-8, "GLOBAL",  curses.A_BOLD | self.colors["cyan"])
			elif mode == "likes":
				title = "Liked"
				if self.Spl["interests_input"] == "add_likes":
					aattr = curses.A_BOLD | self.colors["cyan"]
					dattr = curses.A_NORMAL
				elif self.Spl["interests_input"]  == "del_likes":
					aattr = curses.A_NORMAL
					dattr = curses.A_BOLD | self.colors["cyan"]
				else:
					aattr = curses.A_NORMAL
					dattr = curses.A_NORMAL
				win.addstr(w["height"]+1, 1, "<     >")
				win.addstr(w["height"]+1, 3, "ADD", aattr)
				win.addstr(w["height"]+1, w["width"]-9, "<        >")
				win.addstr(w["height"]+1, w["width"]-7, "DELETE", dattr)
			elif mode == "hates":
				title = "Hated"
				if self.Spl["interests_input"] == "add_hates":
					aattr = curses.A_BOLD | self.colors["cyan"]
					dattr = curses.A_NORMAL
				elif self.Spl["interests_input"]  == "del_hates":
					aattr = curses.A_NORMAL
					dattr = curses.A_BOLD | self.colors["cyan"]
				else:
					aattr = curses.A_NORMAL
					dattr = curses.A_NORMAL
				win.addstr(w["height"]+1, 1, "<     >")
				win.addstr(w["height"]+1, 3, "ADD", aattr)
				win.addstr(w["height"]+1, w["width"]-9, "<        >")
				win.addstr(w["height"]+1, w["width"]-7, "DELETE", dattr)
			elif mode == "similar_users":
				title = "Users"
				win.addstr(w["height"]+1, w["width"]-10, "<         >")
				win.addstr(w["height"]+1, w["width"]-8, "REFRESH",  curses.A_BOLD | self.colors["cyan"])
			
			win.addstr(0, 1, "< %s >" % (" " * len(title)))
			if mode == self.display["interests"]:
				 win.addstr(0, 3, title, curses.A_BOLD | self.colors["green"])
			else:
				 win.addstr(0, 3, title, curses.A_BOLD)
			if self.display["interests"] == mode:
				win.attroff(self.colors["green"])
			win.refresh()
			self.windows["text"][mode] = twin = win.subwin(w["height"], w["width"], w["top"], w["left"])
			
			twin.scrollok(0)
			twin.idlok(1)
	
			

		except Exception, e:
			self.Hlog( "debug", "InterestsWindows: " + str(e))
			
	def DestroyOldWindows(self):
		mode = self.display["mode"]
		if mode == "lists":
			userlist = self.display["list"]
		for window in self.windows["text"]:
			del window
		for window in self.windows["border"]:
			del window
		
	def ModeTrust(self):
		try:
			self.display["list"] = "trusted"
			#self.DestroyOldWindows()
			self.Spl["show_menu"] = False
			
			s = self.windows["dimensions"][self.display["list"]] = {"height": self.h-7, "top": 2, "left": 1, "width": self.w-2, "start": 0}
			self.ListTrust()
			self.DrawListsWindows(self.display["list"])
			
			self.FormatLists(s, "trusted")
			
			self.HotKeyBar()
			curses.doupdate()
		except Exception, e:
			self.Hlog("debug", "ModeTrust: " + str(e))
			
	def ModeBuddy(self):
		try:
			self.display["list"] = "buddied"
			self.Spl["show_menu"] = False
			
			s = self.windows["dimensions"][self.display["list"]] = {"height": self.h-7, "top": 2, "left": 1, "width": self.w-2, "start": 0}
			self.ListBuddy()
			self.DrawListsWindows(self.display["list"])
			
			self.FormatLists(s, "buddied")
			
			self.HotKeyBar()
			curses.doupdate()
		except Exception, e:
			self.Hlog("debug", "ModeBuddy: " + str(e))
			
	def ModeBan(self):
		try:
			self.display["list"] = "banned"
			self.Spl["show_menu"] = False
			
			s = self.windows["dimensions"][self.display["list"]] = {"height": self.h-7, "top": 2, "left": 1, "width": self.w-2, "start": 0}
			self.DrawListsWindows(self.display["list"])
			self.ListBan()
			self.FormatLists(s, "banned")
			self.HotKeyBar()
			curses.doupdate()
		except Exception, e:
			self.Hlog("debug", "ban_mode: " + str(e))
			
	def ModeIgnore(self):
		try:
			self.display["list"] = "ignored"
			self.Spl["show_menu"] = False
			
			s = self.windows["dimensions"][self.display["list"]] = {"height": self.h-7, "top": 2, "left": 1, "width": self.w-2, "start": 0}
			self.DrawListsWindows(self.display["list"])
			
			self.FormatLists(s, "ignored")
			self.HotKeyBar()
			curses.doupdate()
		except Exception, e:
			self.Hlog("debug", "ModeIgnore: " + str(e))
			
	def FormatLists(self, window, mode):
		try:
			if self.logs[mode] != None and self.logs[mode] != []:
				clipped_list, self.scrolling[mode], self.windows["dimensions"][self.display["list"]]["start"] = self.scrollbox(self.logs[mode], self.scrolling[mode], window["height"])
				count = 0 
				try:
					self.windows["border"][self.display["list"]].addstr(self.h-6, self.w-18, "< "+str(len(self.logs[mode]))+" >", self.colors["green"] | curses.A_BOLD)
					self.windows["border"][self.display["list"]].noutrefresh()	
				except:
					pass
				self.windows["text"][self.display["list"]].erase()
				for lines in clipped_list:
					self.DrawLists(lines, count, self.display["list"])
					count += 1
				
				self.windows["text"][self.display["list"]].noutrefresh()
		except Exception, e:
			self.Hlog("debug", "FormatLists: " + str(e))
			
	def SelectLists(self):
		try:
			if self.display["list"]=="buddied":
				this_list = self.logs["buddied"]
			elif self.display["list"]=="banned":
				this_list = self.logs["banned"]
			elif self.display["list"]=="ignored":
				this_list = self.logs["ignored"]
			elif self.display["list"]=="trusted":
				this_list = self.logs["trusted"]
			clipped_list, self.scrolling[self.display["list"]], self.windows["dimensions"][self.display["list"]]["start"] = self.scrollbox(this_list, self.scrolling[self.display["list"]], self.h-7)
			count = 0
			self.windows["text"][self.display["list"]].erase()
			for lines in clipped_list:
				self.DrawLists(lines, count, self.display["list"])
				count += 1
			self.windows["text"][self.display["list"]].refresh()
		except Exception, e:
			self.Hlog("debug", "SelectLists: " + str(e))
			
	def ModeLists(self):
		self.display["mode"] = "lists"
		self.Spl["show_menu"] = False
		if self.display["list"] == "buddied":
			self.ModeBuddy()
		elif self.display["list"] == "banned":
			self.ModeBan()
		elif self.display["list"] == "ignored":
			self.ModeIgnore()
		elif self.display["list"] == "trusted":
			self.ModeTrust()	
		elif self.display["list"] == "interests":
			self.ModeInterests()	
			
	def ModeRoomsList(self):
		try:
			self.display["mode"] = "roomlist"
			self.Spl["show_menu"] = False
			
			s = self.windows["dimensions"]["roomlist"] = {"height": self.h-7, "top": 2, "left": 1, "width": self.w-2}
			self.DrawListsWindows("roomlist")
			
			self.sizedrooms = []
			alpharooms = []
			
			if mucous_config["mucous"]["rooms_sort"]  in ("alpha", "alpha-reversed"):
				for rooms in self.data["roomlist"].keys():
					alpharooms.append(rooms)
				alpharooms.sort(key=str.lower)
				if mucous_config["mucous"]["rooms_sort"] =="alpha-reversed":
					alpharooms.reverse()
					
			elif mucous_config["mucous"]["rooms_sort"] in ("size", "size-reversed"):
				bigsizes = []
				bigsizes=self.sortbyvalue (self.data["roomlist"])
				if mucous_config["mucous"]["rooms_sort"] == "size":
					bigsizes.reverse()
				for rooms, sizes in bigsizes:
					alpharooms.append(rooms)
			
			for rooms9 in alpharooms:
				if self.data["roomlist"][rooms9] >= mucous_config["mucous"]["roomlistminsize"]:
					self.sizedrooms.append(rooms9)
					
			self.FormatRoomsList()
			
			self.HotKeyBar()
			curses.doupdate()
		except Exception, e:
			self.Hlog("debug", "ModeRoomsList: " + str(e))
		
		
	def DrawRoomsList(self, roomitem, count, start):
		try:
			
			if count + start == self.scrolling["roomlist"]:
				attrib =  curses.A_BOLD | curses.A_REVERSE
			else:
				attrib = curses.A_NORMAL
			num = str(self.data["roomlist"][roomitem])
			while len(num) < 8:
				num += " "
			string = num + self.dlang(roomitem)
			if len(string) < self.w-2:
				spaces = " " * (self.w-2 - len(string))
			else:
				string = string[:self.w-2]
				spaces = ''
			self.windows["text"]["roomlist"].addstr(string+spaces, attrib)
			
		except Exception, e:
	
			pass
			
	def sortbyvalue(self, dict):
		try:
			""" Return a list of (key, value) pairs, sorted by value. """
			_swap2 = lambda (x,y): (y,x)
			mdict = map(_swap2, dict.items())
			mdict.sort()
			mdict = map(_swap2, mdict)
			return mdict
		except Exception, e:
			self.Hlog("debug", "sortbyvalue: " + str(e))
			
	def FormatRoomsList(self):
		try:
			self.windows["text"]["roomlist"].erase()
			clipped_list, self.scrolling["roomlist"], self.windows["dimensions"]["roomlist"]["start"] = self.scrollbox(self.sizedrooms, self.scrolling["roomlist"], self.h-7)
			count =0 
			for rooms10 in clipped_list:
				self.DrawRoomsList(rooms10, count, self.windows["dimensions"]["roomlist"]["start"])
				count += 1
			self.windows["text"]["roomlist"].refresh()
		except Exception, e:
			self.Hlog("debug", "FormatRoomsList: " + str(e))
				

	def ModeSetupDefault(self):
		try:
			self.Spl["setup_input"] = "default"
			self.ModeSetup()
		except Exception, e:
			self.Hlog("debug", "ModeSetupDefault: "+ str(e))
			
	def SetupButton(self, title, option, x, y, height, width, optionbold=False, titlepad=True, border=True):
		try:
			winborder = curses.newwin(height,width,x,y)
			if border:
				winborder.border()
			if title != None:
				if titlepad:
					winborder.addstr(0,1, "< %s >" % title, curses.A_BOLD)
				else:
					winborder.addstr(0,1, title, curses.A_BOLD)
			winborder.noutrefresh()
			win = winborder.subwin(height-2,width-2,x+1,y+1)
			win.scrollok(1)
			if option != None:
				if optionbold:
					win.addstr(option, self.colors["cyan"] | curses.A_BOLD)
				else:
					win.addstr(option, self.colors["cyan"])
			win.noutrefresh()
			del win
			del winborder
		except Exception,e:
			self.Hlog("debug", "SetupButton: "+title+" "+ str(e))
			
	def SetupCheck(self, title, option, x, y, height, width, titlebold=False, toggle=False):
		try:
			enabled = "[x]"
			disabled = "[ ]"
			selected = "(*)"
			notselected = "( )"
			
			win = curses.newwin(height,width,x,y)
			win.erase()
			if option in ("True", "true", "yes"):
				if toggle:
					z = selected
				else:
					z = enabled
			else:
				if toggle:
					z = notselected
				else:
					z = disabled
			win.addstr(z+" ", self.colors["cyan"])
			if title != None:
				if titlebold:
					win.addstr(title,  curses.A_BOLD)
				else:
					win.addstr(title)
			win.noutrefresh()
			
			del win

		except Exception,e:
			self.Hlog("debug", "SetupButton: "+title+" "+ str(e))
			
	def ModeSetup(self):
		
		self.display["mode"] = "setup"
		self.Spl["show_menu"] = False
		try:
			# Cleanup stale windows
			if "setup" in self.windows["border"]:
				del self.windows["border"]["setup"]
				
			w = self.windows["dimensions"]["setup"] = {"height": self.h-5, "width": self.w, "top": 1, "left": 0}	
			mw = self.windows["border"]["setup"] = curses.newwin(w["height"], w["width"], w["top"], w["left"])
			mw.erase()
			mw.border()
			mw.addstr(w["height"]-1, 2, "< Use the mouse, if possible. Otherwise: /help setup >")

			if self.display["setup"] == "mucous":
				self.set_edit_title("Mucous Setup")
				try:
					mw.addstr(0, 1, "< Mucous >",  curses.A_BOLD)
					mw.addstr(0, 15, "< Museek >")
					mw.addstr(0, 30, "< Shares >")
					mw.addstr(0, 45, "< Userinfo >")
					mw.addstr(0, 60, "< Logs >")
				except:
					pass
			elif self.display["setup"] == "museek":
				try:
					mw.addstr(0, 1, "< Mucous >")
					mw.addstr(0, 15, "< Museek >",  curses.A_BOLD)
					mw.addstr(0, 30, "< Shares >")
					mw.addstr(0, 45, "< Userinfo >")
					mw.addstr(0, 60, "< Logs >")
				except:
					pass
			elif self.display["setup"] == "shares":
				try:
					mw.addstr(0, 1, "< Mucous >")
					mw.addstr(0, 15, "< Museek >")
					mw.addstr(0, 30, "< Shares >",  curses.A_BOLD)
					mw.addstr(0, 45, "< Userinfo >")
					mw.addstr(0, 60, "< Logs >")
				except:
					pass
			elif self.display["setup"] == "userinfo":
				try:
					mw.addstr(0, 1, "< Mucous >")
					mw.addstr(0, 15, "< Museek >")
					mw.addstr(0, 30, "< Shares >")
					mw.addstr(0, 45, "< Userinfo >",  curses.A_BOLD)
					mw.addstr(0, 60, "< Logs >")
				except:
					pass
			elif self.display["setup"] == "logs":
				try:
					mw.addstr(0, 1, "< Mucous >")
					mw.addstr(0, 15, "< Museek >")
					mw.addstr(0, 30, "< Shares >")
					mw.addstr(0, 45, "< Userinfo >")
					mw.addstr(0, 60, "< Logs >",  curses.A_BOLD)
				except:
					pass
			si = self.Spl["setup_input"]
			if si == "default":
				self.set_edit_title("Setup Mode")
			elif si == "interface":
				self.set_edit_title("Set Interface")
			elif si == "custom-url":
				self.set_edit_title("Set custom URL handler: command$command")
			elif si == "interface-password":
				self.set_edit_title("Set Mucous's Interface password")
			elif si == "museek-interface-password":
				self.set_edit_title("Set Museek's Interface password")
			elif si == "museek-interface-bind":
				self.set_edit_title("Add a Museek Interface")
			elif si == "server-host":
				self.set_edit_title("Set Server Address")
			elif si == "server-port":
				self.set_edit_title("Set Server Port")
			elif si == "soulseek-username":
				self.set_edit_title("Set Soulseek Username")
			elif si == "soulseek-password":
				self.set_edit_title("Set Soulseek Password")
			elif si == "slots":
				self.set_edit_title("Set Number of Upload Slots to:")
			elif si == "download-dir":
				self.set_edit_title("Set completed download directory")
			elif si == "incomplete-dir":
				self.set_edit_title("Set incompleted download directory")
			elif si == "userinfo":
				self.set_edit_title("Set UserInfo")
			elif si == "userimage":
				self.set_edit_title("Set UserImage")
			elif si == "adddir":
				self.set_edit_title("Add directory to your normal shares")
			elif si == "rmdir":
				self.set_edit_title("Remove directory from your normal shares")
			elif si == "addbuddydir":
				self.set_edit_title("Add directory to your buddy shares")
			elif si == "rmbuddydir":
				self.set_edit_title("Remove directory from your buddy shares")
			mw.noutrefresh()
			# Create buttons, settings and immediately Delete them to aviod leaks
			if self.display["setup"] in ("shares"):
				# First Row
				self.SetupButton("Normal", "List Shared", 3,1,3,16)
				self.SetupButton(None, "Add Directory", 3,17,3,16)
				self.SetupButton(None, "Remove Dir", 3,33,3,16)
				self.SetupButton(None, "Click on the buttons to run the local muscan.\nWhen you click on Add/Remove Directory, type in the directory below, and start with '//' instead of just a '/'", 2,49,10,self.w-50)
				# Second Row
				self.SetupButton(None, "Rescan Shares",6,1,3,16)
				self.SetupButton(None, "Update Shares", 6,17,3,16)
				
				# Third Row
				self.SetupButton("Buddy-only", "List Shared", 9,1,3,16)
				self.SetupButton(None, "Add Directory", 9,17,3,16)
				self.SetupButton(None, "Remove Dir", 9,33,3,16)
				
				# Fourth Row
				self.SetupButton(None, "Rescan Shares", 12,1,3,16)
				self.SetupButton(None, "Update Shares", 12,17,3,16)
				self.SetupButton(None, "Reload Shares", 12,49,3,16, optionbold=True)
				
				museekconfigfile = self.Spl["museekconfigfile"]
				# Fifth Row
				self.SetupButton("Museek Config File", museekconfigfile[:self.w-2], 15,1,3,self.w-2)
			elif self.display["setup"] in ("userinfo"):
				info = ""
				if "userinfo" in self.config.keys():
					if "text" in self.config["userinfo"]:
						info = self.config["userinfo"]["text"]
						#for line in self.config["userinfo"]["text"]:
							#info += line.decode(mucous_config["mucous"]["language"], "replace") +"\n"
				
				self.SetupButton("Your Userinfo", info, 2,1,self.h-8,self.w-2)
				
				inputimage = curses.newwin(1,13,self.h-6,1)
				inputimage.erase()
				inputimage.addstr( "Your Image: ")
				inputimage.noutrefresh()
				
				if "userinfo" in self.config.keys():
					if "image" in self.config["userinfo"]:
						inputimage2 = curses.newwin(1,self.w-2-14,self.h-6,14)
						inputimage2.erase()
						inputimage2.scrollok(1)
						inputimage2.addstr( str(self.config["userinfo"]["image"][:self.w-3-14]))
						inputimage2.noutrefresh()
				del inputimage2
				del inputimage
			elif self.display["setup"] in ("logs"):
				self.SetupCheck("Log Chat messages? ", mucous_config["mucous"]["logging"],2,1,1,30, True)
				
				self.SetupButton("Log Directory", os.path.expanduser(mucous_config["mucous"]["log_dir"])[:37], 5,1,3,self.w-2)
				

			elif self.display["setup"] == "mucous":
				# Interface
				interface =""
				if "connection" in mucous_config:
					interface = self.dlang( mucous_config["connection"]["interface"][:28] )
				
				self.SetupButton("Museek Interface", interface ,2,1, 3,32)
				
				
				if "connection" in mucous_config:
					if self.display["password"]=="yes":
						password = self.dlang( str(mucous_config["connection"]["passw"]) )
					else:
						password = '*********'
				else:
					password = "NOT set"
					
				self.SetupButton("Interface Password", password, 5,1,3,32)
				
				bwin = curses.newwin(6,22,2,33)
				bwin.border()
				try:
					bwin.addstr(0, 1, "< Stats >",  curses.A_BOLD)
				except:
					pass
				bwin.noutrefresh()
				inbwin1_1 = bwin.subwin(1,20,3,34)
				inbwin1_2 = bwin.subwin(1,20,4,34)
				inbwin1_3 = bwin.subwin(1,20,5,34)
				inbwin1_4 = bwin.subwin(1,20,6,34)
				inbwin1_1.scrollok(1)
				inbwin1_2.scrollok(1)
				inbwin1_3.scrollok(1)
				inbwin1_4.scrollok(1)
				if self.data["mystats"] != []:
					try:
						inbwin1_1.addstr("Files: "+str(self.data["mystats"][3]), self.colors["cyan"] )
						inbwin1_2.addstr("Dirs: "+str(self.data["mystats"][4]), self.colors["cyan"] )
						inbwin1_3.addstr("Downloads: "+str(self.data["mystats"][2]), self.colors["cyan"] )
						inbwin1_4.addstr("Speed: "+str(self.data["mystats"][1]/1024)+"KB/s", self.colors["cyan"] )
						#self.data["mystats"] = user,  avgspeed, numdownloads, numfiles, numdirs
					except:
						pass
				else:
					if self.usernames["username"] != None:
						self.SendMessage(messages.PeerStats(self.usernames["username"]))
				inbwin1_1.noutrefresh()
				inbwin1_2.noutrefresh()
				inbwin1_3.noutrefresh()
				inbwin1_4.noutrefresh()
				del inbwin1_1
				del inbwin1_2
				del inbwin1_3
				del inbwin1_4 
				del bwin
				
				self.SetupCheck("Show Tickers:         /showtickers", mucous_config["tickers"]["tickers_enabled"] ,8,1,1,45, True)

				self.SetupCheck("Cycle Tickers:        /tickers", mucous_config["tickers"]["ticker_cycle"] ,9,1,1,45, True, True)
				self.SetupCheck("Scroll Tickers:       /tickers", mucous_config["tickers"]["ticker_scroll"] ,10,1,1,45, True, True)
				self.SetupCheck("Auto-clear Transfers: /autoclear", mucous_config["mucous"]["auto-clear"],11,1,1,45, True)

				self.SetupCheck("Auto-retry Transfers: /autoretry", mucous_config["mucous"]["auto-retry"],12,1, 1,45, True)

				self.SetupCheck("Auto-Buddy downloads: /autobuddy", mucous_config["mucous"]["autobuddy"],13,1,1,45, True)
				
				self.SetupCheck("Beep:                 /beep", mucous_config["mucous"]["beep"],14,1,1,45, True)
				self.SetupButton("< Ticker Time >", " -  %.2f +\n -  %.2f +" % ( float(mucous_config["tickers"]["cycletime"]), float(mucous_config["tickers"]["scrolltime"])), 8,39, 4,16, False, False)
				# Minimum Room size for Roomlist
				
				self.SetupButton("<Min Roomlist>", " -  "+str(mucous_config["mucous"]["roomlistminsize"])+" +", 8,55, 3,16, False, False)

				self.SetupButton("Encoding", mucous_config["mucous"]["language"], 12,39,3,16)
				
				# Custom URL
				prefix =""
				if "url custom prefix" in mucous_config["mucous"] and "url custom suffix" in mucous_config["mucous"]:
					prefix = self.dlang(mucous_config["mucous"]["url custom prefix"])+"$"+self.dlang(mucous_config["mucous"]["url custom suffix"])
				self.SetupButton("Custom URL Reader", prefix,15,1,3,32, optionbold=True)
				self.SetupButton("URL Reader", self.dlang(mucous_config["mucous"]["url reader"]), 15,33,3,16)


				# Save button
				self.SetupButton(None, " Save Config", 15,49,3,16, True)
				



			elif self.display["setup"] == "museek":
				# Server
				bw = curses.newwin(5,38,2,1)
				bw.border()
				bw.addstr(0, 1, "< Server >",  curses.A_BOLD)
					
				bw.noutrefresh()
				inbw = bw.subwin(1,36,3,2)
				inbw.scrollok(1)
				inbw.addstr("Host: ")
				if "server" in self.config:
					try:
						inbw.addstr(self.dlang( self.config["server"]["host"][:22] )+":"+self.config["server"]["port"], self.colors["cyan"] )
					except:
						pass
				inbw.noutrefresh()
				del inbw
				
	
				
				inusernamewin2 = bw.subwin(1,36,4,2)
				inusernamewin2.scrollok(1)
				inusernamewin2.addstr("Name: ")
				if "server" in self.config:
					a = self.dlang(self.config["server"]["username"])
					try:
						inusernamewin2.addstr(a, self.colors["cyan"])
					except:
						pass

				inusernamewin2.noutrefresh()
				del inusernamewin2

				inifacepasswin = bw.subwin(1,36,5,2)
				inifacepasswin.addstr("Pass: ")
				if self.display["password"]=="yes":
					if "server" in self.config:
						inifacepasswin.addstr(self.dlang( self.config["server"]["password"] ), self.colors["cyan"])
						
				else:
					if "server" in self.config:
						inifacepasswin.addstr("*********", self.colors["cyan"])
				inifacepasswin.noutrefresh()
				del inifacepasswin
				del bw
	
				ifacepasswin = curses.newwin(3,26,2,39)
				ifacepasswin.border()
				ifacepasswin.addstr(0, 1, "< Interface Password >",  curses.A_BOLD)

				ifacepasswin.noutrefresh()
				inifacepasswin = ifacepasswin.subwin(1,24,3,40)
				inifacepasswin.scrollok(1)
				if "interfaces" in self.config:
					if self.display["password"]=="yes":
						try:
							inifacepasswin.addstr(self.dlang( self.config["interfaces"]["password"] ), self.colors["cyan"])
						except:
							pass
					else:
						inifacepasswin.addstr("*********", self.colors["cyan"])
				inifacepasswin.noutrefresh()
				del inifacepasswin

				#------------------------

				self.SetupCheck("Share to Buddies-Only", self.config["transfers"]["only_buddies"],8,1,1,30, True)

				self.SetupCheck("Buddies get Privileges", self.config["transfers"]["privilege_buddies"],9,1,1,30, True)

				self.SetupCheck("Enable Buddy-Only shares",self.config["transfers"]["have_buddy_shares"],10,1,1,30, True)

				self.SetupCheck("Allow Trusted users to send you files",self.config["transfers"]["trusting_uploads"],11,1,1,self.w-3, True)

				self.SetupCheck("Send automatic warnings via Private Chat",self.config["transfers"]["user_warnings"],12,1,1,self.w-3, True)

				self.SetupButton("<Connections >", self.config["clients"]["connectmode"],5,49,3,16, True, False)

				self.SetupButton("<Upload Slots>", " - " + self.config["transfers"]["upload_slots"]+ " +", 8,49,3,16, True, False)

				dirwin = curses.newwin(4,self.w-2,13,1)
				dirwin.border()
				dirwin.addstr(0, 1, "< Download/Incomplete Directories >",  curses.A_BOLD)
				dirwin.noutrefresh()
				dircompletewin = dirwin.subwin(1,self.w-4,14,2)
				try:
					dircompletewin.addstr(self.dlang(self.config["transfers"]["download-dir"]), self.colors["cyan"])
				except: pass
				dircompletewin.noutrefresh()
				dirincompletewin = dirwin.subwin(1,self.w-4,15,2)
				try:
					dirincompletewin.addstr(self.dlang(self.config["transfers"]["incomplete-dir"]), self.colors["cyan"])
				except: pass
				dirincompletewin.noutrefresh()
				del dirincompletewin
				del dircompletewin
				del dirwin
				

		except Exception, e:
			self.Hlog("debug", "ModeSetup: " + str(e) )
		self.ModeTopbar()
		self.HotKeyBar()
		curses.doupdate()
	# TOPBAR MODE
	
	
	def ModeTopbar(self):
		try:
			# Clean stale windows
			if "top" in self.windows["border"]:
				del self.windows["border"]["top"]
			if "onlinestatus" in self.windows["border"]:
				del self.windows["border"]["onlinestatus"]
			if "uploadstatus" in self.windows["border"]:
				del self.windows["border"]["uploadstatus"]
			if "downloadstatus" in self.windows["border"]:
				del self.windows["border"]["downloadstatus"]
			if "searchstatus" in self.windows["border"]:
				del self.windows["border"]["searchstatus"]
			if "alert" in self.windows["border"]:
				del self.windows["border"]["alert"]
			if "username" in self.windows["border"]:
				del self.windows["border"]["username"]
				
			tb = self.windows["border"]["top"] =   curses.newwin(1, self.w, 0, 0)
			tb.bkgdset(" ", self.colors["blafgcyabg"]  | curses.A_REVERSE | curses.A_BOLD)
			tb.idlok(1)
			tb.erase()
			tb.noutrefresh()
							
			osw = self.windows["border"]["onlinestatus"]  =  curses.newwin(1, 8, 0, 0)
			osw.bkgdset(" ", self.colors["blafgcyabg"]  |curses.A_REVERSE | curses.A_BOLD)
			osw.idlok(1)
			try:
				osw.erase()
				osw.addstr(self.logs["onlinestatus"],  self.colors["blafgcyabg"] )
			except:
				pass
			osw.noutrefresh()
			
			usw = self.windows["border"]["uploadstatus"]  = curses.newwin(1, 10, 0, 25)
			usw.bkgdset(" ", self.colors["blafgcyabg"]  | curses.A_REVERSE | curses.A_BOLD)
			usw.idlok(1)
			try:
				usw.erase()
				usw.addstr(self.logs["uploads"],  self.colors["blafgcyabg"] )
			except:
				pass
			usw.noutrefresh()
			
			dsw = self.windows["border"]["downloadstatus"] = curses.newwin(1, 12, 0, 35)
			dsw.bkgdset(" ", self.colors["blafgcyabg"]  | curses.A_REVERSE | curses.A_BOLD)
			dsw.idlok(1)
			try:
				dsw.erase()
				dsw.addstr(self.logs["downloads"],  self.colors["blafgcyabg"] )
			except:
				pass
			dsw.noutrefresh()
			
		
			ssw = self.windows["border"]["searchstatus"] = curses.newwin(1, 15, 0, 47)
			ssw.bkgdset(" ", self.colors["blafgcyabg"]  | curses.A_REVERSE | curses.A_BOLD)
			ssw.idlok(1)
			try:
				ssw.erase()
				ssw.addstr(self.logs["search_count"][0],  self.colors["blafgcyabg"] )
				ssw.addstr(str(self.logs["search_count"][1]),  self.colors["blafgcyabg"] )
			except:
				pass
			ssw.noutrefresh()
		
		
			aw = self.windows["border"]["alert"] = curses.newwin(1, 15, 0, self.w-15)
			aw.bkgdset(" ", self.colors["blafgcyabg"]  | curses.A_REVERSE | curses.A_BOLD)
			aw.idlok(1)
			
			self.AlertStatus(self.logs["alert"])
			un = self.windows["border"]["username"] =  curses.newwin(1, 16, 0, 9)
			un.idlok(1)
			un.bkgdset(" ", self.colors["blafgcyabg"]  | curses.A_REVERSE | curses.A_BOLD)
			
			if self.usernames["username"] != None:
				try:
					un.erase()
					un.addstr(self.dlang(self.usernames["username"][:15]),  self.colors["blafgcyabg"] )
				except:
					pass
			un.noutrefresh()
		
		except Exception,e :
			self.Hlog("debug", "topbar mode" + str(e))

		
	def HotKeyBar(self):
		try:
			# Clean stale windows
			if "bottom" in self.windows["border"]:
			 	del self.windows["border"]["bottom"]
				
			bb = self.windows["border"]["bottom"] = curses.newwin(1, self.w-1, self.h-1, 0)
			bb.addstr(" 1",  curses.A_BOLD)
			if self.display["mode"] == "chat":
				if self.alert["CHAT"] != {}:
					nick = 0
					for room, status in self.alert["CHAT"].items():
						if status == "nick":
							nick = 1
					if nick == 1:
						bb.addstr("Chat", self.colors["red"] |curses.A_BOLD |curses.A_REVERSE )
					else:
						bb.addstr("Chat", self.colors["yellow"] |curses.A_BOLD |curses.A_REVERSE )
				else:
					bb.addstr("Chat",  curses.A_REVERSE |  self.colors["greenbg"])
			else:
				if self.alert["CHAT"] != {}:
					nick = 0
					for room, status in self.alert["CHAT"].items():
						if status == "nick":
							nick = 1
					if nick == 1:
						bb.addstr("Chat", self.colors["red"] | curses.A_REVERSE )
					else:
						bb.addstr("Chat", self.colors["yellow"] | curses.A_REVERSE )
				else:
					bb.addstr("Chat",  self.colors["cybg"])
			bb.addstr(" 2",  curses.A_BOLD)
			if self.display["mode"] == "private":
				if self.alert["PRIVATE"] != []:
					bb.addstr("Private", self.colors["yellow"] |curses.A_BOLD |curses.A_REVERSE )
				else:
					bb.addstr("Private",curses.A_REVERSE |  self.colors["greenbg"])
			else:
				if self.alert["PRIVATE"] != []:
					bb.addstr("Private", self.colors["yellow"] |curses.A_REVERSE )
				else:
					bb.addstr("Private", self.colors["cybg"])
			bb.addstr(" 3",   curses.A_BOLD)
			if self.display["mode"] == "transfer":
				bb.addstr("Transfers",curses.A_REVERSE |  self.colors["greenbg"])
			else:
				bb.addstr("Transfers", self.colors["cybg"])
			
			bb.addstr(" 4",  curses.A_BOLD)
			if self.display["mode"] == "search":
				if self.alert["SEARCH"] != []:
					bb.addstr("Search", self.colors["yellow"] |curses.A_REVERSE |curses.A_BOLD)
				else:
					bb.addstr("Search",curses.A_REVERSE |  self.colors["greenbg"])
			else:
				if self.alert["SEARCH"] != []:
					bb.addstr("Search", self.colors["yellow"] |curses.A_REVERSE )
				else:
					bb.addstr("Search", self.colors["cybg"])
			bb.addstr(" 5",  curses.A_BOLD)
			if self.display["mode"] == "info":
				if self.alert["INFO"] != []:
					bb.addstr("Info", self.colors["yellow"] |curses.A_REVERSE |curses.A_BOLD)
				else:
					bb.addstr("Info",curses.A_REVERSE |  self.colors["greenbg"])
			else:
				if self.alert["INFO"] != []:
					bb.addstr("Info", self.colors["yellow"] |curses.A_REVERSE )
				else:
					bb.addstr("Info", self.colors["cybg"])
			bb.addstr(" 6",  curses.A_BOLD)
			if self.display["mode"] == "browse":
				if self.alert["BROWSE"] != []:
					bb.addstr("Browse", self.colors["yellow"] |curses.A_REVERSE |curses.A_BOLD)
				else:
					bb.addstr("Browse",curses.A_REVERSE |  self.colors["greenbg"])
			else:
				if self.alert["BROWSE"] != []:
					bb.addstr("Browse", self.colors["yellow"] |curses.A_REVERSE)
				else:
					bb.addstr("Browse", self.colors["cybg"])
	
			bb.addstr(" 7",  curses.A_BOLD)
			if self.display["mode"] == "lists":
				bb.addstr("Users",curses.A_REVERSE |  self.colors["greenbg"])
			else:
				bb.addstr("Users",  self.colors["cybg"])
	
			bb.addstr(" 8",  curses.A_BOLD)
			if self.display["mode"] == "roomlist":
				bb.addstr("Rooms",curses.A_REVERSE |  self.colors["greenbg"])
			else:
				bb.addstr("Rooms", self.colors["cybg"])
	
			bb.addstr(" 9",  curses.A_BOLD)
			if self.display["mode"] == "setup":
				bb.addstr("Setup",curses.A_REVERSE |  self.colors["greenbg"])
			else:
				bb.addstr("Setup",  self.colors["cybg"])
			bb.addstr(" 10",  curses.A_BOLD)
			if self.display["mode"] in ("debug", "help", "status"):
				if self.alert["HELP"] != []:
					bb.addstr("Help", self.colors["yellow"] |curses.A_BOLD |curses.A_REVERSE )
				else:
					bb.addstr("Help",curses.A_REVERSE |  self.colors["greenbg"])
			else:
				if self.alert["HELP"] != []:
					bb.addstr("Help", self.colors["yellow"] | curses.A_REVERSE )
				else:
					bb.addstr("Help",  self.colors["cybg"])
		except:
			pass
		bb.noutrefresh()

	# ---^  MODES ^
		
	# --- TEXT PLACEMENT v
	def FileLog(self, messagetype, timestamp, place, message):
		try:
			if '/' in place:
				place = place.replace("/", "\\")
			path = os.path.join(os.path.expanduser(mucous_config["mucous"]["log_dir"]), messagetype, place)
			dir = os.path.split(path)[0]
			try:
				if not os.path.isdir(dir):
					os.makedirs(dir)
				f = open(path, "a")
				message.replace("\n","\\n")
				f.write("%s %s\n" % (timestamp, message))
				f.close()
			except:
				self.Hlog("status", "Cannot write to file %s, check permissions" % path)
		except Exception, e:
			self.Hlog("debug", "FileLog: " + str(e))
			
	def PrivateChatStart(self, user):
		try:
			self.usernames["private"] = user
			if user not in self.logs["private"].keys():
				self.logs["private"][user] = []
				if mucous_config["mucous"]["logging"] in ("yes"):
					self.PrivateChatOldLogs(user)
				
			if self.display["mode"] == 'private':
				self.ModePrivate()
		except Exception, e:
			self.Hlog("debug", "PrivateChatStart: " + str(e))
			
	def LogPrivateChat(self, direction, user, message):
		try:
			timestamp = time.strftime("%H:%M:%S")
			if user not in self.logs["private"].keys():
				self.logs["private"][user]=['']
	
			if message[:4] == "/me ":
				if direction:
					self.logs["private"][user].append([timestamp, self.usernames["username"],  message])
				else:
					self.logs["private"][user].append([timestamp, user, message])
			else:
				
				if direction:
					self.logs["private"][user].append([timestamp, self.usernames["username"], message])
				else:
					self.logs["private"][user].append([timestamp, user, message])
					
			if self.usernames["private"] == None:
				self.usernames["private"] = user
				if self.display["mode"] == "private":
					self.ModePrivate()
			elif self.usernames["private"] == user:
				if self.display["mode"] == "private":
					self.ModePrivate()
			elif self.usernames["private"] != user and self.usernames["private"] != None:
				self.AlertStatus("PM: "+user)
				
		except Exception, e:
			self.Hlog( "debug", "LogPrivateChat: " + str(e))
				
	def LogInfo(self, s):
		try:
			s= self.dlang(s)
			if "\n" in s:
				lis = s.split("\n")
				for line in lis:
					self.infolog.append("%s" % line)
			else:
				self.infolog.append("%s" % s)
			if self.display["mode"] == "info" and self.usernames["info"] == None:
				self.DrawUserInfoText()
		except Exception, e:
			self.Hlog("debug", "LogInfo: " + str(e))


	def LogChatRoomStatus(self, user, room, did, what):
		try:

			yes = 0
			
			
			if room not in self.logs["roomstatus"]:
				self.logs["roomstatus"][room] = []
			oldlen = len(self.logs["roomstatus"][room])
			if did == "ticker" and what != '':
				if user in self.data["rooms"][room]:
					if room == self.Spl["room"]:
						yes =1
						
			elif did == "join":
				self.logs["roomstatus"][room].append("%s %s joined" % (time.strftime("%H:%M:%S"), user))
				if room == self.Spl["room"]:
					yes =1
					
			elif did == "left":
				self.logs["roomstatus"][room].append("%s %s left" % (time.strftime("%H:%M:%S"), user))
				if room == self.Spl["room"]:
					yes =1
			elif did == "change":
				for rooms11 in self.data["rooms"].keys():
					if user in self.data["rooms"][rooms11]:
						string = "%s %s is %s" % (time.strftime("%H:%M:%S"), user, what)
						if self.logs["roomstatus"][rooms11] == []:
							self.logs["roomstatus"][rooms11].append(string)
							if rooms11 == self.Spl["room"]:
								yes =1
						elif string[10:] != self.logs["roomstatus"][rooms11][-1][10:]:
							self.logs["roomstatus"][rooms11].append(string)
							if rooms11 == self.Spl["room"]:
								yes = 1
								
			if "roomstatus" not in self.windows["text"]:
				return			
			tw = self.windows["text"]["roomstatus"]
			if self.display["mode"] == "chat" and yes == 1:
				if self.scrolling["roomstatus"] >= oldlen -1:
					if len(self.logs["roomstatus"][room]) > 305:
						del self.logs["roomstatus"][room][0]
					self.scrolling["roomstatus"] = -1
					self.DrawChatRoomStatusText()

		except Exception, e:
			self.Hlog("debug", "LogChatRoomStatus: " + str(e))

	def DrawSearchCount(self, s):
		try:
			if self.logs["search_count"] != ["Results: ", s]:
				self.logs["search_count"] = "Results: ", s
				ssw = self.windows["border"]["searchstatus"]
				try:
					ssw.erase()
					ssw.addstr(self.logs["search_count"][0],  self.colors["blafgcyabg"] )
					ssw.addstr(str(self.logs["search_count"][1]),  self.colors["blafgcyabg"] )
					ssw.refresh()
				except Exception, e:
					self.Hlog( "debug", "Search Status: " + str(e))
		except Exception, e:
			self.Hlog("debug", "DrawSearchCount: " + str(e))
		
	def DrawUploadCount(self, s):
		try:
			if self.logs["uploads"] != "Up: %s" %str(s):
				self.logs["uploads"] = "Up: %s" %str(s)
				usw = self.windows["border"]["uploadstatus"]
				try:
					usw.erase()
					usw.addstr(self.logs["uploads"], self.colors["blafgcyabg"] )
					usw.refresh()
				except Exception, e:
					self.Hlog( "debug", "Upload Status: " + str(e))
		except Exception, e:
			self.Hlog("debug", "DrawUploadCount: " + str(e))
		
	def DrawDownloadCount(self, s):
		try:
			if self.logs["downloads"] != "Down: %s" %str(s):
				self.logs["downloads"] = "Down: %s" %str(s)
				dsw = self.windows["border"]["downloadstatus"]
				try:
					dsw.erase()
					dsw.addstr(self.logs["downloads"], self.colors["blafgcyabg"] )
					dsw.refresh()
				except Exception, e:
					self.Hlog( "debug", "Download Status: " + str(e))
		except Exception, e:
			self.Hlog("debug", "DrawDownloadCount: " + str(e))

	def AlertCheck(self):
		try:
			if self.display["mode"] == "chat":
				if self.Spl["room"] in self.alert["CHAT"].keys():
					del self.alert["CHAT"][self.Spl["room"]]
			elif self.display["mode"] == "private":
				if self.usernames["private"] in self.alert["PRIVATE"]:
					self.alert["PRIVATE"].remove(self.usernames["private"])
			elif self.display["mode"] == "browse":
				if self.usernames["browse"] in self.alert["BROWSE"] and self.usernames["browse"] != "__default":
					self.alert["BROWSE"].remove(self.usernames["browse"])
			elif self.display["mode"] == "search":
				if self.Spl["current_search"] in self.alert["SEARCH"]:
					self.alert["SEARCH"].remove(self.Spl["current_search"])
			elif self.display["mode"] == "info":
				if self.usernames["info"] in self.alert["INFO"]:
					self.alert["INFO"].remove(self.usernames["info"])
			elif self.display["mode"] in ("help", "debug", "status"):
				#if ("debug", "help", "status") in self.alert["HELP"]:
				self.alert["HELP"] = []
			self.AlertNext()
			self.HotKeyBar()
		except Exception, e:
			self.Hlog("debug", "AlertCheck: " + str(e))

	def AlertNext(self):
		try:
			if self.display["mode"] ==  "search":
				if self.alert[self.display["mode"].upper()] != []:
					for s in self.alert[self.display["mode"].upper()]:
						self.AlertStatus(self.data["search_tickets"][s])
						return
				else:
					self.AlertPick()
			if self.display["mode"] in ("info", "private",  "browse"):
			#if self.display["mode"].upper() in ("PRIVATE", "TRANSFERS",  "SEARCH", "INFO", "BROWSE"):
			
				if self.alert[self.display["mode"].upper()] != []:
					for s in self.alert[self.display["mode"].upper()]:
						self.AlertStatus(s)
						return
				else:
					self.AlertPick()
			elif self.display["mode"].upper()  == "CHAT":
				if self.alert[self.display["mode"].upper()] != {}:
					for m, l in self.alert["CHAT"].items():
						self.AlertStatus(m)
						return
					self.AlertStatus("")
				else:
					self.AlertPick()
			elif self.display["mode"] in ("help", "debug", "status"):
				for s in self.alert["HELP"]:
					if s == "help":
						self.AlertStatus("New Help")
					elif s == "debug":
						self.AlertStatus("New Bug")
					elif s == "status":	
						self.AlertStatus("New Status")
					break
				else:
					self.AlertPick()
			else:
				self.AlertPick()
		except Exception, e:
			self.Hlog( "debug", "AlertNext: " + str(e))
			
	def AlertPick(self):
		try:
			for mode, lists in self.alert.items():
				#self.helplog.append(str(mode)+" " +str(l))
				if lists == []:
					continue
				elif lists == {}:
					continue
				
				if mode == "HELP":
					for s in self.alert["HELP"]:
						if s == "help":
							self.AlertStatus("New Help")
						elif s == "debug":
							self.AlertStatus("New Bug")
						elif s == "status":	
							self.AlertStatus("New Status")
						break
					return
				elif mode == "SEARCH":
					for s in self.alert["SEARCH"]:
						self.AlertStatus(self.data["search_tickets"][s])
						return

				for i in lists:
					if i != "":
						self.AlertStatus(i)
						return
			self.AlertStatus("")
		except Exception, e:
			self.Hlog( "debug", "AlertPick: " + str(e))
			
	def AlertStatus(self, s):
		try:
			self.logs["alert"] = s
			aw = self.windows["border"]["alert"]
			aw.erase()
			
			if len(self.logs["alert"][:14]) < 13 and len(self.logs["alert"][:14]) > 0:
				line = " "+self.dlang( self.logs["alert"][:14] )+" "
			else:
				line = self.dlang( self.logs["alert"][:14] )
			aw.addstr(line, self.colors["yellow"] )
			aw.refresh()
		except Exception, e:
			self.Hlog( "debug", "Alert Status: " + str(e))
				
				

	# --- TEXT PLACEMENT ^

	# THREADS THREADING vv
	
	def ThreadNickCheck(self):
		try:
			if self.usernames["username"] != None:
				return
			self.display["mode"] = "status"
			self.ModeHelp()
			self.Hlog("status", "Connection is taking a while to start, maybe you are trying to connect to a FTP daemon?")
			self.Hlog("status", "Killing connection..")
			self.Hlog("status", "Try using /interface to connect to a different port.")
			for line in self.help_connect:
				self.Hlog("status", line)
			driver.Driver.close(self)
		except Exception,e:
			self.Hlog("debug", "ThreadNickCheck: " + str(e))
			
	def ThreadTransfersRetry(self):
		try:
			if mucous_config["mucous"]["auto-retry"] != "yes":
				self.retry_timer.cancel()
			else:
				for user_path, transfer  in self.transfers["downloads"].items():
					if int(transfer[3]) in (11, 12, 13, 14):
						self.SendMessage(messages.DownloadFile(transfer[1], transfer[2]))
				self.retry_timer.cancel()
				self.retry_timer = threading.Timer(30.0, self.ThreadTransfersRetry)
				self.retry_timer.start()
		except Exception,e:
			self.Hlog("debug", "ThreadTransfersRetry: " + str(e))
			
	def timeout(self):
		try:
			self.timeout_timer.cancel()
			if self.Spl["status"] == 0:
				self.timedout = True
				self.ToggleAwayStatus()

		except Exception,e:
			self.Hlog("debug", "timeout: " + str(e))
	
	def ThreadTransfersClear(self):
		try:
			if mucous_config["mucous"]["auto-clear"] != "yes":
				self.clear_timer.cancel()
			else:
				for userpath, values in self.transfers["uploads"].items():
					if values[3] in (0, 10, 11, 12, 13, 14):
						self.SendMessage(messages.TransferRemove(1, values[1], values[2]))
							
				for userpath, values in self.transfers["downloads"].items():
					if values[3] == 0:
						self.SendMessage(messages.TransferRemove(0, values[1], values[2]))
				self.clear_timer.cancel()
				
				self.clear_timer = threading.Timer(30.0, self.ThreadTransfersClear)
				self.clear_timer.start()
		except Exception,e:
			self.Hlog("debug", "ThreadTransfersClear: " + str(e))
			
	def ThreadMuscan(self):
		try:
			self.muscan_timer.cancel()
			if subprocess_fail:
				self.Hlog("status", "This feature requires Python 2.4")
				return
			if mucous_config["connection"]["interface"][:9] in ("localhost", "/tmp/muse") and self.muscan_command != [] :
				p = "/usr/bin/muscan"
				if os.path.exists(p):
				
					z = subprocess.Popen( self.muscan_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
					stdout_text, stderr_text = z.communicate()
					z.wait()
					
					stdout_text = stdout_text.split('\n')
					stderr_text = stderr_text.split('\n')
					for line in stdout_text:
						if line.isspace() or line == '':
							pass
						else:
							self.Hlog("status", line)
					for line in stderr_text:
						if line.isspace() or line == '':
							pass
						else:
							self.Hlog("status", line)
					self.Hlog("status", "Finished with shares.")
			else:
				self.Hlog("status", "Your Museekd is either running remotely or already running a command, cancelling.")
		
				
			self.muscan_command = []
		except Exception,e:
			self.Hlog("debug", "ThreadMuscan: " + str(e))
			
	def MuscanAddNormal(self):
		self.Spl["setup_input"]="adddir"
		self.ModeSetup()
	def MuscanAddBuddy(self):
		self.Spl["setup_input"]="addbuddydir"
		self.ModeSetup()
	def MuscanRemoveBuddy(self):
		self.Spl["setup_input"]="rmbuddydir"
		self.ModeSetup()
	def MuscanRemoveNormal(self):
		self.Spl["setup_input"]="rmdir"
		self.ModeSetup()
	def MuscanRestartThread(self):
		self.muscan_timer.cancel()
		self.muscan_timer = threading.Timer(1.0, self.ThreadMuscan)
		self.muscan_timer.start()
	def MuscanListNormal(self):
		self.muscan_command = ["muscan", "-c", self.Spl["museekconfigfile"], "-l"]
		self.MuscanRestartThread()
		self.Hlog("status", "Listing normal shares with muscan.")
	def MuscanListBuddy(self):
		self.muscan_command = ["muscan", "-c", self.Spl["museekconfigfile"], "-b", "-l"]
		self.MuscanRestartThread()
		self.Hlog("status", "Listing buddy shares with muscan.")
	def MuscanRescanBuddy(self):
		self.muscan_command = ["muscan", "-c", self.Spl["museekconfigfile"], "-v", "-b", "-r"]
		self.MuscanRestartThread()
		self.Hlog("status", "Rescanning buddy shares with muscan, don't forget to Reload them.")
	def MuscanUpdateBuddy(self):
		self.muscan_command = ["muscan", "-c", self.Spl["museekconfigfile"], "-v", "-b"]
		self.MuscanRestartThread()
		self.Hlog("status", "Updating buddy shares with muscan, don't forget to Reload them.")
	def MuscanUpdateNormal(self):
		self.muscan_command = ["muscan", "-c", self.Spl["museekconfigfile"], "-v"]
		self.MuscanRestartThread()
		self.Hlog("status", "Updating shares with muscan, don't forget to Reload them.")
	def MuscanRescanNormal(self):
		self.muscan_command = ["muscan", "-c", self.Spl["museekconfigfile"], "-v", "-r"]
		self.MuscanRestartThread()
		self.Hlog("status", "Rescanning shares with muscan, don't forget to Reload them.")
			
	def DrawTicker(self):
		try:
			if self.display["mode"] != "chat" or self.Spl["room"] not in self.data["tickers"] or mucous_config["tickers"]["tickers_enabled"] != 'yes':
				return
			ticks = self.data["tickers"][self.Spl["room"]]
			ttickers = ticks.keys()
			if ttickers == []:
				self.ticker_timer.cancel()
				try:
					self.DrawChatRoomStatusWin()
					self.DrawChatRoomStatusText()
					curses.doupdate()
				except:
					pass
			else:
				ttickers.sort(key=str.lower)
				if mucous_config["tickers"]["ticker_scroll"] == "yes":
					if self.Spl["show_menu"] == True:
						self.ticker_timer.cancel()
						self.ticker_timer = threading.Timer(float(mucous_config["tickers"]["scrolltime"]), self.DrawTicker)
						self.ticker_timer.start()
						return
					longstring = ""
					for user in ttickers:
						longstring += "[%s] %s " % (user, ticks[user])
					if self.display["chatshape"] in ("nostatuslog", "chat-only"):
						bw = self.windows["border"]["chat"]
						s = self.windows["dimensions"]["chat"]
						padd = -3; posy = 0; posx = 2
					else:
						bw = self.windows["border"]["roomstatus"]
						s = self.windows["dimensions"]["roomstatus"]
						padd = 0; posy = 5; posx = 1
					
					if self.Spl["ticker_num"] >= len(longstring):
						self.Spl["ticker_num"] = 0
					part = longstring[self.Spl["ticker_num"]:self.Spl["ticker_num"]+s["width"]-2+padd]
					while len(part) < s["width"]-2 +padd:
						part += longstring[:(s["width"]-2+padd - len(part))] 
					fill = (s["width"]-2 - len(part) +padd) * " "
					bw.addstr(posy, posx, "<%s%s>" %(part, fill))
					bw.refresh()
					self.Spl["ticker_num"] += 1
					#if self.Spl["ticker_num"] >= len(ttickers):
						#self.Spl["ticker_num"] = 0
					self.ticker_timer.cancel()
					self.ticker_timer = threading.Timer(float(mucous_config["tickers"]["scrolltime"]), self.DrawTicker)
					self.ticker_timer.start()
					return
			
				
				if self.Spl["ticker_num"] >= len(ttickers):
					self.Spl["ticker_num"] = 0
				names = ttickers[self.Spl["ticker_num"]]
				n = len(names)
				try:
					if self.Spl["show_menu"] == True: raise Exception,  "Noticker"
					if self.display["chatshape"] not in ("nostatuslog", "chat-only"):
						if "roomstatus" not in self.windows["border"]:
							return
						bw = self.windows["border"]["roomstatus"]
						s = self.windows["dimensions"]["roomstatus"]
						tick = str(ticks[names][:s["width"]-7-n])
						fill = (s["width"]-6-len(tick)-len(names)) * " "
						string = "< [%s] %s%s>" % (names, tick, fill)
						bw.addstr(5, 1, self.dlang( string ))
						bw.refresh()
						
					elif self.display["chatshape"] in ("nostatuslog", "chat-only"):
						mw = self.windows["border"]["chat"]
						s = self.windows["dimensions"]["chat"]
						tick = str(ticks[names][:s["width"]-25-n])
						fill = (s["width"]-25-len(tick)-len(names)) * " "
						string = "< [%s] %s%s>" %(names, tick, fill)
						mw.addstr(0, 18, self.dlang( string ))
						mw.refresh()
				except:
					pass
				

				self.Spl["ticker_num"] += 1

				self.ticker_timer.cancel()
				self.ticker_timer = threading.Timer(float(mucous_config["tickers"]["cycletime"]), self.DrawTicker)
				self.ticker_timer.start()
				
				
		except Exception,e:
			self.Hlog("debug", "DrawTicker: " + str(e))
		# THREADS THREADING THRU TIME ^^

try:
	
	if profile:
	    import hotshot
	    log = os.path.expanduser(config_file) + ".profile"
	    profiler = hotshot.Profile(log)
            print ("Starting using the profiler (saving log to %s)") % log
	    sleep(1)
	    profiler.runcall(curses.wrapper(mucous()))
	else:
            curses.wrapper(mucous())
except Exception, e:
	print e
	
	