function LoadXML (url, onload)
{
	var req;
	if (window.XMLHttpRequest)
		req = new XMLHttpRequest ();
	else if (window.ActiveXObject)
		req = new ActiveXObject ("Microsoft.XMLHTTP");

	req.onreadystatechange = function ()
	{
		if (req.readyState == 4)
		{
			onload ((req.status >= 400) ? null : req);
			//req.abort ();
		}
	};
	req.open ("GET", url, true);
	setTimeout (function () { req.send (null); }, 1);
}

var _mapTransforms = new Object ();

function TransformXML (strXMLURL, strXSLURL, callback)
{
	if (typeof (strXMLURL) == 'string')
		LoadXML (strXMLURL, OnXMLLoaded);
	else
		OnXMLLoaded (strXMLURL);
	
	function OnXMLLoaded (req)
	{
		if (!strXSLURL)
		{
			callback (req.responseText, null);
			return;
		}
		
		var xml;
		try
		{
			xml = req.responseXML;
		} catch (e) {}
		
		if (!xml)
			xml = req;
			
		var xsl = _mapTransforms [strXSLURL.toLowerCase ()];
		if (xsl)
			Transform (xml, xsl);
		else
			LoadXML (strXSLURL, function (xsl) { OnXSLLoaded (xml, xsl.responseXML); } );
	}
	
	function OnXSLLoaded (xml, xsl)
	{
		if (window.XSLTProcessor)
		{
			var processor = new XSLTProcessor ();
			processor.importStylesheet (xsl);
			_mapTransforms [strXSLURL.toLowerCase ()] = processor;
			Transform (xml, processor);
		}
		else
		{
			_mapTransforms [strXSLURL.toLowerCase ()] = xsl;
			Transform (xml, xsl);
		}
	}
	
	function Transform (xml, xsl)
	{
		var xmlTransformed = null;
		if (xml)
		{
			if (xsl.transformToFragment)
				xmlTransformed = xsl.transformToFragment (xml, document);
			else
				xmlTransformed = xml.transformNode (xsl);
		}
		callback (xmlTransformed, xml);
	}
}

var _eltDebug;
function Debug (s)
{
	if (!_eltDebug)
	{
		_eltDebug = document.createElement ("div");
		_eltDebug.id = "debug";
		document.body.appendChild (_eltDebug);
	}
	_eltDebug.innerHTML += s + "<br/>";
}

function trim (str)
{
	if (!str) return str;
	return str.replace(/^\s*|\s*$/g,"");	// trim
}

function IsValidEmail (str)
{
	var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
	return filter.test(str);
}

function GetOffsets (elt)
{
	var offsets = new Point (-document.body.offsetLeft, -document.body.offsetTop);
	while (elt)
	{
		offsets.Add2 (elt.offsetLeft, elt.offsetTop);
		elt = elt.offsetParent;
	}
	return offsets;
}

function GetEventOffsets (evt)
{
	if (document.all)
	{
		var target = GetTarget (evt);
		var offsets = GetOffsets (target);
		offsets.Add2 (evt.offsetX, evt.offsetY);
		return offsets;
	}
	else
	{
		return new Point (evt.pageX, evt.pageY);
	}
}

function GetEventOffsetsFrom (evt, elt)
{
	var offsets = GetEventOffsets (evt);
	offsets.Sub (GetOffsets (elt));
	
	return offsets;
}

function GetTarget (evt)
{
	if (!evt) evt = window.event;
	if (!evt) return null;
	var target = evt.target ? evt.target : evt.srcElement;
	if (target.nodeType == 3)
		return target.parentNode;
	return target;
}


function Point (x, y)
{
	this.x = x || 0;
	this.y = y || 0;

	this.Add = function (pt)
	{
		this.x += pt.x;
		this.y += pt.y;
	}

	this.Sub = function (pt)
	{
		this.x -= pt.x;
		this.y -= pt.y;
	}

	this.Add2 = function (x, y)
	{
		this.x += x;
		this.y += y;
	}
	
	this.toString = function ()
	{
		return "("+this.x+","+this.y+")";
	}
}


function insertAfter (eltParent, eltNew, eltAfter)
{
	if (!eltAfter)
		eltParent.insertBefore (eltNew, eltParent.firstChild);
	else
		eltParent.insertBefore (eltNew, eltAfter.nextSibling);
}

function BindEvent (elt, handler)
{
	return function (e) { return handler.call (elt, e || window.event); }
}

function BindCall (obj, handler)
{
	return function () { return handler.apply (obj, arguments); }
}


function CancelEvent (evt)
{
	if (evt)
	{
		evt.cancelBubble = true;
		if (evt.stopPropagation) evt.stopPropagation();
	}
}



function GetEvent (evt)
{
	if (evt) return evt;
	var wnd = window;
	while (wnd && !wnd.event)
	{
		var wndParent = wnd.parent;
		if (wnd == wndParent)
			break;
		wnd = wndParent;
	}
	if (wnd)
		return wnd.event;
	return null;
}



function DoAjax (strURL, callback, callbackError)
{
	var eltFrame = document.createElement ("iframe");
	eltFrame.callback = callback;
	eltFrame.callbackError = callbackError;
	eltFrame.fRemove = true;
	//eltFrame.style.display = "none";
	eltFrame.style.position = "absolute";
	eltFrame.style.visibility = "hidden";
	document.body.appendChild (eltFrame);
	eltFrame.src = strURL;
}

function HandleAjaxCallback (wnd)
{
	var frame = GetFrameElement (wnd);
	if (!frame) return;
	var callback = frame.callback;
	frame.callback = null;
	frame.callbackError = null;
	if (!callback) return;
	
	var args = new Array ();
	for (var i = 1; i < arguments.length; i ++)
		args.push (arguments [i]);

	callback.apply (this, args);
	if (frame.fRemove)
		document.body.removeChild (frame);
}

function HandleAjaxError (wnd)
{
	var frame = GetFrameElement (wnd);
	if (!frame) return;
	var callback = frame.callbackError;
	frame.callback = null;
	frame.callbackError = null;
	if (!callback) return;
	
	var args = new Array ();
	for (var i = 1; i < arguments.length; i ++)
		args.push (arguments [i]);

	callback.apply (this, args);
	if (frame.fRemove)
		document.body.removeChild (frame);
}

function GetFrameElement (wnd)
{
	if (!wnd) return null;
	var elt = wnd.frameElement;
	if (elt) return elt;

	var rgFrames = window.frames;
	for (var i = 0; i < rgFrame.length; i ++)
	{
		var frame = rgFrames [i];
		var wndFrame = frame.contentWindow;
		if (wndFrame == wnd)
			return frame;
	}
	return null;
}


function ParseQueryString (strQuery)
{
	if (strQuery.length == 0)
		return;
		
	var rgPairs = strQuery.substring (1).split ('&');
	
	var cPairs = rgPairs.length;
	for (var i = 0; i < cPairs; i ++)
	{
		var strPair = rgPairs [i];
		var rgParts = strPair.split ('=');
		var key = rgParts [0];
		var value = rgParts [1];
		this [key] = value;
	}
}


// drop-down handlers

var _fDropDownNeedHover = function ()
{
	if (navigator.appVersion.indexOf("MSIE") < 0)
		return false;

	var version = parseFloat (navigator.appVersion.split("MSIE") [1]);
	return version < 7.0;
} ();

var _dropdown_hoverelt;
var _dropdown_hoverclass;
function DropDown_OnMouseOver (elt)
{
	if (!_fDropDownNeedHover)
		return;
	if (_dropdown_hoverelt)
	{
		if (_dropdown_hoverelt == elt)
			return;
		DropDown_OnMouseLeave ();
	}
	_dropdown_hoverclass = elt.className;
	if (elt.className)
		elt.className += " hover";
	else
		elt.className = "hover";
	elt.onmouseleave = DropDown_OnMouseLeave;
	_dropdown_hoverelt = elt;
}

function DropDown_OnMouseLeave ()
{
	if (!_dropdown_hoverelt)
		return;
	_dropdown_hoverelt.className = _dropdown_hoverclass;
	_dropdown_hoverelt.onmouseleave = null;
	_dropdown_hoverelt = _dropdown_hoverclass = null;
}

function getCookie( name ) {
	var start = document.cookie.indexOf( name + "=" );
	var len = start + name.length + 1;
	if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
		return null;
	}
	if ( start == -1 ) return null;
	var end = document.cookie.indexOf( ';', len );
	if ( end == -1 ) end = document.cookie.length;
	return unescape( document.cookie.substring( len, end ) );
}

function setCookie( name, value, expires, path, domain, secure ) {
	var today = new Date();
	today.setTime( today.getTime() );
	if ( expires ) {
		expires = expires * 1000 * 60 * 60 * 24;
	}
	var expires_date = new Date( today.getTime() + (expires) );
	document.cookie = name+'='+escape( value ) +
		( ( expires ) ? ';expires='+expires_date.toGMTString() : '' ) + //expires.toGMTString()
		( ( path ) ? ';path=' + path : '' ) +
		( ( domain ) ? ';domain=' + domain : '' ) +
		( ( secure ) ? ';secure' : '' );
}

function deleteCookie( name, path, domain ) {
	if ( getCookie( name ) ) document.cookie = name + '=' +
			( ( path ) ? ';path=' + path : '') +
			( ( domain ) ? ';domain=' + domain : '' ) +
			';expires=Thu, 01-Jan-1970 00:00:01 GMT';
}

function findPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}

function findPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}
