/**
 * Simple shoutbox, written by me for use on nihongoresources.com
 * (c) 2010 Michiel "Pomax" Kamermans
 *
 * consists of:
 *
 *  - shoutbox.php
 *  - shoutbox.js
 *  - shoutbox.css
 *  - shoutbox.db		sqlite3, layout: (tss integer [=seconds], tsms integer [=milliseconds], name text, comment text)
 */


// value pairs.
var shoutbox_location;
var shoutbox_default_location = "/shoutbox";

var shoutbox_message_height;
var shoutbox_default_message_height = '300px';

var shoutbox_update_interval;
var shoutbox_default_update_interval = '15000';	// 15 seconds = 15,000 milliseconds

// check if addLoadEvent is defined. If it isn't, define it.
if(typeof addLoadEvent == 'undefined') {
	this.addLoadEvent = function(func) {
		var oldonload = window.onload;
		if (typeof window.onload != 'function') { window.onload = func; }
		else { window.onload = function() { if (oldonload) { oldonload(); } func(); }}}}

// add the shoutbox loader to the window.onload queue
addLoadEvent(shoutbox_loadShoutBox);

// generic "get some JSON object from a URL" function (synchronised)
function shoutbox_loadShoutBox() 
{
	// load shoutbox CSS file
	shoutbox_css = document.createElement("link");
	shoutbox_css.setAttribute("rel", "stylesheet");
	shoutbox_css.setAttribute("type", "text/css");
	shoutbox_css.setAttribute("href", "/shoutbox/shoutbox.css?t="+(new Date()).getTime());
	document.getElementsByTagName("head")[0].appendChild(shoutbox_css);
	// launch shoutbox
	shoutbox_loadProperties();
  	shoutbox_init();
}

// sets up the framework and does an initial data load
function shoutbox_init()
{
	shoutbox_loadFrame();
  	shoutbox_checkUpdates();
}

function shoutbox_loadProperties()
{
	// load json properties
	props = document.getElementById('shoutbox').innerHTML;
	props = props.substring(4,props.length-3);
	document.getElementById('shoutbox').innerHTML='';
	if(props!="") { props = eval("("+props+")"); } else { props = {}; }
	// assign internal values
	shoutbox_message_height = props.shoutbox_message_height || shoutbox_default_message_height;
	shoutbox_update_interval = props.shoutbox_update_interval || shoutbox_default_update_interval;
	shoutbox_location = props.shoutbox_location || shoutbox_default_location;
}

// make input strings safe for URL transport.
function shoutbox_makesafe(input) 
{
	str = input.replace(/ /g,"0x20");
	str = str.replace(/\$/g,"0x24");
	str = str.replace(/&/g,"0x26");
	str = str.replace(/'/g,"0x27");
	str = str.replace(/\"/g,"0x22");
	str = str.replace(/\+/g,"0x2B");
	str = str.replace(/=/g,"0x3D");
	str = str.replace(/\?/g,"0x3F");
	str = str.replace(/</g,"0x3C");
	str = str.replace(/>/g,"0x3E");
	return str;
}

// post an entry to the shoutbox
function shoutbox_post()
{
	var name = document.getElementById('sbname').value;
	var comment = document.getElementById('sbcomment').value;
	
	// check name for illegal characters
	var safe_name = name.replace(/[!"#$%&()*+,-/:;<=>?@\[\]\\^`{|} ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿]/g,'');
	if(name != safe_name) { alert('For safety reasons, most special punctuations and symbols are not allowed in names.'); }
	else
	{
		comment = shoutbox_makesafe(comment);
		var url = shoutbox_location + "/shoutbox.php?post=post&name="+shoutbox_makesafe(name)+"&comment="+comment;
		getContentFromURL(url);
		shoutbox_init();
	}
}

// clears the text elements and sets their font color to black
function shoutbox_se(element)
{
	if(element.value && (element.value=='What do you want to say?' || element.value=='Your name...'))
	{
		element.value='';
		element.style.color = '#000';
	}
}

// build the html framework
function shoutbox_loadFrame()
{
	// clear shoutbox
	var shoutbox = document.getElementById('shoutbox');
	if(shoutbox.hasChildNodes()) {
		while(shoutbox.childNodes.length>= 1) {
			shoutbox.removeChild(shoutbox.firstChild); }}
	// build master 
	var master = document.createElement("div");
	var sbcontent = document.createElement("div");
	sbcontent.setAttribute('style', 'max-height: '+shoutbox_message_height+'; overflow: auto; overflow-x: hidden; font-size: 80%; border: 1px solid black; border-bottom: none;');
	sbcontent.id = 'shoutbox_pipe';
	master.appendChild(sbcontent);
	var postform = document.createElement("div");
	postform.setAttribute('class', 'sbf');
	postform.innerHTML =	"<input type='textfield' id='sbcomment' class='sbc' value='What do you want to say?' onfocus='shoutbox_se(this)' />"+
					"<input type='textfield' id='sbname' class='sbn' value='Your name...'  onfocus='shoutbox_se(this)' />"+
					"<input type='button' id='sbshout' class='sbs' value='Say it!' onclick='shoutbox_post()'/>";
	master.appendChild(postform);
	shoutbox.appendChild(master);
}

// perform a JSON retrieval for newly posted messages
function shoutbox_checkUpdates()
{
	var ID_SECONDS = 0;
	var ID_MILLIS = 1;
	var ID_NAME = 2;
	var ID_COMMENT = 3;
	var content = getContentFromURL(shoutbox_location + '/shoutbox.php?boxcontent');
	var comments = content.comments;
	// the first time you use the shoutbox, there will be no posts. We need to catch that.
	if(typeof(comments)!="undefined")
	{
		var pipe = ""
		for(i=0, end=comments.length; i<end; i++)
		{
			var date = new Date(1000 * parseInt(comments[i][ID_SECONDS],10));
			date = date.toLocaleString()
			date = date.split(" GMT");
			date = date[0];
			var name = comments[i][ID_NAME];
			var comment = comments[i][ID_COMMENT];
			var thiscomment = "<div class='sbe'><div class='sbp'>" + name.toLowerCase() + "</div><div class='sbc'>" + comment + "</div><div class='sbt'>" + date + "</div></div>\n";
			pipe = thiscomment + pipe;
		}
		document.getElementById('shoutbox_pipe').innerHTML = pipe;
	}
	
	// asynchronous recursion
	setTimeout("shoutbox_checkUpdates()", shoutbox_update_interval);
}

// generic "get some JSON object from a URL" function (synchronised)
// we could rely on jQuery, but relying on a huge library just for get()
// kind of defeats the idea of a small shoutbox script...
function getContentFromURL(url)
{
	// get information from database - is this character already defined?
	var xmlHttp;
	var error=false;
	try { xmlHttp = new XMLHttpRequest();  }
	catch (requesterror) {
		try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");  }
		catch (activexerror) {
			try { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); }
			catch (browsererror) { error=true; alert('Your browser seems incompatible with the XMLHTTP object, this page will not work properly for you.'); }}}

	// fire off a request, if we can
	if(!error) {
		xmlHttp.open("GET", url, false);
		xmlHttp.send(null);
		// synchronous means we get the data back
		var response = xmlHttp.responseText;
		if(response!="") {
			// JSON
			if(response.substring(0,1)=='{') { return eval('(' + response + ')'); }
			// Plain text or HTML
			else { return response; }}}
	// failed query
	return false; 			
}
