//Builds a Array with grid data
function CreateDataGrid()
{
	function init(){
		var url = createUrl();
		getXML(url);
	}

	//Creates the URL that's needed
	function createUrl(){
		var random = new Date().getTime();
		//return "xml/section" + model.section + ".xml" + "?random=" + random;
		if(model.section == "14")
		{
			return "xml/section14.php?id=" + model.section + "&cid=" + model.cid + "&random=" + random;	
		}
		else if(model.section == "15")
		{
			return "xml/section15.xml?id=" + model.section + "&cid=" + model.cid + "&random=" + random;			
		}
		else if(model.section == "02")
		{
			return "xml/sections.php?id=" + model.section + "&cid=" + model.cid + "&random=" + random;			
		}
		else
		{
		return "xml/section" + model.section + ".xml" + "?random=" + random;		
		}
	}

	//Gets the XML from XMLRequest
	function getXML(url){
		var xmlListener = new Object();
		xmlListener.xmlLoaded = function(){
			onSucces(xmlRequest.getXML());
		};
		xmlListener.xmlError = function(){
			onError();
		};
		var xmlRequest = new XMLRequest();
		xmlRequest.addListener(xmlListener);
		xmlRequest.requestXML(url);
	}

	//Function gets called when XML is received
	function onSucces(xml){
		var dataGrid = createData(xml);
		var grid = new BuildupGrid();
		grid.init(dataGrid);
		
	}

	//Function gets called when a error occured in Function "GetSectionXML.getXML()"
	function onError(){
		alert("ERROR page does not exist");
	}

	//Creates DataGrid Object
	function createData(xml){
		var data = new Array();
		var xmlPage = returnElements(xml.getElementsByTagName('pages')[0], "page");
		for(var i=0;i<xmlPage.length;i++){
			data[i] = new Object();
			data[i].id = String(getXmlNodeValue(returnElements(xmlPage[i], "id")[0]));
			data[i].title = String(getXmlNodeValue(returnElements(xmlPage[i], "pagetitle")[0]));
			data[i].url = String(getXmlNodeValue(returnElements(xmlPage[i], "url")[0]));
			data[i].x = String(getXmlNodeValue(returnElements(xmlPage[i], "x")[0]));
			data[i].y = String(getXmlNodeValue(returnElements(xmlPage[i], "y")[0]));
			data[i].z = String(getXmlNodeValue(returnElements(xmlPage[i], "z")[0]));
		}
		return data;
	}

	//Public functions
	this.init = init;
}


//Builds a grid with a given Array
function BuildupGrid()
{
	
	//Begin Grid builder
	function init(dataGrid){
		createContainer(dataGrid);
	}

	//Creates container Div
	function createContainer(dataGrid){
		for(var i=0;i<dataGrid.length;i++)
		{
			//alert(dataGrid[i].id);
			var insertHTML = "<div id=\"content" + dataGrid[i].id + "\" class=\"pageContent\"></div><div class=\"pageLoader\" id=\"loader"+ dataGrid[i].id + "\"></div>";
			
			var page = createElement(model.stage, "div", "page", "page" + dataGrid[i].id, insertHTML);
			//alert(page.innerHTML);
			var pageX = calculateX(dataGrid[i].x);
			var pageY = calculateY(dataGrid[i].y);
			page.style.top = pageY + "px";
			page.style.left = pageX + "px";
			createGhostButton(dataGrid[i].id, pageX, pageY);
			createGridArray(dataGrid[i].id, dataGrid[i].url, dataGrid[i].title, dataGrid[i].x, dataGrid[i].y, dataGrid[i].z);
			if(model.pageId == dataGrid[i].id){
				model.gridControl.disableGhost(dataGrid[i].id);
			}
		}
		stageControl.startUpStage();
		
	}

	//Creates overlaying Button
	function createGhostButton(id, pageX, pageY){
		var ghostButton = createElement(model.stage, "div", "ghost", "ghost" + id);
		ghostButton.style.top = pageY + "px";
		ghostButton.style.left = pageX  + "px";
		ghostButton.onmouseover = function(){
			stageControl.ghostButtonOver(this, id);
		};
		ghostButton.onmouseout = function(){
			stageControl.ghostButtonOut(this, id);
		};
		ghostButton.onclick = function(){
			stageControl.gotoLink(id+"-"+model.cid);
		};
		setOpacity(ghostButton, 0);
	}

	//Creates Array data sources
	function createGridArray(id, url, title, x, y, z){
		if((model.pageId == null)&&(x == 0)&&(y == 0)&&(z == 0)){
			model.pageId = id;
			model.gridControl.disableGhost(id);
		}
		var gridPosName = String(x) + String(y) + String(z);
		model.gridPos[gridPosName] = {id: id};
		model.gridId[id] = {x: x, y: y, z: z, url:url, loaded: false, title: title};
	}

	//Calculates X position of page
	function calculateX(x){
		return ((model.pageWidth*x) + (model.pageSpace*x));
	}

	//Calculates Y position of page
	function calculateY(y){
		return ((model.pageHeight*y) + (model.pageSpace*y));
	}

	//Public functions
	this.init = init;
}


//Handles all container specs
function ContainerClass()
{
	//Resizes containers
	function resizeContainers(item) {
		var isMinWidth = false
		var elm = document.getElementById(item);
		var innerWidth = getDisplayWidth();
		var innerHeight = getDisplayHeight();
		if(innerWidth <=  model.mainWidthMin  ){
			elm.style.width = model.mainWidthMin + "px";
			isMinWidth = true
		} else {
			elm.style.width = innerWidth + "px";
		}
		if((innerHeight - model.offSetHeight) <=  model.mainHeightMin){
			if(model.notIE && !model.isMinWidth){
				elm.style.width = (innerWidth - 16 ) + "px";
			}
			elm.style.height = model.mainHeightMin + "px";
		} else {
			if (model.isMinWidth && model.notIE) {
				innerHeight = innerHeight - 16;
			}
			elm.style.height = innerHeight - (model.offSetHeight -  28) + "px";
		}
		repositionContainer("contentcontainer", elm.style.width, elm.style.height);
		if((innerHeight) <= 600){
			document.getElementById("footer").style.top = model.mainHeightMin - 10 + "px";
		} else {
			document.getElementById("footer").style.top = innerHeight - (model.offSetHeight -  18) + "px";
		}
	}

	//Repositions container
	function repositionContainer(item, clipWidth, clipHeight) {
		var elm = document.getElementById(item);
		var marginLeft = (model.containerWidth - parseInt(clipWidth))/2;
		var marginTop = (model.containerHeight - parseInt(clipHeight))/2;
		elm.style.left = "-"+Math.abs(marginLeft)+"px";
		elm.style.top = "-"+Math.abs(marginTop)+"px";
	}

	//public functions
	this.resizeContainers = resizeContainers;
}


//Tweens given element
function TweenEngine()
{
	//Tweens given element
	function tweenPage(el, x, y, duration, callBack){
		var attributes = {points: {by: [x, y]}};
  		var tweenPage = new YAHOO.util.Motion(el, attributes);
		tweenPage.duration = duration;
		tweenPage.method = EVOLVE.Easing.expoEaseBoth;
		tweenPage.onStart.subscribe(disableStage);
		tweenPage.onComplete.subscribe(enableStage);
		if(callBack){
			tweenPage.onComplete.subscribe(callBack);
		}
		tweenPage.animate();
	}

	//Fades given element in
	function fadeSectionOut(el, duration, callback){
		var fadeIn = new YAHOO.util.Anim(el, {opacity: {to: 1}}, 0, YAHOO.util.Easing.easeOut);
		fadeIn.onStart.subscribe(disableStage);
		fadeIn.duration = duration;
		if(callback){
			fadeIn.onComplete.subscribe(callback);
		}
		fadeIn.animate();
	}

	//Fades given element out
	function fadeSectionIn(el, duration, callback){
		var fadeOut = new YAHOO.util.Anim(el, {opacity: {to: 0}}, 1, YAHOO.util.Easing.easeOut);
		fadeOut.duration = duration;
		fadeOut.onComplete.subscribe(enableStage);
		if(callback){
			fadeOut.onComplete.subscribe(callback);
		}
		fadeOut.animate();
	}

	//Fades given element out
	function fadeChallengeOut(el, duration, callback){
		var fadeOut = new YAHOO.util.Anim(el, {opacity: {to: 0}}, 1, EVOLVE.Easing.expoEaseBoth);
		fadeOut.duration = duration;
		if(callback){
			fadeOut.onComplete.subscribe(callback);
		}
		fadeOut.animate();
	}
	

	//Fades and Tweens given block
	function tweenBlocks(el, x, y, duration, callback){
		var fadeIn = new YAHOO.util.Anim(el, {opacity: {to: 1}}, 0, EVOLVE.Easing.expoEaseOut);
		fadeIn.duration = duration;
		var attributes = {points: {by: [x, y]}};
  		var tweenBlock = new YAHOO.util.Motion(el, attributes);
		tweenBlock.duration = duration;
		tweenBlock.method = EVOLVE.Easing.expoEaseOut;
		if(callback){
			fadeIn.onComplete.subscribe(callback);
		}
		fadeIn.animate();
		tweenBlock.animate();
	}

	//Fades given block
	function fadeBlocks(el, duration, callback){
		var fadeIn = new YAHOO.util.Anim(el, {opacity: {to: 1}}, 0, EVOLVE.Easing.expoEaseOut);
		fadeIn.duration = duration;
		if(callback){
			fadeIn.onComplete.subscribe(callback);
		}
		fadeIn.animate();
	}

	//Fades given block
	function fadeInGroup(el, duration, callback){
		var fadeIn = new YAHOO.util.Anim(el, {opacity: {to: 1}}, 0, EVOLVE.Easing.expoEaseOut);
		fadeIn.duration = duration;
		if(callback){
			fadeIn.onComplete.subscribe(callback);
		}
		fadeIn.animate();
	}

	//Fades given block
	function fadeOutGroup(el, duration, callback){
		var fadeOut = new YAHOO.util.Anim(el, {opacity: {to: 0}}, 1, EVOLVE.Easing.expoEaseOut);
		fadeOut.duration = duration;
		if(callback){
			fadeOut.onComplete.subscribe(callback);
		}
		fadeOut.animate();
	}

	//Fades given block
	function fadeInIcon(el, duration, callback){
		var fadeIn = new YAHOO.util.Anim(el, {opacity: {to: 1}}, 0, EVOLVE.Easing.expoEaseOut);
		fadeIn.duration = duration;
		if(callback){
			fadeIn.onComplete.subscribe(callback);
		}
		fadeIn.animate();
	}

	//Fades given block
	function fadeOutIcon(el, duration, callback){
		var fadeOut = new YAHOO.util.Anim(el, {opacity: {to: 0}}, 1, EVOLVE.Easing.expoEaseOut);
		fadeOut.duration = duration;
		if(callback){
			fadeOut.onComplete.subscribe(callback);
		}
		fadeOut.animate();
	}

	//Fades given element out
	function tweenLoaderOut(el, duration, callback){
		var loaderOut = new YAHOO.util.Anim(el, {opacity: {to: 0}}, 1, YAHOO.util.Easing.easeOut);
		loaderOut.duration = duration;
		loaderOut.onComplete.subscribe(function(){
			el.style.display = "none";
		});
		loaderOut.animate();
	}

	//Tweens given element
	function portfolioTweener(el, x, y, duration, callBack, onTween){
		var attributes = {points: {by: [x, y]}};
  		var tweenPage = new YAHOO.util.Motion(el, attributes);
		tweenPage.duration = duration;
		tweenPage.method = EVOLVE.Easing.expoEaseBoth;
		tweenPage.onStart.subscribe(disableStage);
		tweenPage.onComplete.subscribe(enableStage);
		if(callBack){
			tweenPage.onComplete.subscribe(callBack);
		}
		if(onTween){
			tweenPage.onTween.subscribe(onTween);
		}
		tweenPage.animate();
	}

	//Fades given element in
	function fadeGalleryOut(el, duration, callback){
		var fadeIn = new YAHOO.util.Anim(el, {opacity: {to: 1}}, 0, YAHOO.util.Easing.easeOut);
		fadeIn.duration = duration;
		if(callback){
			fadeIn.onComplete.subscribe(callback);
		}
		fadeIn.animate();
	}

	//Fades given element in
	function fadeGhostIn(el){
		//setOpacity(el, 50);
		var fadeGhostIn = new YAHOO.util.Anim(el, {opacity: {to: 0.5}}, 0, YAHOO.util.Easing.easeOut);
		fadeGhostIn.duration = 0.3;
		fadeGhostIn.animate();
	}

	//Fades given element out
	function fadeGhostOut(el){
	    //setOpacity(el, 0);
		var anim = new YAHOO.util.Anim(el, {opacity: {to: 0 }}, 1, YAHOO.util.Easing.easeOut);
	   	anim.duration = 0.3;
		anim.animate();
	}

	//Enables stage
	function enableStage(){
		model.stageDisabled = false;
	}

	//Disables stage
	function disableStage(){
		model.stageDisabled = true;
	}

	//Public functions
	this.tweenPage = tweenPage;
	this.fadeSectionIn = fadeSectionIn;
	this.fadeSectionOut = fadeSectionOut;
	this.fadeChallengeOut = fadeChallengeOut;
	this.tweenBlocks = tweenBlocks;
	this.fadeBlocks = fadeBlocks;
	this.fadeInGroup = fadeInGroup;
	this.fadeOutGroup = fadeOutGroup;
	this.fadeInIcon = fadeInIcon;
	this.fadeOutIcon = fadeOutIcon;
	this.fadeGalleryOut = fadeGalleryOut;
	this.fadeGhostIn = fadeGhostIn;
	this.fadeGhostOut = fadeGhostOut;
	this.tweenLoaderOut = tweenLoaderOut;
	this.portfolioTweener = portfolioTweener;
}


//Class that handles HTTP requests to get XML
function XMLRequest()
{
	//Ajax Request function
	function requestXML(url, para){
		if(!para){ para = ""; }
		var onComplete = parseXML;
		var callback = {
			success: function(XML) { parseXML(XML); },
			failure: function() { broadCastError(); }
		}
		var requestObj = YAHOO.util.Connect.asyncRequest('GET', url, callback, null);
	}

	//XML Parse function
	var xml;
	function parseXML(req){
		if(req.responseText.indexOf("<!DOCTYPE") != -1){
		  	var re = /^<!DOCTYPE(.*)>/g;
		  	var tmp = re.exec(req.responseText);
			var content = req.responseText.substr(re.lastIndex, req.responseText.length);
		} else {
			var content = req.responseText;
		}
		if (window.ActiveXObject){
			xml = new ActiveXObject("Microsoft.XMLDOM");
			xml.async = "false";
			xml.loadXML(content);
		}else {
			var xml_Parser = new DOMParser();
			xml = xml_Parser.parseFromString(content, "application/xml");
		}
		onXMLObj.broadcastMessage("xmlLoaded");
	}

	//Broadcasts a error to all listeners
	function broadCastError(){
		onXMLObj.broadcastMessage("xmlError");
	}

	//Returns XML Document Object
	function getXML(){
		return xml;
	}

	//XML Ready Broadcaster
	var onXMLObj = new Object();
	JSBroadcaster.initialize(onXMLObj);

	//Adds listener to XML broadcaster
	function addListener(listener){
		onXMLObj.addListener(listener);
	}

	//Removes listener from XML broadcaster
	function removeListener(listener){
		onXMLObj.removeListener(listener);
	}

	//XMLRequest's methods
	this.requestXML = requestXML;
	this.getXML = getXML;
	this.addListener = addListener;
	this.removeListener = removeListener;
}



// -- History Management -- //




//Gets called onstartup
function initBrowserHistory(){
	var bookmarkedState = YAHOO.util.History.getBookmarkedState("id");
	var initialState = bookmarkedState || "default";
 	YAHOO.util.History.register("id", initialState, stateChangeHandler);
}

//Gets called when state changes
function stateChangeHandler(id){
	if(id == "default"){
		id = model.gridPos["000000"].id;
	}
	model.gridControl.gotoPage(id);
}



// -- Handy Tools -- //




//Creates Div or Img element
function createElement(parent, el, elClass, id, innerValue, width, height, src){
	if (el == "img"){
		var element = document.createElement(el);
		if (id){element.id = id;}
		element.src = src;
		appendedEl = parent.appendChild(element);
		if (width){appendedEl.width = width;}
		if (height){appendedEl.height = height;}
		if (elClass){appendedEl.className = elClass;}
		return appendedEl;
	} else {
		var element = document.createElement(el);
		if (id){element.id = id;}
		var appendedEl = parent.appendChild(element);
		if (innerValue){appendedEl.innerHTML = innerValue;}
		if (elClass){appendedEl.className = elClass;}
		return appendedEl;
	}
}

//Returns a number from a "value"px string
function stripValuePx(value){
	return parseInt(value.substr(0, value.indexOf("px")));
}

//Sets Opacity
function setOpacity(imageobject, value) {
	imageobject.style.opacity = value/10;
	imageobject.style.filter = 'alpha(opacity=' + value*10 + ')';
}

//returns textNode of given elementNode
function getXmlNodeValue(xmlNode){
	if(xmlNode.textContent) {return xmlNode.textContent;}
	else if(xmlNode.text){return xmlNode.text;}
	else if(xmlNode.firstChild.nodeValue){return xmlNode.firstChild.nodeValue;}
	else {return null;}
}

//returns all childeren of given parentNode
function childElements(parentNode) {
	var l= new Array();
	for (var i= 0; i<parentNode.childNodes.length; i++)
		if (parentNode.childNodes[i].nodeType==1){
		l[l.length]= parentNode.childNodes[i];
	}
	if (l.length){return l;}
	else{return false;}
}

//returns correct elements
function returnElements(parentNode, tagname) {
	var l= new Array();
	for (var i= 0; i<parentNode.childNodes.length; i++)
		if ((parentNode.childNodes[i].nodeType==1) && (parentNode.childNodes[i].tagName == tagname)){
		l[l.length]= parentNode.childNodes[i];
	}
	if (l.length){return l;}
	else{return false;}
}

//Returns window ACTUAL height
function getDisplayHeight(){
	var height;
	if (window.innerHeight > 0) {
		height = window.innerHeight;
		model.notIE = true;
	} else if (document.documentElement.clientHeight > 0) {
		height = document.documentElement.clientHeight;
	} else {
		height = document.body.clientHeight;
	}
	return height;
}

//Returns window ACTUAL Width
function getDisplayWidth(){
	var width;
	if (window.innerWidth > 0) {
		width = window.innerWidth;
	} else if (document.documentElement.clientWidth > 0) {
		width = document.documentElement.clientWidth;
	} else {
		width = document.body.clientWidth;
	}
	return width;
}