// JavaScript Document
function ChatClass (containerName, optionObj) {
	
	this.containerName = containerName;
	this.$container = $(containerName);
	
	this.option = {
		game: 'hg',
		gameID: 1,
		gameTurn: -1,
		gameTurnShow: -1,
		enabled: false,
		width: this.$container.width(),
		height: this.$container.height(),
		poll: true,
		pollPeriod: 5000,
		jsonRoot: ''
	};
	$.extend(this.option, optionObj);
	
	this.pollsterIID = -1;
	this.lastMessageID = -1;
	
	this.urls = {
		chat:this.option.jsonRoot+'json/chat.php',
		user:this.option.jsonRoot+'json/user.php'
	}
	this.self = {};
	
	this.init = function(){
		this.$container
			.addClass('chatContainer')
			.addClass('rounded6')
			.html('<div class="chatMessages"></div>');
		$('div.chatMessages', this.$container).addClass('rounded4');
		if(this.option.enabled) {
			this.$container
				.addClass('chatEnabled')
				.append($( 	'<div class="chatInput"><form action="#" id="chatForm" onSubmit="return false;">' +
							'<input type="text" id="chatInputMessage" id="chatInputMessage" maxSize="250" value="" />' +
							'<input type="submit" id="chatInputSubmit" id="chatInputSubmit" value="Send" />' +
				  			'</form></div>'));
			$('#chatInputSubmit', this.$container).addClass('rounded4').bind('click', {chat:this}, function(e){ e.data.chat.sendMessage(); });	
			$('#chatInput', this.$container).bind('submit', {chat:this}, function(e){ e.data.chat.sendMessage(); return false; });
			$('#chatInputMessage', this.$container).addClass('rounded4').focus();
		};
		this.size(this.option.width, this.option.height,this.option.enabled);
		this.getSelf();
	};
	
	this.size = function(newWidth, newHeight, showInput){
		if (showInput === undefined) { showInput = this.option.enabled; }
		this.option.width = newWidth;
		this.option.height = newHeight;
		this.$container.width(this.option.width).height(this.option.height);
		$('div.chatMessages', this.$container).height(this.option.height-8).width(this.option.width-8);
		if(showInput) {
			$('div.chatMessages', this.$container).height(this.option.height-28);
			$('div.chatInput', this.$container).width(this.option.width-6).show();
			$('#chatInputMessage', this.$container).width(this.option.width-66);
		} else {
			$('div.chatInput', this.$container).hide();
		};
		this.updateScroll();
	}
	
	this.turn = function(newTurn) {
		if (newTurn !== undefined && newTurn !== null && newTurn !== '' && !isNaN(newTurn)) {
			this.option.gameTurn = newTurn;
		}
	}

	/*---------------------------------------------------------------------------
		Get the user's details
	---------------------------------------------------------------------------*/
	this.getSelf = function(){
		$.ajax( {
			url:this.urls.user,
			data:'action=self',
			type:'GET',
			dataType:'json',
			callingObject:this,
			success:function(data, textStatus) {
					if(data.self !== undefined) { this.callingObject.self = data.self; }
					this.callingObject.startPollster();
					this.callingObject.getUpdate();
				},
			error:function (XMLHttpRequest, textStatus, errorThrown) {
					alert("Error:\n" + XMLHttpRequest + "\n" + textStatus + "\n" + errorThrown);
				}
		});	
	};

	/*---------------------------------------------------------------------------
		Turn on and off pollster
	---------------------------------------------------------------------------*/
	this.startPollster = function() {
		clearInterval(this.pollsterIID);
		if (this.option.poll) {
			var hgc = this;
			this.pollsterIID = setInterval(function(){hgc.getUpdate(true);}, this.option.pollPeriod);
		}
	};
	
	this.stopPollster = function() {
		clearInterval(this.pollsterIID);
	};
	
	/*---------------------------------------------------------------------------
		Add messages to display
	---------------------------------------------------------------------------*/
	
	this.appendMessage = function(messageData, ignoreSelf) {
		var i, ilen;
		var msgNew = false;
		var msgClass = '';
		var $msgContiner = $('div.chatMessages', this.$container);
		for (i=0, ilen=messageData.length; i < ilen; i++ ) {
			
			if (messageData[i][4] !== undefined && messageData[i][4] !== this.option.gameTurnShow) {
				if (messageData[i][4] === 0) {
					$msgContiner.append('<div class="chatMessage system">Game setup</div>');
				} else {
					$msgContiner.append('<div class="chatMessage system">Game turn '+messageData[i][4]+'</div>');
				}
				this.option.gameTurnShow = messageData[i][4];
			}
			
			if(!ignoreSelf || messageData[i][1] != this.self.id) {
				msgClass = '';
				if (messageData[i][1] === this.self.id) { msgClass = 'self'; } 
				else if (messageData[i][1] === 0) { msgClass = 'system'; }
				$msgContiner.append('<div class="chatMessage '+msgClass+' rounded3"><span class="chatMessageUser">'+messageData[i][2]+':</span> '+messageData[i][3]+'</div>');
				msgNew = true;
			}
			if (this.lastMessageID < messageData[i][0]) { this.lastMessageID = messageData[i][0]; }
		}
		if (msgNew) { this.updateScroll(); }
	};
	
	this.updateScroll = function() {
		var $msgContiner, $lastItem, contentHeight;
		$msgContiner = $('div.chatMessages', this.$container);
		$lastItem = $('div.chatMessage:last', $msgContiner);
		if ($lastItem.length === 0) { return; }
		contentHeight = $msgContiner.scrollTop() + $lastItem.position().top + $lastItem.outerHeight();
		if (contentHeight > $msgContiner.height()) { $msgContiner.scrollTop( contentHeight - $msgContiner.height() ); }		
	};
	
	/*---------------------------------------------------------------------------
		Get Updates
	---------------------------------------------------------------------------*/
	
	this.getUpdate = function(ignoreSelf) {
		clearInterval(this.pollsterIID);
		if (ignoreSelf === undefined) { ignoreSelf = false; }
		var dataArray = [];
		
		dataArray.push('action=get');
		dataArray.push('g=' + this.option.game);
		dataArray.push('gid=' + this.option.gameID);
		dataArray.push('lm=' + this.lastMessageID);
		dataArray.push('ts=' + new Date().getTime());
		
		$.ajax( {
			url:this.urls.chat,
			data:dataArray.join('&'),
			type:'POST',
			dataType:'json',
			callingObject:this,
			ignoreSelf:ignoreSelf,
			success:function(data, textStatus) {
					if(data.messages !== undefined && data.messages.length > 0) { this.callingObject.appendMessage(data.messages, this.ignoreSelf); }
				},
			error:function (XMLHttpRequest, textStatus, errorThrown) {
					//alert("Error:\n" + XMLHttpRequest + "\n" + textStatus + "\n" + errorThrown);
				}
		});	
		
		if (this.option.poll) {
			var hgc = this;
			this.pollsterIID = setInterval(function(){hgc.getUpdate(true);}, this.option.pollPeriod);
		}
	};
	
	/*---------------------------------------------------------------------------
		Send Message
	---------------------------------------------------------------------------*/
	
	this.sendMessage = function() {
		var messageStr = $.trim($('#chatInputMessage').val());
		var dataArray = [];
		$('#chatInputMessage').val('');
		if (messageStr === '') { return false; }
		
		if (this.option.gameTurn !== this.option.gameTurnShow) {
			if (this.option.gameTurn === 0) {
				$('div.chatMessages', this.$container).append('<div class="chatMessage system">Game setup</div>');
			} else {
				$('div.chatMessages', this.$container).append('<div class="chatMessage system">Game turn '+this.option.gameTurn+'</div>');
			}
			this.option.gameTurnShow = this.option.gameTurn;
		}
		
		$('div.chatMessages', this.$container).append('<div class="chatMessage self"><span class="chatMessageUser">'+this.self.name+':</span> '+messageStr+'</div>');
		this.updateScroll();
		
		// Do message preprocessing here
		messageStr = messageStr.replace(/\\/g, "\\\\");
		messageStr = messageStr.replace(new RegExp('&', "g"), '\&');
		messageStr = messageStr.replace(new RegExp('"', "g"), '\"');
		
		dataArray.push('action=set');
		dataArray.push('g=' + this.option.game);
		dataArray.push('gid=' + this.option.gameID);
		dataArray.push('gt=' + this.option.gameTurn);
		dataArray.push('msg=' + escape(messageStr));
		dataArray.push('ts=' + new Date().getTime());
		
		// Send message
		$.ajax( {
			url:this.urls.chat,
			data:dataArray.join('&'),
			type:'POST',
			dataType:'json',
			success:function(data, textStatus) {
					if($.trace) { $.trace(data); }
				},
			error:function (XMLHttpRequest, textStatus, errorThrown) {
					alert("Error:\n" + XMLHttpRequest + "\n" + textStatus + "\n" + errorThrown);
				}
		});
		
		this.getUpdate(true);
		$('#chatInputMessage').focus();
	};
	
	/*---------------------------------------------------------------------------
		Call Init
	---------------------------------------------------------------------------*/
	this.init();
	
}
