/* Karma MOD AJAX functions
-------------------------------------------------
	Author: m157y
	Version: 04 March 2010

	Copyright 2007-2010 David Lawson, m157y, A_Jelly_Doughnut
-------------------------------------------------*/

var karma = {
	httpRequest: null, // XMLHTTPRequest object
	usersPosts: [], // Array for connection between users and posts
	coordY: 0, // Mouse Y coordinate, used for box positioning
	iconsObj: null, // Buttons object

	/**
	* UI Functions
	*/
	// Show confirm/comment box
	showBox: function()
	{
		// Box already visible
		if (document.getElementById('karma-ajax').style.visibility == 'visible')
		{
			return;
		}

		// Set box top position
		document.getElementById('karma-ajax').style.top = (this.coordY - 100) + 'px';

		// Show box
		document.getElementById('karma-ajax').style.visibility = 'visible';

		// Change box style to loading
		document.getElementById('karma-ajax').className = 'karma-loading';

		// Enable parser of key presses
		this.eventAdd(document, 'keydown', this.parseKeyPress, false);
	},

	// Hide confirm/comment box
	hideBox: function()
	{
		// Hide box
		document.getElementById('karma-ajax').style.visibility = 'hidden';

		// Delete box content
		document.getElementById('karma-ajax').innerHTML = '';

		// Disable parser of key presses
		this.eventRemove(document, 'keydown', this.parseKeyPress, false);

		return false;
	},

	// Update page content
	updatePage: function()
	{
		// Ouch, we already loaded, we don't need any class
		document.getElementById('karma-ajax').className = '';

		// Update data, if we have proper XML response
		if (this.httpRequest.responseXML != null && this.httpRequest.responseXML.hasChildNodes())
		{
			var id = this.httpRequest.responseXML.getElementsByTagName('id')[0].firstChild.nodeValue;
			var xmlData = this.httpRequest.responseXML.getElementsByTagName('data')[0].firstChild.nodeValue;

			// On deleting set successfully deleted message,
			// but on updating set new karma value
			if (document.getElementById('cpr' + id) != undefined) // We're deleted karma
			{
				document.getElementById('cpr' + id).innerHTML = xmlData;
			}
			else if (document.getElementById('karma') != undefined) // We're at viewprofile/viewpm page
			{
				// Set new karma value
				document.getElementById('karma').innerHTML = xmlData;
			}
			else // We're at viewtopic page
			{
				// This is a loop, which will update karma values for all posts by karmaed user
				for (i = 0; i < this.usersPosts[id].length; i++)
				{
					document.getElementById('karma-' + this.usersPosts[id][i]).innerHTML = xmlData;
				}
			}

			// Hide karma buttons
			if (document.getElementById(this.iconsObj) != undefined)
			{
				document.getElementById(this.iconsObj).innerHTML = '';
			}

			// Hide confirm/comment box
			this.hideBox();

			// Exit function
			return;
		}

		// Load confirm/comment box
		document.getElementById('karma-ajax').innerHTML = this.httpRequest.responseText;
	},

	/**
	* AJAX functions
	*/
	// Send GET/POST query
	ajaxQuery: function(url, dataStr)
	{
		// If XMLHTTPRequest doesn't created, we must show error
		if (this.httpRequest == undefined)
		{
			return;
		}

		// If dataStr not null we must send POST query,
		// else it will be GET query
		if (dataStr != '')
		{
			this.httpRequest.open('POST', url, true);

			// Headers for POST query
			this.httpRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
			this.httpRequest.setRequestHeader('Content-length', dataStr.length);
			this.httpRequest.setRequestHeader('Connection', 'close');
		}
		else
		{
			this.httpRequest.open('GET', url, true);

			// Workaround for some browsers
			dataStr = null;
		}

		// On state changes we call our parser
		this.httpRequest.onreadystatechange = function (){ karma.ajaxDone(); };

		// Send data
		this.httpRequest.send(dataStr);
	},

	// On-load events
	ajaxDone: function()
	{
		// Show box, if needed
		// Also it'll show loading image
		this.showBox();

		// Exit function if reply not loaded
		if (this.httpRequest.readyState != 4)
		{
			return;
		}

		// Show error if loaded with error
		if (this.httpRequest.status != 200) 
		{
			alert(this.httpRequest.status + ' | ' + this.httpRequest.statusText);
			return;
		}

		// Call UI updater
		this.updatePage();
	},

	/**
	* Support functions
	*/
	// Init function, creates XMLHTTP object
	// and set functions to events
	init: function()
	{
		// Create XMLHTTP object
		if (window.XMLHttpRequest) // Safari, Opera, Mozilla, etc
		{
			this.httpRequest = new XMLHttpRequest();
		}
		else if (window.ActiveXObject) // Internet Explorer
		{
			this.httpRequest = new ActiveXObject('Msxml2.XMLHTTP');
			if (this.httpRequest == undefined) // Old Internet Explorer
			{
				this.httpRequest = new ActiveXObject('Microsoft.XMLHTTP');
			}
		}

		// Enable mouse coords catching
		this.eventAdd(document, 'mousemove', this.getMouseY, false);
	},

	// Adding values to user-posts array
	// Used at viewtopic for all posts by user updating
	linkPostToUser: function(user_id, post_id)
	{
		if (this.usersPosts[user_id] == undefined)
		{
			this.usersPosts[user_id] = new Array();
			this.usersPosts[user_id].push(post_id);
		}
		else
		{
			this.usersPosts[user_id].push(post_id);
		}
	},

	// Get mouse Y coordinates
	getMouseY: function(event)
	{
		if (event)
		{
			// Catch Y mouse coords
			if (typeof(event.pageY) == 'number') // Safari, Opera, Mozilla, etc
			{
				karma.coordY = event.pageY;
			}
			else // Internet Explorer
			{
				// In IE you must catch page scrolled height
				// document.documentElement.scrollTop used in IE6+
				scrollDiff = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
				karma.coordY = event.clientY + scrollDiff;
			}
		}
	},

	// Parse key presses
	parseKeyPress: function(event)
	{
		// On ESC press hide confirm/comment box
		if (event.keyCode == 27)
		{
			karma.hideBox();
		}
		else if (event.keyCode == 10 || (event.ctrlKey && event.keyCode == 13))
		{
			formObj = (document.getElementById('postform') != undefined) ? document.getElementById('postform') : document.getElementById('confirm');
			karma.update(formObj);
		}
	},

	// Generate url and dataStr and call query
	update: function(dataObj)
	{
		var dataStr = '';

		if (dataObj.getAttribute('action') != undefined)
		{
			// Catch user id
			dataStr = 'u=' + dataObj.u.value;

			// Enabled comments? Okay, we catch the message
			if (dataObj.message != undefined)
			{
				dataStr = dataStr + '&message=' + encodeURI(dataObj.message.value);
			}

			// Also we catch karma power, if it enabled
			if (dataObj.power != undefined)
			{
				dataStr = dataStr + '&power=' + dataObj.power.value;
			}

			// Catch topic icon, if it enabled
			if (dataObj.icon)
			{
				iconsCount = dataObj.icon.length;
				for (i = 0; i < iconsCount; i++)
				{
					if (dataObj.icon[i].checked)
					{
						dataStr = dataStr + '&icon=' + dataObj.icon[i].value;
					}
				}
			}

			// Catch post support fields, if we at viewtopic
			// Or catch pm support field, if we at viewpm
			if (dataObj.p != undefined)
			{
				dataStr = dataStr + '&f=' + dataObj.f.value; // Forum ID
				dataStr = dataStr + '&t=' + dataObj.t.value; // Topic ID
				dataStr = dataStr + '&p=' + dataObj.p.value; // Post ID
			}
			else if (dataObj.pm != undefined)
			{
				dataStr = dataStr + '&pm=' + dataObj.pm.value; // PM ID
			}

			// And, of course, we catch confirm fields
			if (dataObj.sess != undefined)
			{
				dataStr = dataStr + '&sess=' + dataObj.sess.value; // Session ID
				dataStr = dataStr + '&confirm_uid=' + dataObj.confirm_uid.value; // Confirm User ID
				dataStr = dataStr + '&confirm=' + encodeURI(dataObj.confirm.value); // Confirm button value
			}
			else
			{
				dataStr = dataStr + '&post=Submit'; // Submit button value
			}

			// Set icons object name
			this.iconsObj = 'karma-icons';
			if (dataObj.p != undefined) // At viewtopic we have post_id
			{
				this.iconsObj = this.iconsObj + '-' + dataObj.p.value;
			}

			// Catch url
			url = dataObj.getAttribute('action'); // Catch action attribute from <form>
		}
		else
		{
			// Catch url
			url = dataObj.getAttribute('href'); // Catch href attribute from <a>
		}

		// Prepare url for AJAX
		url = url.replace('&amp;', '&'); // Replace &amp; to &, because it doesn't work at JS
		url = url + '&ajax=true'; // And add ajax addition to url

		// Querying result to our url+data
		this.ajaxQuery(url, dataStr);

		return false;
	},

	/**
	* Events functions
	*/
	// Add event listener
	eventAdd: function(obj, event, listener, capture)
	{
		capture = capture || false; // If useCapture not specified, use false
		if (obj.addEventListener) // Safari, Opera, Mozilla, etc
		{
			obj.addEventListener(event, listener, capture);
		}
		else if (obj.attachEvent) // Internet Explorer
		{
			obj.attachEvent('on' + event, listener);
		}
	},

	// Remove event listener
	eventRemove: function(obj, event, listener, capture)
	{
		capture = capture || false; // If useCapture not specified, use false
		if (obj.removeEventListener) // Safari, Opera, Mozilla, etc
		{
			obj.removeEventListener(event, listener, capture);
		}
		else if (obj.detachEvent) // Internet Explorer
		{
			obj.detachEvent('on' + event, listener);
		}
	}
};

karma.init();