var Rectangle = new Class(
	{
		x:0,
		y:0,
		width:0,
		height:0,
	    initialize: function(x,y,width,height){
	        this.x = x;
	        this.y = y;
	        this.width = width;
	        this.height = height;
	    }
	}
);

var SystemState = new Class(
	{
		hiddenElements : new Array()
	}
);

SystemState.instance = null;

SystemState.getInstance = function(){
	if(this.instance == null){
		this.instance = new this();
	}
	return this.instance;
}

function pageWidth() {
	var res = window.innerWidth != null? window.innerWidth : document.documentElement && document.documentElement.clientWidth ?  
	     document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : null;
	return res;
}
function pageHeight() {
	return  window.innerHeight != null? window.innerHeight : document.documentElement && document.documentElement.clientHeight ?  
	document.documentElement.clientHeight : document.body != null? document.body.clientHeight : null;
}

function posLeft() {
	return typeof window.pageXOffset != 'undefined' ? window.pageXOffset :document.documentElement && document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ? document.body.scrollLeft : 0;
}
	
function posTop() {
	return typeof window.pageYOffset != 'undefined' ?  window.pageYOffset : document.documentElement && document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ? document.body.scrollTop : 0;
}
function posRight() {
	return posLeft()+pageWidth();
}
function posBottom() {
	return posTop()+pageHeight();
}

function getFlashMovieObject(movieName){
	if (window.document[movieName]){
		return window.document[movieName];
	}
	if (!Browser.Engine.trident){
		if (document.embeds && document.embeds[movieName])
			return document.embeds[movieName]; 
	}
	else{
		return $(movieName);
	}
}

function getAbsoluteY(element){
	if(! element){
		return -1;
	}
	var curtop = 0;
	if(element.offsetParent){
		while(1){
			curtop += element.offsetTop;
          	if(!element.offsetParent)
            	break;
			element = element.offsetParent;
		}
	}
	else if(element.y){
		curtop += element.y;
		return curtop;
	}
	return curtop;
}

function getAbsoluteX(element){
	if(! element){
		return -1;
	}
	var curleft = 0;
	if(element.offsetParent){
		while(1){
			curleft += element.offsetLeft;
          	if(!element.offsetParent)
            	break;
			element = element.offsetParent;
		}
	}
	else if(element.x){
		curleft += element.x;
		return curleft;
	}
	return curleft;
}

function getAvailableWidth(){
	if(!Browser.Engine.trident){
		var dWidth = top.window.outerWidth - top.window.innerWidth;
		return top.screen.availWidth - dWidth;
	}
	else{
		return top.screen.availWidth;
	}
}

function debug(message){
	if($("debugger")){
		$("debugger").appendText(message);
		$("debugger").appendChild(new Element('br'));
	}
}

/*
	function tests if a point (x,y) is inside a given rectangle
*/
function containsCoordinates(rectangle, x,y){
	if(x <= rectangle.x) return false;
	if(x >= rectangle.x + rectangle.width) return false;
	if(y <= rectangle.y) return false;
	if(y >= rectangle.y + rectangle.height) return false;
	return true;
}

/*
	tests if an element overlaps with another element
*/
function overlaps(element1, element2){
	var bounds1 = getBounds(element1);
	var bounds2 = getBounds(element2);
	if(containsCoordinates(bounds1, bounds2.x, bounds2.y)){
		return true;
	}
	if(containsCoordinates(bounds1, bounds2.x, bounds2.y + bounds2.height)){
		return true;
	}
	if(containsCoordinates(bounds1, bounds2.x + bounds2.width, bounds2.y)){
		return true;
	}
	if(containsCoordinates(bounds1, bounds2.x + bounds2.width, bounds2.y + bounds2.height)){
		return true;
	}	
	return false;
}

function hideOverlappingElements(overlappedElement, elementsToCheck){
	
	var bounds = getBounds(overlappedElement);
	var hiddenElements = SystemState.getInstance().hiddenElements;
	for(var i = 0; i < elementsToCheck.length; i++){
		var element = elementsToCheck[i];
		if(element == topElement || contains(element, overlappedElement) || contains(overlappedElement, element)){
			continue;
		}
		if(overlaps(overlappedElement, element)){
			element.setStyle('visibility', 'hidden');
			if(hiddenElements.indexOf(element < 0)){
				hiddenElements.push(element);
			}
		}
		else if(hiddenElements.indexOf(element >= 0)){
			element.setStyle('visibility', 'visible');
			hiddenElements.erase(element);
		}
	}
}

function showHiddenElements(overlappedElement, elementsToCheck){
	var hiddenElements = SystemState.getInstance().hiddenElements;
	for(var i = 0; i < elementsToCheck.length; i++){
		var element = elementsToCheck[i];
		if(element == topElement || contains(element, overlappedElement) || contains(overlappedElement, element)){
			continue;
		}
		if(hiddenElements.indexOf(element >= 0)){
			element.setStyle('visibility', 'visible');
			hiddenElements.erase(element);
		}
	}
}

function getBounds(element){
	var width = element.getStyle('width').toInt();
	var height = element.getStyle('height').toInt();
	var x = getAbsoluteX(element);
	var y = getAbsoluteY(element);
	return new Rectangle(x,y,width, height);
}

function contains(parentElement, childElement){
	var theParent = childElement.getParent();
	while(theParent != null && theParent != undefined){
		if(theParent == parentElement){
			return true;
		}
		theParent = parentElement.getParent();
	}
	return false;
}

function getDomainFromUrl(url){
	if(url == null){
		return null;
	}
	var afterHTTP = url.substring(7,url.length);
	var nextSlashIndex = afterHTTP.indexOf("/");
	var domain = afterHTTP.substring(0, nextSlashIndex);
	return domain;
}
