/*

	Javascript-based DOM services. Based on Classes module.
	
	Author: Mantzoukas Alexander
	Version: 3.4.2.100

*/

function isIE()
{
	var agt = navigator.userAgent.toLowerCase();
	var isIe = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
	return isIe;
}

var Bounds = new Class();

Bounds.Declare(
	{
		top: new Property(),
		left: new Property(),
		bottom: new Property(),
		right: new Property(),
		width: new Property(),
		height: new Property(),
		
		Constructor: function(_top, _left, _bottom, _right)
		{
			if (_top != null)
				this.top.set( _top );
			if (_left != null)
				this.left.set( _left );
			if (_bottom != null)
				this.bottom.set( _bottom );
			if (_right != null)
				this.right.set( _right );
			
			if (_left != null && _right != null)
				this.width.set( _right - _left  );
			if (_top != null && _bottom != null)
				this.height.set( _bottom - _top );
		},
		
		isInBorders: function(x, y)
		{
			if (y >= this.top.get() &&
				y <= this.bottom.get() &&
				x >= this.left.get() &&
				x <= this.right.get())
				return true;
			
			return false;
		},
		
		percentageOverlap: function(element)
		{
			element = $element(element);
			var elBounds = element.getBounds();
			
			var maxtop = (this.top.get() > elBounds.top.get()) ? this.top.get() : elBounds.top.get();
			var maxleft = (this.left.get() > elBounds.left.get()) ? this.left.get() : elBounds.left.get();
			var minright = (this.right.get() < elBounds.right.get()) ? this.right.get() : elBounds.right.get();
			var minbottom = (this.bottom.get() < elBounds.bottom.get()) ? this.bottom.get() : elBounds.bottom.get();
			
			var ov_width = minright - maxleft;
			var ov_height = minbottom - maxtop;
			
			if (ov_width < 0 || ov_height < 0) return 0;
			
			var perc = 100 * ( ov_width * ov_height ) / ( this.width.get() * this.height.get() );
			
			return perc;
		}
	}
);

/*******************************************************************************
	Library Required Functions Declarations
*******************************************************************************/

function getScrollY()
{
	var scrOfY = 0;
	if( typeof( window.pageYOffset ) == 'number' )
		scrOfY = window.pageYOffset;
	else if( document.body && document.body.scrollTop )
		scrOfY = document.body.scrollTop;
	else if( document.documentElement && document.documentElement.scrollTop )
		scrOfY = document.documentElement.scrollTop;
	return scrOfY;
}

function getScrollX()
{
	var scrOfX = 0;
	if( typeof( window.pageXOffset ) == 'number' )
		scrOfX = window.pageXOffset;
	else if( document.body && document.body.scrollLeft )
		scrOfX = document.body.scrollLeft;
	else if( document.documentElement && document.documentElement.scrollLeft)
		scrOfX = document.documentElement.scrollLeft;
	return scrOfX;
}

function getNumberFromStyle(str)
{
	if (!str.match(/-?\d+(px|em|pt|cm)?/))
		return null;
	return Number(str.match(/-?\d+/));
}

function getUnitFromStyle(str)
{
	if (!str.match(/-?\d+(px|em|pt|cm)/))
		return null;
	return str.match(/(px|em|pt|cm)/)[1];
}

function toStylePercentage( x, total )
{
	return ( Math.round( (x / total)*100*100. ) / 100. ) + "%";
}

function getHeight(element)
{
	element = $element(element);
	if (element.clientHeight && element.clientHeight != 0)
		return element.clientHeight;
	else return element.offsetHeight;
}

function getWidth(element)
{
	element = $element(element);
	if (element.clientWidth && element.clientWidth != 0)
		return element.clientWidth;
	else return element.offsetWidth;
}

function getRelativeLeft(element)
{
	element = $element(element);
	var left = 0;
	do
	{
		left += element.offsetLeft || 0;
		try { element = element.offsetParent; }
		catch(e) { element = null; }
		if (element)
		{
			var p = element.style.position;
			if (p == 'relative' || p == 'absolute') break;
		}
	} while (element);
	return left;
}

function getRelativeTop(element)
{
	element = $element(element);
	var top = 0;
	do
	{
		top += element.offsetTop || 0;
		try { element = element.offsetParent; }
		catch(e) { element = null; }
		if (element)
		{
			var p = element.style.position;
			if (p == 'relative' || p == 'absolute') break;
		}
	} while (element);
	return top;
}

function getLeft(element)
{
	element = $element(element);
	var left = 0;
	do
	{
		left += element.offsetLeft || 0;
		try { element = element.offsetParent; }
		catch(e) { element = null; }
	} while (element);
	return left;
}

function getTop(element)
{
	element = $element(element);
	var top = 0;
	do
	{
		top += element.offsetTop || 0;
		try { element = element.offsetParent; }
		catch(e) { element = null; }
	} while (element);
	return top;
}

function getScreenSize()
{
	var screenSize = new Object();
	
	screenSize.width = screen.width;
	screenSize.height = screen.height;
	
	return screenSize;
}

function getCorrectElement(e)
{
	var targ;
	if (!e) e = window.event;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	if (targ.nodeType == 3) // defeat Safari bug
	   targ = targ.parentNode;
	return $enhance(targ);
}

function getCurrentAndRelated(e, _this)
{
	var current, related;
	
	if (window.event)
	{
		current = _this;
		related = window.event.toElement;
	}
	else
	{
		current = e.currentTarget;
		related = e.relatedTarget;
	}
	
	return [ current, related ];
}

function getRelated(e)
{
	var related;
	
	if (window.event)
	{
		related = $element(window.event.toElement);
	}
	else
	{
		related = $element(e.relatedTarget);
	}
	
	return related;
}

function getTargetElement(e)
{
	if (!e) e = window.event;
	return $element( isIE() ? e.srcElement : e.target );
}

function chainEventListener(evName, funcRef, el)
{
	el = $elements(el);
	
	if (el[0].addEventListener)
	{
		for(var i = 0; i < el.length; ++i)
		{
			var ref = Reference(funcRef, el[i]);
			el[i].addEventListener(evName, ref, false);
			__GC.markEvent( evName, ref, el[i] );
		}
	}
	else if (el[0].attachEvent)
	{
		for(var i = 0; i < el.length; ++i)
		{
			var ref = Reference(funcRef, el[i]);
			el[i].attachEvent('on' + evName, ref);
			__GC.markEvent( evName, ref, el[i] );
		}
	}
}

function removeEventListener(evName, funcRef, el)
{
	el = $elements(el);
	if (el[0].addEventListener)
	{
		for(var i = 0; i < el.length; ++i)
			el[i].removeEventListener(evName, funcRef, false);
	}
	else if (el[0].attachEvent)
	{
		for(var i = 0; i < el.length; ++i)
			el[i].detachEvent('on' + evName, funcRef);
	}
}

function chainWindowEvent(evName, funcRef)
{
	var oldEvent = window[evName];
	
	if (typeof window[evName] == "function")
	{
		window[evName] = function()
		{
			oldEvent.apply( window, arguments );
			funcRef.apply( window, arguments );
		}
	}
	else
	{
		window[evName] = funcRef;
	}
}

function cancelPropagation(e)
{
	if (!e) e = window.event;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
}

function getCorrectKey(e)
{
	if ( window.event )
		return e.keyCode;
	else
		return e.which;
}

function checkCapsLock(e)
{
	var myKeyCode = getCorrectKey(e);
	var myShiftKey = e.shiftKey;
	
	if ( ( myKeyCode >= 65 && myKeyCode <= 90 ) && !myShiftKey )
		return true;
	else if ( ( myKeyCode >= 97 && myKeyCode <= 122 ) && myShiftKey )
		return true;
	
	return false;
}

function trapEvent(e)
{
	if (!e) e = window.event;
	try
	{
		e.preventDefault();
		return false;
	}
	catch(ex)
	{
		return false;
	}
}

function getClickedButton(e)
{
	if ( isIE() )
	{
		switch(e.button)
		{
			case 1:
				return 0;
			case 4:
				return 1;
			case 2:
				return 2;
			default:
				break;
		}
		return -1;
	}
	else
		return e.button;
}

function getSelectedText()
{
	var str = null;
	if (document.getSelection)
	{
		str = document.getSelection();
	}
	else if (document.selection && document.selection.createRange)
	{
		var range = document.selection.createRange();
		str = range.text;
	}
	
	return str;
}

function clearSelectedText()
{
	if (isIE())
	{
		var range = document.selection.empty();
	}
}

function createCookie(name, value, days, path, domain, secure)
{
	if (days)
	{
		var date = new Date();
		date.setTime( date.getTime() + ( days*24*60*60*1000 ) );
		var expires = "; expires=" + date.toGMTString();
	}
	else var expires = "";
	
	document.cookie = name + "=" + value + expires +
		((path) ? "; path=" + path : "") +
		((domain) ? "; domain=" + domain : "") +
		((secure) ? "; secure" : "");
}

function readCookie(name)
{
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++)
	{
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name, path, domain)
{
	createCookie(name,"",-1, path, domain);
}

function leapYear( year )
{
	var tmpYear = Number( year );
	if (tmpYear % 4 == 0 && (tmpYear % 1000 == 0 || tmpYear % 100 != 0))
		return true;
	
	return false;
}

function getDays( month, year )
{
	var tmpArr = new Array(12);
	month = new Number(month);
	
	tmpArr[0] = 31;                         	// January
	tmpArr[1] = 28;                         	// February
	tmpArr[2] = 31;                         	// March
	tmpArr[3] = 30;                         	// April
	tmpArr[4] = 31;                         	// May
	tmpArr[5] = 30;                         	// June
	tmpArr[6] = 31;                         	// July
	tmpArr[7] = 31;                         	// August
	tmpArr[8] = 30;                         	// September
	tmpArr[9] = 31;					// October
	tmpArr[10] = 30;	                       	// November
	tmpArr[11] = 31;                        	// December
	
	if( leapYear(year) )
	{
		tmpArr[1] = 29;
	}
	
	return tmpArr[month];
}

function writeFlash(theMovie, width, height, theContainer, theCaptions)
{
	var flashHTML = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="' + width + '" height="' + height + '" type="application/x-shockwave-flash">';
	flashHTML += '<param name="movie" value="' + theMovie + '" />';
	flashHTML += '<param name="quality" value="high" />';
	flashHTML += '<param name="wmode" value="transparent" />';
	flashHTML += '<param name="FlashVars" value="captions=' + theCaptions + '">';
	flashHTML += '<param name="menu" value="false" />';
	flashHTML += '<embed src="' + theMovie + '" quality="high" wmode="transparent" menu="false" FlashVars="captions=' + theCaptions + '" width="' + width + '" height="' + height + '" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>';
	flashHTML += '</object>';
	$element(theContainer).innerHTML = flashHTML;
}

var selectsCounter = 0;
function hideSelectsIE()
{
	if (isIE())
	{
		++selectsCounter;
		var sel = $elements("select");
		for(var i = 0; i < sel.length; ++i)
			sel[i].style.visibility = "hidden";
	}
}

function showSelectsIE()
{
	if (isIE())
	{
		if (selectsCounter < 2)
		{
			var sel = $elements("select");
			for(var i = 0; i < sel.length; ++i)
				sel[i].style.visibility = "";
		}
		
		--selectsCounter;
	}
}

var getRule = function(name)
{
	var AllRules = this.getRules();
	name = name.replace(/\s+/g, " ");
	var names = name.split(" ");
	var rules = [];
	for(var k = 0; k < names.length; ++k)
	{
		for(var i = 0; i < AllRules.length; ++i)
		{
			var array = AllRules[i].selectorText.toLowerCase().split(",");
			for(var j = 0; j < array.length; ++j)
			{
				if ( array[j].indexOf(names[k]) > -1 )
				{
					rules[ rules.length ] = AllRules[i];
				}
			}
		}
	}
	
	return rules;
}

var AllRules = new Array();
var getRules = function()
{
	if (AllRules.length) return AllRules;
	for(var i = 0; i < document.styleSheets.length; ++i)
	{
		var ss = document.styleSheets[i];
		if (ss.cssRules)
		{
			for(var j = 0; j < ss.cssRules.length; ++j)
				AllRules[AllRules.length] = ss.cssRules[j];
		}
		else if (ss.rules)
		{
			for(var j = 0; j < ss.rules.length; ++j)
				AllRules[AllRules.length] = ss.rules[j];
		}
	}
	return AllRules;
}

/*******************************************************************************
	DOM Objects helpers
*******************************************************************************/

var $element = function( id, parId )
{
	if (!id) return null;
	var root = document;
	if (parId)
		root = $element( parId );
	
	if (typeof id == "string")
	{
		var result = document.getElementById(id);
		//if (!result)
		//	result = document.getElementsByName( id )[0];
		if (!result)
			result = root.getElementsByTagName( id )[0];
		$enhance(result);
		return result;
	}
	else if ( id.IsArray)
	{
		return $elements(id);
	}
	else return $enhance(id);
};

var $elements = function( id, parId )
{
	if (!id) return null;
	var root = document;
	if (parId)
		root = $element( parId );
	
	if (typeof id == "string")
	{
		var arr = new Array();
		var result = [ document.getElementById(id) ];
		//if (!result[0])
		//	result = document.getElementsByName( id );
		if (!result[0])
			result = root.getElementsByTagName( id );
		for(var j = 0; j < result.length; ++j)
			arr[ arr.length ] = $enhance(result[j]);
		return arr;
	}
	else if (id.IsArray)
	{
		var arr = new Array();
		for(var i = 0; i < id.length; ++i)
		{
			var result = [ document.getElementById(id[i]) ];
			//if (!result[0])
			//	result = document.getElementsByName( id[i] );
			if (!result[0])
				result = root.getElementsByTagName( id[i] );
			if (!result.length)
				result = [ id[i] ];
			for(var j = 0; j < result.length; ++j)
				arr[ arr.length ] = $enhance( result[j] );
		}
		return arr;
	}
	else return [ $enhance(id) ];
};

var $child = function( id, parId )
{
	if (!id) return null;
	var root = document;
	if (parId)
		root = $element( parId );
	
	if (typeof id == "string")
	{
		var result = null;
		var allEl = $elements(id, parId);
		result = allEl[0];
		var i = 0;
		while( i < allEl.length && result.parentNode != root )
		{
			++i;
			result = allEl[i];
			break;
		}
		$enhance(result);
		return result;
	}
	else if (id.IsArray)
	{
		return $children(id);
	}
	else return $enhance(id);
};

var $children = function( id, parId )
{
	if (!id) return null;
	var root = document;
	if (parId)
		root = $element( parId );
	
	if (typeof id == "string")
	{
		var result = new Array();
		var allEl = $elements( id, parId );
		var i = 0;
		while( i < allEl.length )
		{
			if (allEl[i].parentNode == root)
			result[ result.length ] = allEl[i];
			++i;
		}
		for(var j = 0; j < result.length; ++j)
			$enhance(result[j]);
		return result;
	}
	else if (id.IsArray)
	{
		var arr = new Array();
		for(var i = 0; i < id.length; ++i)
		{
			var result = new Array();
			var allEl = $elements( id[i], parId );
			var j = 0;
			while( j < allEl.length )
			{
				if (allEl[j].parentNode == root)
				result[ result.length ] = allEl[j];
				++j;
			}
			for(var j = 0; j < result.length; ++j)
				arr[ arr.length ] = $enhance( result[j] );
		}
		return arr;
	}
	else return [ id ];
};

var $create = function( id, parId )
{
	if (!id) return null;
	var parIds = $elements(parId);
	var ids = null;
	if (!id.IsArray)
		ids = [ id ];
	else
		ids = id;
	var els = new Array();
	for(var i = 0; i < parIds.length; ++i)
	{
		for(var j = 0; j < ids.length; ++j)
		{
			els[ els.length ] = document.createElement( ids[j] );
			
			parIds[i].appendChild( els[ els.length - 1 ] );
			els[ els.length - 1 ] = $enhance( els[ els.length - 1 ] );
		}
	}
	
	return els;
}

var $createText = function( id, parId )
{
	if (!id) return null;
	var parIds = $elements(parId);
	var ids = null;
	if (!id.IsArray)
		ids = [ id ];
	else
		ids = id;
	var els = new Array();
	for(var i = 0; i < parIds.length; ++i)
	{
		for(var j = 0; j < ids.length; ++j)
		{
			els[ els.length ] = document.createTextNode( ids[i] );
			
			parIds[i].appendChild( els[ els.length - 1 ] );
		}
	}
	
	return els;
}

// Memory leak fix 16-10-07
var __IsEnhanced = function() { return true; };
	
var __isParentOf = function( child )
{
	var par = $element(child).parentNode;
	var parent = this;
	
	while(par)
	{
		if (par == parent) return true;
		par = par.parentNode;
	}
	
	return false;
};

var __isChildOf = function( parent )
{
	var par = this.parentNode;
	parent = $element(parent);
	
	while(par)
	{
		if (par == parent) return true;
		par = par.parentNode;
	}
	
	return false;
};

var __getBounds = function()
{
	var el = this;
	var top = getTop(el);
	var left = getLeft(el);
	var bottom = top + getHeight(el);
	var right = left + getWidth(el);
	if (isIE())
	{
		var btop = getNumberFromStyle(el.style.borderTop);
		var bleft = getNumberFromStyle(el.style.borderLeft);
		top += btop;
		left += bleft;
		bottom += ( btop + getNumberFromStyle(el.style.borderBottom) );
		right += ( bleft + getNumberFromStyle(el.style.borderRight) );
	}
	return new Bounds(top, left, bottom, right);
};

var __getBoundsWithScroll = function()
{
	var el = this;
	var top = getTop(el) + getScrollX();
	var left = getLeft(el) + getScrollY();
	var bottom = top + getHeight(el);
	var right = left + getWidth(el);
	if (isIE())
	{
		var btop = getNumberFromStyle(el.style.borderTop);
		var bleft = getNumberFromStyle(el.style.borderLeft);
		top += btop;
		left += bleft;
		bottom += ( btop + getNumberFromStyle(el.style.borderBottom) );
		right += ( bleft + getNumberFromStyle(el.style.borderRight) );
	}
	return new Bounds(top, left, bottom, right);
};

var __getRelativeBounds = function()
{
	var el = this;
	var top = getRelativeTop(el);
	var left = getRelativeLeft(el);
	var bottom = top + getHeight(el);
	var right = left + getWidth(el);
	if (isIE())
	{
		var btop = getNumberFromStyle(el.style.borderTop);
		var bleft = getNumberFromStyle(el.style.borderLeft);
		top += btop;
		left += bleft;
		bottom += ( btop + getNumberFromStyle(el.style.borderBottom) );
		right += ( bleft + getNumberFromStyle(el.style.borderRight) );
	}
	return new Bounds(top, left, bottom, right);
};

var __getRelativeBoundsWithScroll = function()
{
	var el = this;
	var top = getRelativeTop(el) + getScrollX();
	var left = getRelativeLeft(el) + getScrollY();
	var bottom = top+ getHeight(el);
	var right = left + getWidth(el);
	if (isIE())
	{
		var btop = getNumberFromStyle(el.style.borderTop);
		var bleft = getNumberFromStyle(el.style.borderLeft);
		top += btop;
		left += bleft;
		bottom += ( btop + getNumberFromStyle(el.style.borderBottom) );
		right += ( bleft + getNumberFromStyle(el.style.borderRight) );
	}
	return new Bounds(top, left, bottom, right);
};

var __on = function(evName, funcRef)
{
	chainEventListener(evName, funcRef, this);
}

var $enhance = function( element )
{
	if (!element) return null;
	
	if (element.IsEnhanced) return element;
	element.IsEnhanced = __IsEnhanced;
	element.isParentOf = __isParentOf;
	element.isChildOf = __isChildOf;
	element.getBounds = __getBounds;
	element.getBoundsWithScroll = __getBoundsWithScroll;
	element.getRelativeBounds = __getRelativeBounds;
	element.getRelativeBoundsWithScroll = __getRelativeBoundsWithScroll;
	element.on = __on;
	
	return element;
}

var $import = function( scriptUrl, optionalId, onload )
{
	var scriptNode = document.createElement("script");
	scriptNode.type = "text/javascript";
	scriptNode.src = scriptUrl;
	if (optionalId)
		scriptNode.id = optionalId;
	$element("body").appendChild(scriptNode);
}

var $debug = function( txt, append )
{
	if (append) $element("debug").innerHTML += txt;
	else $element("debug").innerHTML = txt;
}

window.on = function(evName, funcRef)
{
	chainWindowEvent(evName, funcRef);
}
