function PreviousElement(element)
{
	if (element.previousSibling.tagName)
		return element.previousSibling;
	else
		return element.previousSibling.previousSibling;
}
function NextElement(element)
{
	if (element.nextSibling.tagName)
		return element.nextSibling;
	else
		return element.nextSibling.nextSibling;
}
function FirstChildElement(element)
{
	if (element.firstChild && element.firstChild.tagName)
		return element.firstChild;
	else
		return element.childNodes[1];
}

function HookEvent(element, event_name, func)
{
	if (element.attachEvent)
		element.attachEvent("on"+event_name, func);
	else if (element.addEventListener)
		element.addEventListener(event_name, func, false);
	else
		alert("Cannot attach event");
}

function sprintf()
{
	if (!arguments || arguments.length < 1 || !RegExp)
	  return;
	
	var str = arguments[0];
	var re = /([^%]*)%('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X)(.*)/;
	var a = b = [], numSubstitutions = 0, numMatches = 0;
	while (a = re.exec(str))
	{
		var leftpart = a[1], pPad = a[2], pJustify = a[3], pMinLength = a[4];
		var pPrecision = a[5], pType = a[6], rightPart = a[7];
		
		numMatches++;
		if (pType == '%')
		   subst = '%';
		else
		{
			numSubstitutions++;
			if (numSubstitutions >= arguments.length)
			{
			  alert('Error! Not enough function arguments (' + (arguments.length - 1)
			     + ', excluding the string)\n'
			     + 'for the number of substitution parameters in string ('
			     + numSubstitutions + ' so far).');
			}
			var param = arguments[numSubstitutions];
			var pad = '';
				if (pPad && pPad.substr(0,1) == "'") pad = leftpart.substr(1,1);
			 	else if (pPad) pad = pPad;
			var justifyRight = true;
			  if (pJustify && pJustify === "-") justifyRight = false;
			var minLength = -1;
			  if (pMinLength) minLength = parseInt(pMinLength);
			var precision = -1;
			  if (pPrecision && pType == 'f')
			    precision = parseInt(pPrecision.substring(1));
			var subst = param;
			switch (pType)
			{
			case 'b':
			  subst = parseInt(param).toString(2);
			  break;
			case 'c':
			  subst = String.fromCharCode(parseInt(param));
			  break;
			case 'd':
			  subst = parseInt(param) ? parseInt(param) : 0;
			  break;
			case 'u':
			  subst = Math.abs(param);
			  break;
			case 'f':
			  subst = (precision > -1)
			   ? Math.round(parseFloat(param) * Math.pow(10, precision))
			    / Math.pow(10, precision)
			   : parseFloat(param);
			  break;
			case 'o':
			  subst = parseInt(param).toString(8);
			  break;
			case 's':
			  subst = param;
			  break;
			case 'x':
			  subst = ('' + parseInt(param).toString(16)).toLowerCase();
			  break;
			case 'X':
			  subst = ('' + parseInt(param).toString(16)).toUpperCase();
			  break;
			}
			var padLeft = minLength - subst.toString().length;
			if (padLeft > 0)
			{
			  var arrTmp = new Array(padLeft+1);
			  var padding = arrTmp.join(pad?pad:" ");
			}
			else
			{
			  var padding = "";
			}
		}
		str = leftpart + padding + subst + rightPart;
	}
	return str;
}

function urlencode(string)
{
	string = string.replace(/\r\n/g,"\n");
	
	var utftext = "";
	for (var n = 0; n < string.length; n++) 
	{
		var c = string.charCodeAt(n);
		
		if (c < 128) {
			utftext += String.fromCharCode(c);
		}
		else if((c > 127) && (c < 2048)) {
			utftext += String.fromCharCode((c >> 6) | 192);
			utftext += String.fromCharCode((c & 63) | 128);
		}
		else {
			utftext += String.fromCharCode((c >> 12) | 224);
			utftext += String.fromCharCode(((c >> 6) & 63) | 128);
			utftext += String.fromCharCode((c & 63) | 128);
		}
	}
	return utftext;
}

function FindInSelect(text_input)
{
	var text = text_input.value.toLowerCase();
	var select = NextElement(text_input);
	
	if (text != '')
	{
		for (var i = 0; i<select.options.length; i++)
		{
			if (select.options[i].text.toLowerCase() == text)
			{
				if (i != 0)
				{
					select.options[i].selected = true;
					if (select.onchange)
						select.onchange();
					return;
				}
			}
		}
		
		for (var i = 0; i<select.options.length; i++)
		{
			if (select.options[i].text.toLowerCase().indexOf(text) != -1)
			{
				if (i != 0)
				{
					select.options[i].selected = true;
					if (select.onchange)
						select.onchange();
					return;
				}
			}
		}
	}
	
	select.options[0].selected = true;
	if (select.onchange)
		select.onchange();
}