//**************************************************************************

//                               ajax_core.js

//                            -------------------

//   begin                : Saturday, Jul 16, 2005

//   copyright            : (C) 2005 alcaeus

//   email                : mods@alcaeus.org

//

//   $Id: ajax_core.js,v 1.5 2006/04/18 20:59:04 alcaeus Exp $

//

//**************************************************************************



//**************************************************************************

//

//   This program is free software; you can redistribute it and/or modify

//   it under the terms of the GNU General Public License as published by

//   the Free Software Foundation; either version 2 of the License, or

//   (at your option) any later version.

//

//**************************************************************************





//

// This is the only value you should change

// It defines the time in milliseconds that the script waits before automatically submitting the fields for usernames (New PM and username search)

//

var KEYUP_TIMEOUT = 500;



var request = null;

var error_handler = '';



// Don't want to use const, var works in JS 1.0 as well :)

var AJAX_OP_COMPLETED = 0;

var AJAX_ERROR = 1;

var AJAX_CRITICAL_ERROR = 2;

var AJAX_POST_SUBJECT_EDITED = 3;

var AJAX_POST_TEXT_EDITED = 4;

var AJAX_POLL_RESULT = 5;

var AJAX_WATCH_TOPIC = 6;

var AJAX_LOCK_TOPIC = 7;

var AJAX_MARK_TOPIC = 8;

var AJAX_MARK_FORUM = 9;

var AJAX_PM_USERNAME_FOUND = 10;

var AJAX_PM_USERNAME_SELECT = 11;

var AJAX_PM_USERNAME_ERROR = 12;

var AJAX_PREVIEW = 13;



var AJAX_DEBUG_RESULTS = 0;

var AJAX_DEBUG_REQUEST_ERRORS = 0;

var AJAX_DEBUG_HTML_ERRORS = 0;



//

// Determine whether AJAX is available

//

if (window.XMLHttpRequest)

{

	var tempvar = new XMLHttpRequest();

	ajax_core_defined = (tempvar == null) ? 0 : 1;

	delete(tempvar);

}

//Use the IE/Windows ActiveX version

else if (window.ActiveXObject)

{

	var tempvar= new ActiveXObject("Microsoft.XMLHTTP");

	ajax_core_defined = (tempvar == null) ? 0 : 1;

	delete(tempvar);

}

else

{

	ajax_core_defined = 0;

}



//

// General function. This one is the mother of all AJAX functions ;)

//

function loadXMLDoc(url, params, submitmethod, changehandler)

{

	if ((submitmethod != 'GET') && (submitmethod != 'POST'))

	{

		submitmethod = 'GET';

	}

	

	//Use the native object available in all browsers (IE >= 7)

	if (window.XMLHttpRequest)

	{

		request = new XMLHttpRequest();

		var is_activex = false;

	}

	//Use the ActiveX version for IE < 7

	else if (window.ActiveXObject)

	{

		request = new ActiveXObject("Microsoft.XMLHTTP");

		var is_activex = true;

	}

	

	if (!request)

	{

		return false;

	}

	

	eval("request.onreadystatechange = "+changehandler);

	if (submitmethod == 'POST')

	{

		request.open(submitmethod, url, true);

		request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=' + ajax_page_charset);

		request.send(params);

	}

	else

	{

		request.open(submitmethod, url + '?' + params, true);

		request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=' + ajax_page_charset);

		if (is_activex)

		{

			// This seems to be an issue in the ActiveX-Object: no parameter needed

			request.send();

		}

		else

		{

			// The native versions take null as a parameter

			request.send(null);

		}

	}

	

	return true;

}



function getTagValues(tagname, haystack)

{

	var tag_array = haystack.getElementsByTagName(tagname);

	var result_array = Array();

	for (i = 0; i < tag_array.length; i++)

	{

		result_array[i] = (tag_array[i].firstChild && tag_array[i].firstChild.data) ? tag_array[i].firstChild.data : '';

	}

	return result_array;

}



function getFirstTagValue(tagname, haystack)

{

	var tag_array = haystack.getElementsByTagName(tagname);

	if ((tag_array.length > 0) && (tag_array[0].firstChild))

	{

		return (tag_array[0].firstChild.data) ? tag_array[0].firstChild.data : '';

	}

	return '';

}





//

// This function is used to parse any standard error file

//

function error_req_change()

{

	//Check if the request is completed, if not, just skip over

	if (request.readyState == 4)

	{

		var result_code = AJAX_OP_COMPLETED;

		var error_msg = '';

		//If the request wasn't successful, we just hide any information we have.

		if (request.status == 200)

		{

			var response = request.responseXML.documentElement;

			if (AJAX_DEBUG_RESULTS)

			{

				alert(request.responseText);

			}

			//Don't react if no valid response was received

			if (response != null)

			{

				result_code = getFirstTagValue('result', response);

				error_msg = getFirstTagValue('error_msg', response);

			}

		}

		

		eval(error_handler+"(result_code, error_msg);");

		delete request;

	}

}



//

// Just like sprintf() in php

// replacements can be any type

//

function sprintf(text, replacements)

{

	var i = 0;

	//This prevents us from having to create an array for replacements with one value

	//checking for type 'object' may not be really smart, but who cares ;)

	if ((typeof replacements) != 'object')

	{

		var repl = Array(1);

		repl[0] = replacements;

	}

	else

	{

		var repl = replacements;

	}

	

	while (((charindex = text.indexOf('%s')) >= 0) && (i < repl.length))

	{

		var temptext = text.substr(0, charindex);

		text = temptext + repl[i] + text.substr(charindex+2, text.length);

		i++;

	}

	

	return text;

}



function getElementById(ElementId)

{

	if (document.documentElement)

	{

		return document.getElementById(ElementId);

	}

	else

	{

		return document.all[ElementId];

	}

}



function rtrim(text)

{

	if (text == '')

	{

		return '';

	}

	

	var part = '';

	var i = text.length;

	do

	{

		part = text.substring(i-1, i);

		i--;

	} while ((part == ' ') || (part == '\n') || (part == '\r'));

	text = text.substring(0, i+1);

	

	return text;

}

	

function ltrim(text)

{

	if (text == '')

	{

		return '';

	}

	

	var part = '';

	var i = 0;

	do

	{

		part = text.substring(i, i+1);

		i++;

	} while ((part == ' ') || (part == '\n') || (part == '\r'));

	text = text.substring(i-1, text.length);

	

	return text;

}



function trim(text)

{

	return ltrim(rtrim(text));

}



function setClickEventHandler(obj, handler)

{

	if (obj.onclick)

	{

		eval('obj.onclick = function() { '+handler+' }');

	}

	else

	{

		obj.setAttribute('onclick', handler, 'false');

	}

}



function setInnerText(obj, newtext)

{

	if (newtext == '')

	{

		newtext = '&nbsp;';

	}

	

	if (obj.innerText)

	{

		obj.innerText = newtext;

	}

	else if (obj.firstChild)

	{

		obj.firstChild.nodeValue = newtext;

	}

	else

	{

		obj.innerHTML = newtext;

	}

}



// Separate escaping function to fix bug with + and % signs in QuickEdit and QuickPreview

function ajax_escape(text)

{

	text = escape(text).replace(/(\%)/g, "%25");

	return text.replace(/(\+)/g, "%2b");

}



// This function is a workaround for long posts being truncated in PITA browsers

function parseResult(response)

{

	var res = response.match(/\<response\>((.|\s)+?)\<\/response\>/gm);

	var fields = new Array();

	if (res != null)

	{

		contents = RegExp.$1;

		res = contents.match(/\<.+?\>((.|\s)+?)\<\/.+?\>/gm);

		if (res == null)

		{

			return fields;

		}

		

		for (var i = 0; i < res.length; i++)

		{

			var field = new Array();

			res[i].match(/^\<(.+?)\>/g);

			field.push(RegExp.$1);

			res[i].match(/\<.+?\>((.|\s)+)\<\/.+?\>/gm);

			field.push(unhtmlspecialchars(RegExp.$1));

			

			fields.push(field)

		}

	}

	

	return fields;

}



function unhtmlspecialchars(text)

{

	text = text.replace(/&quot;/g, '"');

	text = text.replace(/&lt;/g, '<');

	text = text.replace(/&gt;/g, '>');

	text = text.replace(/&amp;/g, '&');

	

	return text;

}



function utf8_decode(text)

{

	while (res = text.match(/&#(\d{1,4});/))

	{

		num = res[0];

		pos = text.indexOf(num);

		if (pos == -1)

		{

			return text;

		}

		

		text = text.substring(0, pos) + unescape('%u' + parseInt(num.substring(2, num.length-1)).toString(16)) + text.substring(pos+num.length, text.length);

	}

	

	return text;

}

