// Chat object
function chatClass(ident){
	// Initializing variables
	this.sessionId = null;
	this.ident = ident;
	this.users = {};
	this.usersLoaded = false; // Displays if the userlist is loaded
	this.users_num = 0;
	this.imgUrl = null;
	this.login = null;
	this.splitMode = false;
	this.channelName = '';
	this.channelId = null;
	
	this.writerDocument = null;
	this.readerDocument = null;
	this.usersDocument = null;
	
	this.usersDropdownLoaded = false;
	this.privateListObj = null;
	this.currentPrivateLogin = ''; // Default is channel
	this.privates = {'':true}; // Default channel, there must be one empty
	this.privateBlinks = {}; // Array of window intervals 
	this.privateBlinkStatus = {}; // Status of current blinking
	
	this.blinkOnColor = "black";
	this.blinkOffColor = "white";
	
	this.cssFile = '/styles/chat1.css';
	
	this.preferences = { // Preferences array
		clockFormat: '[H:m]',
		clock: false
	}; 
	
	this.setReaderDocument = function(document){
		this.readerDocument = document;
		if(!this.readerDocument.parentWindow){
			this.readerDocument.parentWindow = document.defaultView;
		}
	}
	
	this.setWriterDocument = function(document){
		this.writerDocument = document;
		if(!this.writerDocument.parentWindow){
			this.writerDocument.parentWindow = document.defaultView;
		}
	}
	
	this.setUsersDocument = function(document){
		this.usersDocument = document;
		if(!this.usersDocument.parentWindow){
			this.usersDocument.parentWindow = document.defaultView;
		}
		
		// Set channel title
		this.usersDocument.getElementById('channelName').innerHTML = this.channelName;
	}
	
	this.getCssFile = function(){
		return this.baseURL + this.cssFile;
	}
	
	this.checkMessage = function(el){
		for(var i = 0; i < el.value.length; i++){
			if(el.value.charCodeAt(i) > 2000){
				alert('Jūsų žinutėje yra neleistinų simbolių. Maloniai prašome patikrinti ar nenaudojate specialių simbolių.');
				return false;
			}
		}
		
		return true;
	}
	
	this.setPrivateListDocument = function(document){
		this.privateListDocument = document;
		if(!this.privateListDocument.parentWindow){
			this.privateListDocument.parentWindow = document.defaultView;
		}
	}
	
	this.selectUser = function(login){
		if(!this.writerDocument){
			return;
		}
		
		if(!this.writerDocument.forms['writer']){return false;}
		var users = this.writerDocument.forms['writer'].elements['to_login'];
		if(users){
			for(i = 0; i < users.length; i++){
				if(login == users.options[i].value){
					users.selectedIndex = i;
				}
			}
		}
		
		try{ // If element if visible
			this.writerDocument.forms['writer'].elements['msg'].focus();		
		}catch(e){};
		
		return;
	}
	
	this.setUsers = function(users){
		this.users = users;
		this.usersLoaded = true;
		this.drawUsers();
		this.drawUsersDropdown();
		
		return true;
	}

	this.loadUsers = function(){
		$.getJSON('bin.php', {key:this.ident, action:'getUsers'},
			function(data, textStatus){
				if(data['do'] == 'quit'){
					chat.quit(data['code'], data['reason']);
					return;
				}
				
				chat.setUsers(data)
			}
			);
	}
	
	this.drawUsers = function(){
		if(this.usersDocument){ // Document mapped
			var usersDiv = this.usersDocument.getElementById("userList");
			
			if(usersDiv){
				
				var usersHTML = '';
				this.usersNum = 0;
				
				for(i in this.users){
					this.usersNum ++;
					var user = this.users[i];
					var userStr = '';
			
					if(user.rank && user.rank != 'v'){
						userStr += '<a href="#" onclick="chat.openProfile(\'' + user.login + '\');return false;"><img src='+this.imgUrl+'/'+this.getIconName(user.rank, user.sex)+' width=10 height=10 border=0 alt="" align=absmiddle></a> ';
					}else{
						userStr += '<img src='+this.imgUrl+'/tr.gif width=10 height=10 border=0 alt="" align=absmiddle> ';
					}
					
					if(user.login != this.login){
						userStr += '<a href="#" onclick="chat.selectUser(\''+user.login+'\'); return false;" ';
						if(user.rank != 'v'){
							userStr += ' ondblclick="chat.openProfile(\''+ user.login +'\'); return false;" ';
						}
						
						if(user.away > 0){
							userStr += ' class="away" ';
						}
						
						userStr += '>' + user.login + '</a>';
					}else{
						userStr += '<a href="#" onclick="chat.selectUser(\'all\');return false;" ';
						
						if(user.rank != 'v'){
							userStr += ' ondblclick="chat.openProfile(\'' + user.login + '\'); return false;" ';
						}
						
						if(user.away > 0){
							userStr += ' class="away" ';
						}
						
						userStr += '>' + user.login + '</a>';
					}
					
					if(user.photo > 0){
						userStr += '&nbsp;<img class="photo" src="images/tr.gif">';
					}
					
					usersHTML += '<div>' + userStr + '</div>';
				}
				
				usersDiv.innerHTML = usersHTML;
				var usersNum = this.usersDocument.getElementById('usersNum');
				
				if(!usersNum){
					return -3;
				}
				
				usersNum.innerHTML = this.usersNum;
				
				return true;
			}else{
				return -2;
			}
		}
		
		return -1;
	}
	
	this.drawUsersDropdown = function(login){
		if(!this.writerDocument || !this.usersLoaded ){
			return -1;
		}
		
		var usersSelectObj = this.writerDocument.getElementById('logins');
		if(!usersSelectObj){
			return -2;
		}
		
		// Saving selected login, if was selected before
		if(usersSelectObj.selectedIndex > 0 && this.usersDropdownLoaded){
			var selectedLogin = usersSelectObj.options[usersSelectObj.selectedIndex].value;
		}else{
			var selectedLogin = login ? login : 'all';
		}
		
		// Clearing list
		usersSelectObj.options.length = 0;
		
		// Adding all
		var elOptNew = this.writerDocument.createElement('option');
		elOptNew.value = ' ';
		elOptNew.text = ' ';
		usersSelectObj.options[0] = elOptNew;
		
		// Adding users to option list
		var index = 1;
		for(i in this.users){
			var user = this.users[i];
			if(user.login == this.login){
				continue;
			}
			
			var elOptNew = this.writerDocument.createElement('option');
			elOptNew.value = user.login;
			elOptNew.text = user.login;
			usersSelectObj.options[index] = elOptNew;
			index ++;
		}
		
		// Sorting by users list
		//sortSelect(usersSelectObj, true);
		
		// Adding value "to all"
		usersSelectObj.options[0].value = 'all';
		usersSelectObj.options[0].text = 'Visiems';

		// Restoring selected login, if login variable is provided select provided
		var l = usersSelectObj.options.length;
		for(var i = 0; i < l; i++ ){
			if(usersSelectObj.options[i].value == selectedLogin){
				usersSelectObj.options[i].selected = true;
				break;
			}
		}
		
		
		// setting flag that dropdown was loaded
		this.usersDropdownLoaded = true;
		return true;
	}
	
	// Writes a message to log
	this.writeMessage = function(type, from, style, msg){
		var div = this.readerDocument.createElement("div");
		var str = '';
		
		if(from == 'system'){
			str += '<span class=sysmsg>' + msg + '</span>';
			
			// Checking if system message can apply the private
			for(i in this.privates){
				if(!i) continue; // Skip channel
				
				if(msg.match(new RegExp("(.*[^A-Za-z0-9_]|^)"+i+"([^A-Za-z0-9_].*|$)"))){ // Found the login in message string
					var pDiv = this.readerDocument.createElement("div"); // Creating another div for a private
					pDiv.innerHTML = str;
					this.readerDocument.getElementById('#private_' + i).appendChild(pDiv);
				}
			}
			
			// Post in a channel talk
			this.readerDocument.getElementById('#channel').appendChild(div);
		}else if(from == '#ads' || from == '#ads1'){
			str += '<table cellpadding=0 border=0 width="100%"><tr><td colspan=3 background="images/dots_blue.gif"><img src="images/tr.gif"></td></tr><tr valign="middle"><td width=10 height=30><img src='+( from == '#ads'?'images/hand_red.gif':'images/hand_green.gif' )+'></td><td width=1>&nbsp;&nbsp;</td><td><span class=admsg>'+msg+'</span></td></tr><tr><td colspan=3 background="images/dots_blue.gif"><img src="images/tr.gif"></td></tr></table>';
			this.readerDocument.getElementById('#channel').appendChild(div);
		}
		else{
			
			if(this.preferences.clockFormat && this.preferences.clock){
				str += '<b class="clock">' + this.getTime(this.preferences.clockFormat) + '</b> ';
			}
			
			switch(type){
				case 'p':
					str += '<img style="vertical-align: middle;" src="images/from.gif" align="middle"> ';
					str += '<b class="private login" onclick="chat.selectUser(\''+from+'\');">' +from+ '</b>';
	
					// append string to channel
					if(this.splitMode){ // For split mode
						if(!this.readerDocument.getElementById('#private_' + from)){
							// Open private if not exists
							this.onPrivateArrive(from);
							this.blinkPrivateTab(from);
							if(this.sound) this._makeSound();
						}else{
							// Just blink
							if(this.currentPrivateLogin != from){
								this.blinkPrivateTab(from);
								if(this.sound) this._makeSound();
							}
						}
						
						this.readerDocument.getElementById('#private_' + from).appendChild(div);
					}else{ // For not split mode
						this.readerDocument.getElementById('#channel').appendChild(div);
					}
					break;
				case 'pe':
					str += '<img style="vertical-align: middle;" src="images/to.gif" align="middle"> ';
					str += '<b class="pe login" onclick="chat.selectUser(\''+from+'\');">' +from+ '</b>';
					
					// append string to channel
					if(this.splitMode){ // For split mode
						if(!this.readerDocument.getElementById('#private_' + from)){
							// Open private
							this.onPrivateArrive(from);
							this.blinkPrivateTab(from);
						}
					
						this.readerDocument.getElementById('#private_' + from).appendChild(div);
					}else{ // For not split mode
						this.readerDocument.getElementById('#channel').appendChild(div);
					}
					break;
				default:
					str += '<b class="login" onclick="chat.selectUser(\''+from+'\');">' +from+ '</b>';
					
					// append string to channel
					this.readerDocument.getElementById('#channel').appendChild(div);
					break;
			}
			
			str +=  ' &gt; <span class="'+style+'">' +msg+ '</span><br>';
		}
		
		chat.scrollChannel(50); // Scrolling down
		
		div.innerHTML = str;
		return;
	}
	
	this.clear = function(){ // Clear chat window
		this.readerDocument.getElementById('#channel').innerHTML = '';
		this.writeMessage('', 'system', '', "Chat'o langas buvo pravalytas ...");
	}
	
	this.scrollChannel = function(step){
		if(step > 0){
			step -= 2;
			this.readerDocument.parentWindow.scrollBy(0, 2);
			setTimeout("chat.scrollChannel(" + step + ")", 8); // Reqursive
		}
		else{
			return false;
		}
	}
	
	this.switchToPrivate = function(login){
		if(!this.privates[login]){
			return;
		}
		
		var s = this.readerDocument.getElementById(this.currentPrivateLogin?'#private_' + this.currentPrivateLogin:'#channel');
		var t = this.readerDocument.getElementById(login?'#private_' + login:"#channel");
		
		if(s && t){
			s.style.display = 'none';
			t.style.display = 'block';
			
			this._selectTab(login);
			this.selectUser(login ? login:'all');
			
			this.currentPrivateLogin = login;
			
			// scroll To the end
			this.readerDocument.parentWindow.scroll(0, 1000000000);
		}
		
		this.stopBlinkingPrivateTab(login);
		return;
	}
	
	this.startPrivate = function(login){
		if(this.privates[login]){// Already started
			return; 
		}
		
		this.privates[login] = true;
		
		// Adding tab and start blinking
		this._addPrivateTab(login);
		
		var div = this.readerDocument.createElement('div');
		div.id = '#private_' + login;
		div.style.display = "none";
		div.innerHTML = '<div>Privatus pokalbis su <strong>'+login+'</strong></div>';
		this.readerDocument.body.appendChild(div);
		return div;
	}
	
	this.closePrivate = function(login){
		if(!login){return;} // Cannot delete channel
		
		if(this.currentPrivateLogin == login){
			this.switchToPrivate(''); // Switch to channel if closing current private
		}
		
		// Remove chat
		var divToDelete = this.readerDocument.getElementById('#private_' + login);
		this.readerDocument.body.removeChild(divToDelete);
		
		// Remove Tab
		this._removePrivateTab(login);
		
		// Remove info
		delete this.privates[login];
	}
	
	// Selecting tab
	this._selectTab = function(login){
		this.privateListObj.ownerDocument.getElementById('tab_' + this.currentPrivateLogin).className = 'tab';
		this.privateListObj.ownerDocument.getElementById('tab_' + login).className = 'tabSelected';
		
		return;
	}
	
	// Adding private tab
	this._addPrivateTab = function(login){
		var el = this.privateListObj.ownerDocument.createElement('a');
		el.innerHTML = login;
		el.href = "/";
		el.onclick = new Function("chat.switchToPrivate('"+login+"');return false;");
		el.ondblclick = new Function("if(confirm('Ar tikrai norite uždaryti privatų pokalbį su "+login+"?')){chat.closePrivate('"+login+"');}");
		el.className = 'tab';
		el.id = 'tab_' + login;
		this.privateListObj.appendChild(el);
	}
	
	// Remove private tab
	this._removePrivateTab = function( login ){
		var child = this.privateListObj.ownerDocument.getElementById('tab_' + login);
		this.privateListObj.removeChild(child);
		this.stopBlinkingPrivateTab(login);
	}
	
	this.blinkPrivateTab = function(login){
		if(this.privateBlinks[login]){// If is blinking
			return;
		}
		
		this.privateBlinks[login] = this.privateListDocument.parentWindow.setInterval('chat._blink("'+login+'");', 500);
	}
	
	this.stopBlinkingPrivateTab = function(login){
		if(this.privateBlinks[login]){
			this.privateListDocument.parentWindow.clearInterval(this.privateBlinks[login]);
			this._blink(login, 1); // Force to stop enabled
			delete this.privateBlinkStatus[login];
			delete this.privateBlinks[login];
		}
	}
	
	this._blink = function(login, forceOn){
		if(this.privateBlinkStatus[login] && !forceOn){
			this.privateListObj.ownerDocument.getElementById('tab_' + login).style.color = this.blinkOffColor;
			this.privateBlinkStatus[login] = 0;
		}else{
			this.privateListObj.ownerDocument.getElementById('tab_' + login).style.color = this.blinkOnColor;
			this.privateBlinkStatus[login] = 1;
		}
	}
	
	this._makeSound = function(){
		if(!this.readerDocument){
			return false;
		}
		
		this.readerDocument.getElementById('soundDiv').innerHTML = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=4,0,0,0" width="1" height="1" id="Untitled-1" align="middle"><param name="allowScriptAccess" value="sameDomain" /><param name="movie" value="sounds/s.swf" /><param name="menu" value="false" /><param name="quality" value="low" /><param name="bgcolor" value="#ffffff" /><embed src="sounds/s.swf" menu="false" quality="low" bgcolor="#ffffff" width="1" height="1" name="s" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"/></object>';
	}
	
	this.getIconName = function(rank, sex){
		switch(rank){
			case "a":
			case "i":
				return "crown.gif";
			break;
			case "o":
				return "cross.gif";
			break;
			case "p":
				return "skydas.gif";
			break;
			case "r":
				return "esponsor.gif";
			break;
			case "s":
				return "sponsor.gif";
			break;
			case "q":
				return "medal.gif";
			break;
			case 't1':
				switch(sex){
					case 'v':
						return 'heart_v.gif';
					break;
					case 'm':
						return 'heart_m.gif';
					break;
				}
			break;
			case 't2':
				switch(sex){
					case 'v':
						return 'chat_v.gif';
					break;
					case 'm':
						return 'chat_m.gif';
					break;
				}
			break;
			case "u":
				switch(sex){
					case "v":
						return "vyras.gif";
					break;
					case "m":
						return "moteris.gif";
					break;
				}
			break;
			default:
				return "tr.gif";
			break;
		}
	}
	
	// Special methods
	// Debugging info
	this.debugInfo = function(){
		var win = window.open('', "debugWindow");
		var info = 'currentPrivateLogin: ' + this.currentPrivateLogin + '<br>';
		
		info += '<br>privates:<br><ul>';
		for(i in this.privates){
			info += '<li>' + i + ':' + this.privates[i] + '</li>';
		}
		info += '</ul>';
		
		info += '<br>privateBlinks:<br><ul>';
		for(i in this.privateBlinks){
			info += '<li>' + i + ':' + this.privateBlinks[i] + '</li>';
		}
		info += '</ul>';
		
		info += '<br>privateBlinkStatus:<br><ul>';
		for(i in this.privateBlinkStatus){
			info += '<li>' + i + ':' + this.privateBlinkStatus[i] + '</li>';
		}
		
		info += '</ul>';
		
		win.document.write(''+info+'');
		win.document.close()
	}
	
	// Date time format
	this.getTime = function(format){
		var d = new Date();
		var m = d.getMinutes();
		return format.replace(/H/g, d.getHours()).replace(/i/g, (m<10)?('0'+m):m);
	}
	
	// Events
	this.onLoadUsers = function (){
		this.drawUsers();
		
		// If users dropdown isn't loaded already, load it
		//if(!this.usersDropdownLoaded){
			this.drawUsersDropdown();
		//}
	}
	
	this.onPrivateArrive = function (fromUser){
		return this.startPrivate(fromUser);
	}
	
	this.onKeyDown = function(event){
		if(event.keyCode == 27){// Esc
			if(event.stopPropagation){
				event.stopPropagation()
			}else{
				event.cancelBubble = true;
			}
			
			if(event.preventDefault){
				event.preventDefault();
			}else{
				event.returnValue = false;
			};
		}
		
		if(event.ctrlKey && event.shiftKey){
			if(event.keyCode != 17){
				// For testing here
			}
			
			switch(event.keyCode){
				case 68: // Ctrl + Shift + D
					chat.debugInfo();
					
					if(event.stopPropagation){
						event.stopPropagation()
					}else{
						event.cancelBubble = true;
					}
					
					if(event.preventDefault){
						event.preventDefault();
					}else{
						event.returnValue = false;
					};
					break;
			}
		}
	}
	
	this.sendMessage = function(to, text, color, italic, bold, underline){
		// Save settings
		this.writeCookie('color' + this.channelId, color, 100);
		
		var style = "" + (italic?1:0) + (bold?1:0) + (underline?1:0);
		this.writeCookie('style' + this.channelId, style, 100);
		
		$.post('bin.php',
			{action: "sendMessage", key: this.ident, to: to, text: text, color: color, italic:italic, bold:bold, underline: underline}, 
			function(data, textStatus){
				if(data['do'] == 'quit'){
					chat.quit(data['code'], data['reason']);
				}
			},
			"json");
	}

	this.getCookie = function(name) {
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i = 0;i < ca.length;i++) {
		var c = ca[i];
		
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
		}
		return null;
	}
	
	this.writeCookie = function(name, value, days){
		if(days){
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = "; expires="+date.toGMTString();
		}else{
			var expires = "";
		}
		
		document.cookie = name+"=" + value + expires + "; path=/";
	}
	
	this.openProfile = function(login){
		return window.open('profile.php?key='+this.ident+'&show_me=' + login, "pic", "toolbar=no,status=no,menu=no,scrollbars=1,resizable=1,height=480,width=620,top=100,left=100");
	}
	
	this.quit = function(code, reason){
		window.top.document.location.href = this.baseURL + "/index.php?action=exit&key=" + this.ident + "&Error=" + code;
	}
}
