// This Class provides all functionality for chatting (ajax request, reloads etc.)
function chat(_emptyPosts, _equalPosts, _postingPeriod) {
	
	var self = this;
	var lastMsgId = 0;
	var className = 1;
	var messageClassName = 1;
	var privateChannelUsername = false;
	
	var autoReloadChatTime = 3000;
	var interval;
	var userList = new Array();
	var userListNow = new Array();
	var privateChannelRequest;
	var Lang = Array();
	Lang[0] = new Object();
	var ignoredUsers = new Array();
	
	var emptyPosts = _emptyPosts;
	var equalPosts = _equalPosts;
	var postingPeriod = _postingPeriod;
	var ticker = 0;
	var addButton = getById('cha_sendButton');
	var addButtonValue = getById('cha_sendButton').value;
	var date = new DateUtil();
	var timeout;
	
	var lastMessageValue = "";
	
	// Initialize Chat
	this.init = function(_autoReloadChatTime) {
		
		if(_autoReloadChatTime)
			autoReloadChatTime = _autoReloadChatTime*1000;
		
		getById('text_message').onkeyup = this.captureKeycode;
		getById('cha_loginButton').onclick = this.login;
		getById('cha_logoutButton').onclick = this.logout;
		getById('cha_sendButton').onclick = this.submitMessage;
		getById('cha_rooId').onchange = function(_sender) {
			self.joinRoom(getById('cha_rooId').options[getById('cha_rooId').selectedIndex].value);
		};
		
		// Disable Login Button if no Rooms are available
		
		// Load language variables
		var request = new AjaxRequest(pathPrefix + "/Ajax/chaLoadLangs", true, false);
		request.doRequest();
		
		var xml = request.getResponseXML();
		
		var entries = xml.getElementsByTagName('entry');
		
		for(var i = 0; i < entries.length; i++) {
			
			var id = entries[i].getElementsByTagName('id')[0].firstChild.nodeValue;
			var value = entries[i].getElementsByTagName('value')[0].firstChild.nodeValue;
			
			Lang[0][id] = value;			
		}
		
		return false;
	
	}
	
	// Start or Stop Auto-Reload Intervals
	this.startStopInterval = function(_value) {
		if(_value)
			interval = window.setInterval(function() {
				self.requestMessages(lastMsgId)}, autoReloadChatTime);
		else
			window.clearInterval(interval);
	}
	
	// Login into chat (This is the first time, check username and so on)
	this.login = function() {
		
		var rooId = getById('cha_rooId').value;
		
		var username = getById('cha_username').value;
			
		var request = new AjaxRequest(pathPrefix + "/Ajax/chaLogin", false, true);
		
		request.callFunction = function(_request) {
   			
			var text = _request.responseText;
			var index = text.indexOf("Error:");
			
			if(index >= 0) {
				
				getById('chatError').innerHTML = text.substr(index+6);
				getById('chatError').style.display = "";
				
			}
			else {
				
				// Resume if no errors
				showHide('cha_chatBox');
				getById('chatError').style.display = "none";
				
				self.joinRoom(rooId);
				self.requestMessages(lastMsgId);
				self.startStopInterval(true);
				
				// Disable Button
				getById('cha_loginButton').style.display = "none";
				getById('cha_username').disabled = true;
				getById('cha_logoutButton').style.display = "";
				getById('cha_userlist').style.display = "";
				
				// Cleanup Chat Div (deletes old messages)
				getById('chat_messages').innerHTML = "";
			}
			
		};
		
		request.setPostvars("rooId=" + rooId + "&username=" + username);
		request.doRequest();

		return false;
	}
	
	// Show hides user and saves to array
	this.showHideUser = function(_id) {
		showHide("userAction_" + _id);
		
		for(var i = 0; i < userList.length; i++) {
			
			if (userList[i] == _id) {
				userList[i] = null;
				return;
			}
		}
		userList.push(_id);
	}
	
	this.logout = function() {

		self.startStopInterval(false);
		
		var request = new AjaxRequest(pathPrefix + "/Ajax/chaLogout", true, true);
		request.doRequest();
		
		//getById('cha_username').disabled = false;
		showHide("cha_loginButton");
		showHide("cha_logoutButton");
		
		showHide('cha_chatBox');
		
		return false;		
	}
	
	// Join Room
	this.joinRoom = function(_rooId) {
		
		if(!_rooId)
			return false;
		
		this.clearMessages();
		
		if(privateChannelUsername)
			this.closePrivateChannel(privateChannelUsername);
		
		
		var request = new AjaxRequest(pathPrefix + "/Ajax/chaJoinRoom", true, true);
		
		request.setPostvars("rooId=" + _rooId + "&color=" + getById('usercolor').value);
		request.doRequest();
		lastMsgId = request.getResponseText();
		

		return false;
	}
	
	// clears all Messages
	this.clearMessages = function() {
		getById('chat_messages').innerHTML = "";
	}
	
	// Capture keyupEvent -> Check if Submit is requestet
	this.captureKeycode = function(_e) {
		
		if(window.event) {
			var keycode = window.event.keyCode;
		}
		else {
			
			var keycode = _e.which;
		}
		
		if(keycode == 13) {
			
			if(ticker > 0)
				return;
			
			self.submitMessage();
		}
		
	}
	
	// Submit Chat Message 
	this.submitMessage = function() {
		var message = getById('text_message').value;
		getById('text_message').value = "";
		
		
		if (!emptyPosts) {
			if (message.length == 0) {
			
				alert(Lang[0]["cha.p.noEmptyMessages"]);
				return false;
				
			}
		}
		
		if(!equalPosts) {
			
			if(message == lastMessageValue) {
								
				alert(Lang[0]["cha.p.noEqualMessages"]);
				return false;
			}
		}
		
		if (postingPeriod > 0) {
			
			if(ticker > 0)
				return;
			
			clearTimeout(timeout);
			ticker = postingPeriod;
			addButton.disabled = "disabled";
			
			self.tick();
		}
		
		var request = new AjaxRequest(pathPrefix + "/Ajax/chaSubmitMessage", false, true);
		request.setPostvars("message=" + message + "&lastMsgId=" + lastMsgId + (privateChannelUsername ? "&privateChannelUsername=" + privateChannelUsername : "")
			+ "&color=" + getById('usercolor').value);
		request.callFunction = this.response;
		request.doRequest();
		
		lastMessageValue = message;
		
		return false;
	}
	
	// Ticker function (posting periode)
	
	this.tick = function() {
		
		if(ticker >= 0) {
			if(ticker == 0) {
				
				addButton.disabled = false;
				addButton.value = addButtonValue;
			}
			else {
				addButton.value = addButtonValue + " (" + (ticker) + ")";
				ticker--;
			}
			
			timeout = setTimeout(function() {self.tick() }, 1000);
		}
		else clearInterval(timeout);
						
	}
	
	// Open private Channel
	this.openPrivateChannel = function(_username) {
		
		privateChannelRequest = _username;
		
		var request = new AjaxRequest(pathPrefix + "/Ajax/chaOpenPrivateChannel", false, true);
		request.setPostvars("username=" + privateChannelRequest + "&lastMsgId=" + lastMsgId + "&action=open");
		request.callFunction = this.response;
		request.doRequest();
	}
	
	// Enter private channel => Accept/JOIN
	this.enterPrivateChannel = function(_username, _action) {
		
		if(!_action)
			var action = "enter";
			
		else var action = _action;
		
		var request = new AjaxRequest(pathPrefix + "/Ajax/chaOpenPrivateChannel", false, true);
		request.setPostvars("username=" + _username + "&lastMsgId=" + lastMsgId + "&action=" + action);
		request.callFunction = this.response;
		request.doRequest();
		
		this.clearMessages();
		privateChannelUsername = _username;
		
	}
	
	// Close private Channel
	this.closePrivateChannel = function(_username, _action) {
		
		if(!_action)
			var action = "close";
			
		else var action = _action;
		
		var request = new AjaxRequest(pathPrefix + "/Ajax/chaClosePrivateChannel", false, true);
		request.setPostvars("username=" + _username + "&lastMsgId=" + lastMsgId + "&action=" + action);
		request.callFunction = this.response;
		request.doRequest();
		
		privateChannelUsername = null;
	}
	
	// Decline private Channel => Decline/Don't Accept
	this.declinePrivateChannel = function(_username) {
		
		var request = new AjaxRequest(pathPrefix + "/Ajax/chaClosePrivateChannel", false, true);
		request.setPostvars("username=" + _username + "&lastMsgId=" + lastMsgId + "&action=decline");
		request.callFunction = this.response;
		request.doRequest();
	}
	
	// Insert Whisper-To Prefix
	this.whisperTo = function(_username) {
		getById('text_message').value = "/PN (" + _username + ") ";
	}
	
	// Start a new request
	this.requestMessages = function(_lastMsgId) {
		
		var request = new AjaxRequest(pagePath + "/modules/cha/chaCore.php", false, true);
		request.callFunction = this.response;
		
		request.setPostvars("lastMsgId=" + _lastMsgId + "&action=requestMessages");
		request.doRequest();

		return false;
	}
	
	// Response Function for new messages
	this.response = function(_request) {
		var xml = _request.responseXML;
		
		var messageNode = xml.getElementsByTagName('messages')[0];
		
		if(messageNode == undefined)
			var messages = Array();
		else
			var messages = messageNode.getElementsByTagName('message');
		
		// Messages
		for (var i = 0; i < messages.length; i++) {
			
			var code = (messages[i].getElementsByTagName('code')[0].firstChild ?
				messages[i].getElementsByTagName('code')[0].firstChild.nodeValue : "");
			
			var usernameSender = messages[i].getElementsByTagName('usernameSender')[0].firstChild.nodeValue;
			
			if (self.findCode(code, usernameSender)) {
				continue;
			}
			
			// Assign Contents
			var text = (messages[i].getElementsByTagName('text')[0].firstChild ?
				messages[i].getElementsByTagName('text')[0].firstChild.nodeValue : "");
			
			var time = date.getTime(messages[i].getElementsByTagName('time')[0].firstChild.nodeValue);;
			var username = messages[i].getElementsByTagName('username')[0].firstChild.nodeValue;
			var usrId = messages[i].getElementsByTagName('usrId')[0].firstChild.nodeValue;
			var color = (messages[i].getElementsByTagName('color')[0].firstChild ?
				messages[i].getElementsByTagName('color')[0].firstChild.nodeValue : "#000000");
			var msgId = messages[i].getElementsByTagName('msgId')[0].firstChild.nodeValue;			
			
			if(parseInt(msgId) <= parseInt(lastMsgId))
				continue;
			
			appendToChat(time, username, text, color);
			if(parseInt(msgId) > parseInt(lastMsgId))
				lastMsgId = msgId;
				
		}
		
		// Users in this room
		
		var usersNode = xml.getElementsByTagName('users')[0];
		var users = usersNode.getElementsByTagName('user');
		var count = usersNode.getAttribute('count');
		
		var userlist = getById('cha_userlist');
		
		// Create <ul> Node if no listings existis yet
		if(!userlist.getElementsByTagName("ul")[0]) {
			
			var newUl = document.createElement("ul");
			newUl.id = "ul_userlist";
			newUl.className = "formList";
			userlist.appendChild(newUl);
		}
		
		userListNow = new Array();
		
		var userlist = getById("ul_userlist");
		
		userlist.innerHTML = "";
		
		for(var i = 0; i < users.length; i++) {
			
			var username = users[i].getElementsByTagName('username')[0].firstChild.nodeValue;
			
			var privateChannel = (users[i].getElementsByTagName('privateChannel')[0].firstChild ?
				users[i].getElementsByTagName('privateChannel')[0].firstChild.nodeValue : "");
				
			var lastAction = users[i].getElementsByTagName('lastAction')[0].firstChild.nodeValue;		
		
			appendToUserlist(username, lastAction);	
		}
		
		userList = userListNow;
		
		// Users in Room
		
		getById('numUsersInRoom').innerHTML = count;
		
	}
	
	// analyse raw text and search for code segments
	this.findCode = function (_text, _username) {
		
		for(var i = 0; i < ignoredUsers.length; i++) {
			
			if(_username == ignoredUsers[i])
				return true;
		}
		
		if(_text == "privateChannel:Accepted") {
			
			if(_username == privateChannelRequest) {
				
				this.enterPrivateChannel(_username, "enterAfterRequest");
				privateChannelUsername = _username;
				privateChannelRequest = null;
			}
			return true;
		}
		
		else if(_text == "privateChannel:Declined") {
			
			if(_username == privateChannelRequest) {
				
				privateChannelRequest = null;
				this.closePrivateChannel(_username, "closeAfterRequest");
			}
			return true;
		}
		
		else if(_text == "privateChannel:Closed") {
			
			if(_username == privateChannelUsername) {
				
				privateChannelUsername = null;
				this.closePrivateChannel(_username, "closeAfterOther");
			}
			
		}
		
		else if(_text == "logout") {
			
			privateChannelUsername = null;
			this.logout();
			
		}
	}
	
	// Apend to userlist
	
	var appendToUserlist = function (_username, _lastAction) {
		
		var userlist = getById("ul_userlist");
		
		var newLi = document.createElement("li");
		
		var display = "none";
		for(var i = 0; i < userList.length; i++) {
			if(userList[i] == _username) {
				var display = "";
				userListNow.push(_username);
			}
		}
		
		// Check if user is ignored
		
		if(in_array(_username, ignoredUsers))
			var ignored = true;
		else
			var ignored = false;
			
		if(_username == getById('cha_username').value)
			var isSelf = true;
		else
			var isSelf = false;
		
		newLi.innerHTML = 
			"<a href=\"#\" onclick=\"chat.showHideUser('" + _username + "'); return false;\" class=\"icon\">"
				+ (!isSelf ? "<img src=\"" + iconPath + "/smallarrow_down.png\" />" : "")
				+ "<span id=\"lastAction_" + _username + "\"> " + _username + " (" + date.getTime(_lastAction) + ")</span></a>"
				+ (!isSelf ? "<div id=\"userAction_" +  _username + "\" style=\"display: " + display + ";\">"
				+ (!privateChannelUsername ? "<a class=\"icon\" href=\"javascript:chat.whisperTo('" + _username + "')\">"
				+	"	<img src=\"" + iconPath + "/chat_16.png\" />"
				+	"	<span>" + Lang[0]["cha.w.whisper"] + "</span> "
				+	"</a><br /> " : "")
				+	"<a class=\"icon\" href=\"javascript:chat." + (privateChannelUsername == _username ? "close" : "open") + "PrivateChannel('" + _username + "')\">"
				+	"	<img src=\"" + iconPath + "/clients_" + (privateChannelUsername == _username ? "cancel_" : "") + "16.png\" id=\"channel_" + _username + " \">"
				+	"	<span>" + (privateChannelUsername == _username ? Lang[0]["cha.p.closePrivateChannel"] :  Lang[0]["cha.p.openPrivateChannel"]) + "</span>"
				+	"</a>"
				+ 	"<br />"
				+	"<a class=\"icon\" href=\"javascript:chat.ignore('" + _username + "')\">"
				+	"	<img src=\"" + iconPath + "/" + (!ignored ? "del" : "check") + "_16.png\" />"
				+	"	<span>" + (ignored ? Lang[0]["cha.p.acceptUser"] : Lang[0]["cha.p.ignoreUser"]) + "</span> "
				+	"</a>"
				+ "</div>" : "");
		
		userlist.appendChild(newLi);
	}
	
	// Append new line to chat div
	var appendToChat = function(_time, _user, _text, _color) {
		var div = document.createElement("div");
		div.className = "chat _" + messageClassName;
		
		if(messageClassName < 2)
			messageClassName++;
		else
			messageClassName--;
		
		// Append Time
		var spanNode = document.createElement("span");
		spanNode.className = "chat_time";
		spanNode.innerHTML = "(" + _time + ") ";
		div.appendChild(spanNode);
	
		// Append Username
		var timeNode = document.createElement("span");
		timeNode.style.color = _color;
		timeNode.className = "chat_user";
		timeNode.innerHTML = _user + ": ";
		div.appendChild(timeNode);
		
		// Append Text
		var textNode = document.createElement("span");
		textNode.className = "cha_text";
		textNode.innerHTML = _text;
		div.appendChild(textNode);
		
		getById('chat_messages').appendChild(div);
		
		// Set Auto-Scrolling
		//div.scrollIntoView(false);
		var messageDiv = getById('chat_messages');
		messageDiv.scrollTop = messageDiv.scrollHeight - messageDiv.offsetHeight + 100;
		
	}
	
	
	// Ignores User
	this.ignore = function(_username) {
		
		var deleted = false;
		for(var i = 0; i < ignoredUsers.length; i++) {
			
			if (_username == ignoredUsers[i] && ignoredUsers[i] != null) {
				ignoredUsers[i] = null;
				var deleted = true;
			}			
		}
		
		if(!deleted)
			ignoredUsers.push(_username);
			
		this.requestMessages(lastMsgId);	
	}
	
}