/**
 * 定数定義
 **/
var serverURL = "server.php";
var logMaxCount = 300;

/**
 * グローバルな変数達
 **/
var request = null;
var dom;
var logContainer;
var formContainer;
var nextLoadLogId = 0;
var reloadTimer;

/**
 * 初期化
 **/
function initialize()
{
	logContainer = document.getElementById("ChatLog");
	formContainer = document.getElementById("ChatForm");
	
	formContainer.onsubmit = function () { onSubmitMessage(); return false; }
	formContainer.name.onfocus = onNameFocus;
	formContainer.name.onblur = onNameBlur;
	
	getLog(0, logMaxCount, nextLoadLogId);
	
	reloadTimer = setInterval(autoReload, 100000);
	
	showMessage(null, 'Hello Avatar!', null, 'information');

/**
	formContainer.message.focus();
 **/
 }

/**
 * 名前入力欄
 **/
function onNameFocus()
{
	if (this.value == this.defaultValue)
	{
		formContainer.name.value = "";
	}
}

/**
 * 名前入力欄
 **/
function onNameBlur()
{
	if (this.value == "")
	{
		this.value = this.defaultValue;
	}
}

/**
 * メッセージ送信チェック
 **/
function onSubmitMessage()
{
	if (request !== null && request.readyState != 0 && request.readyState != 4)
	{
		return;
	}
	
	var name = formContainer.name.value;
	var message = formContainer.message.value;
	
	if (name == "" || name == formContainer.name.defaultValue)
	{
		formContainer.name.focus();
		
		return;
	}

	if (message == "" || message == formContainer.message.defaultValue)
	{
		formContainer.message.focus();
		
		return;
	}

	formContainer.message.value = "";
	formContainer.message.focus();
	
	postMessage(name, message, '');
}

/**
 * メッセージ送信開始
 **/
function postMessage(name, message, type)
{
	var dom = createDOMDocument();
	
	var documentElement = dom.appendChild(dom.createElement("Post"));
	
	var nameNode = dom.createElement("Name");
	nameNode.appendChild(dom.createTextNode(name));
	documentElement.appendChild(nameNode);
	
	var messageNode = dom.createElement("Message");
	messageNode.appendChild(dom.createTextNode(message));
	documentElement.appendChild(messageNode);
	
	var typeNode = dom.createElement("Type");
	typeNode.appendChild(dom.createTextNode(type));
	documentElement.appendChild(typeNode);
	
	request = createXMLHttpRequest();
	request.open("POST", serverURL, true);
	request.onreadystatechange = processPostMessage;
	request.send(dom);
}

/**
 * メッセージ送信プロセス
 **/
function processPostMessage()
{
	if (request.readyState != 4)
	{
		return;
	}
	
	if (request.status != 200)
	{
		showMessage(null, "エラーが発生しました。HTTP ステータス コード: " + request.status + " / " + request.responseText, null, "system");

		return;
	}
	
	getLog(0, logMaxCount, nextLoadLogId);
}

/**
 * メッセージ取得開始
 **/
function getLog(start, count, sinceId)
{
	var dom = createDOMDocument();
	dom.appendChild(dom.createElement("Get"));
	
	var documentElement = dom.documentElement;
	
	var startNode = dom.createElement("Start");
	startNode.appendChild(dom.createTextNode(start));
	documentElement.appendChild(startNode);
	
	var countNode = dom.createElement("Count");
	countNode.appendChild(dom.createTextNode(count));
	documentElement.appendChild(countNode);
	
	if (sinceId !== null)
	{
		var sinceIdNode = dom.createElement("SinceId");
		sinceIdNode.appendChild(dom.createTextNode(sinceId));
		documentElement.appendChild(sinceIdNode);
	}
	
	request = createXMLHttpRequest();
	request.open("POST", serverURL, true);
	request.onreadystatechange = processGetLog;
	request.send(dom);
}

/**
 * メッセージ取得プロセス
 **/
function processGetLog()
{
	if (request.readyState != 4)
	{
		return;
	}
	
	if (request.status != 200)
	{
		showMessage(null, "エラーが発生しました。HTTP ステータス コード: " + request.status, null, "system");

		return;
	}
	
	var dom = request.responseXML;
	
	if (dom === null || dom.documentElement === null)
	{
		showMessage(null, "サーバー エラーです。詳細: " + request.responseText, null, "system");

		return;
	}
	
	var documentElement = dom.documentElement;

	for (var i = 0, iMax = documentElement.childNodes.length; i < iMax; i++)
	{
		var messageNode = documentElement.childNodes.item(i);
		
		var id = null;
		var name = null;
		var message = null;
		var date = new Date()
		var type = null;

		for (var j = 0, jMax = messageNode.childNodes.length; j < jMax; j++)
		{
			var node = messageNode.childNodes.item(j);
			
			switch (node.nodeName)
			{
				case 'Id':
					if (node.hasChildNodes()) id = parseInt(node.childNodes.item(0).nodeValue);
					break;

				case 'Name':
					if (node.hasChildNodes()) name = node.childNodes.item(0).nodeValue;
					break;

				case 'Message':
					if (node.hasChildNodes()) message = node.childNodes.item(0).nodeValue;
					break;

				case 'Date':
					if (node.hasChildNodes()) date.setTime(parseInt(node.childNodes.item(0).nodeValue) * 1000);
					break;

				case 'Type':
					if (node.hasChildNodes()) type = node.childNodes.item(0).nodeValue;
					break;
			}
		}
		
		if (id !== null)
		{
			nextLoadLogId = id + 1;
		}
		
		showMessage(name, message, date, type, i + 1 == iMax);
		
	}
}

/**
 * メッセージを描画する
 **/
function showMessage(name, message, date, type, refresh)
{
	while (logContainer.childNodes.length > logMaxCount)
	{
		logContainer.removeChild(logContainer.firstChild);
	}
	
	var pElement = document.createElement("p");
	pElement.className = type;
	
	if (name != null)
	{
		var nameElement = document.createElement("span");
		nameElement.className = "name";
		nameElement.appendChild(document.createTextNode(name));
		
		pElement.appendChild(nameElement);
		pElement.appendChild(document.createTextNode(" : "));
		
		if (name == formContainer.name.value)
		{
			pElement.className = "self";
		}
	}
	
	var messageElement = document.createElement("span");
	messageElement.className = "message";
	messageElement.appendChild(document.createTextNode(message));

	pElement.appendChild(messageElement);
	
	if (date instanceof Date)
	{
		var dateElement = document.createElement("span");
		dateElement.className = "date";
		
		var month = date.getMonth() + 1;
		var day = date.getDate();
		var hours = date.getHours();
		var minutes = date.getMinutes();
		var seconds = date.getSeconds();
		
		dateElement.appendChild(document.createTextNode(
						month + "/" + day + " " +
						(hours < 10 ? "0" : "") + hours + ":" +
						(minutes < 10 ? "0" : "") + minutes + ":" +
						(seconds < 10 ? "0" : "") + seconds
					));
		
		pElement.appendChild(document.createTextNode(" "));
		pElement.appendChild(dateElement);
	}
	
	logContainer.appendChild(pElement);
	
	if (refresh !== false)
	{
		logContainer.scrollTop += 9999999;
	}
}

/**
 * 自動リロード
 **/
function autoReload()
{
	getLog(0, logMaxCount, nextLoadLogId);
}

// OnLoad イベント ハンドラの登録
if (window.XMLHttpRequest || window.ActiveXObject)
{
	window.onload = initialize;
}
