/*
Script: state.js
	
Dependencies:
	
Author: eBestPractice, <http://wwwm.eBestPractice.net>
*/

/*
State: 
	Enmagatzema la informacio associada a un estat de la pgina.

Propietats
----------
 - idState: Cadena que identifica l'estat
 - idMenu: Cadena que identifica el men associat a l'estat
 - breadcrumbList: La llista d'elements de l'arbre de navegaci (i on linken).
 				   El format s ['text1','estat1','text2','estat2',...,'textN','']
				   L'ltim element correspon a l'estat actual i no contindr link
 - goTo: La funci a executar per passar a aquest estat de forma directa
 - transitionTo: La funci a executar per passar a aquest estat des d'un altre amb efectes.
 				 Si no se li assigna codi, s'executar el codi de la funci goTo
*/
var State = new Class(
	{    
		initialize: function(idState,
							 idMenu,
							 title,
							 transitionWithoutEffectsCode,
							 transitionWithEffectsCode
							 )
		{        
			this.idState = idState; 
			this.idMenu = idMenu;
			this.title = title;
			this.goTo = transitionWithoutEffectsCode;
			this.transitionTo = transitionWithEffectsCode;
		}
	}
);


var StateListener = new Class(
	{    
		initialize: function(stateListenerId,
							 initialState,
							 stateList,
							 breadcrumbList,
							 breadcrumbContainer,
							 breadcrumbActualClass,
							 breadcrumbHistoryClass,
							 locale
							 )
		{        
			this.id = stateListenerId;
			this.currentState = initialState;
			this.initialState = initialState;
			if(stateList)
			{
				this.stateList = new Array();
				for(i=0;i<stateList.length;i++)
				{
					this.stateList[stateList[i].idState]= stateList[i];
				}
			}
			//Tractament del breadcrumb
			//TODO: Indicador de si breadcrumb
			this.breadcrumbList = breadcrumbList;
			this.breadcrumbContainer = breadcrumbContainer; 
			this.breadcrumbActualClass = breadcrumbActualClass;
			this.breadcrumbHistoryClass = breadcrumbHistoryClass;
			this.locale = locale;
			
			//Per decidir quč actualitzem segons el navegador
			var detect = navigator.userAgent.toLowerCase();
			if(detect.indexOf("msie")>-1)
				 this.funcionament = 'iframe';
			else
				 this.funcionament = 'hash';
			
			this.iframe = null;
			this.interval=null;

			this.isTransition = false;
		},

		startListeningChanges: function()
		{
			this.interval = setInterval(this.id + ".testURLChanges();",200);
		},
		
		stopListeningChanges: function()
		{
			if(this.interval!=null)
			{
				clearInterval(this.interval);
				this.interval=null;
			}
		},
		
		testURLChanges: function()
		{
			var state = null;
			var transition = null;
			if(this.funcionament == 'hash')
			{
				state = window.location.hash==null?"":window.location.hash.substring(1);
				transition = this.isTransition;
			}
			else
			{
				state = this.iframe.contentWindow.getState();
				transition = this.iframe.contentWindow.getTransition();
			}
			
			//Comprovem que no sigui null o buida (inici) i que hagi canviat l'estat.
			//Si es així, saltem al link adequat
			if(state!=null && state!="" && state!=this.currentState)
			{
			  //this.stopListeningChanges();
				this.changeState(state,transition);
			}
			//El cas en quč tornem a l'estat buit (inicial) pel back button o perquč
			//hem esborrat part de la URL (el hash)
			else if(this.currentState!=this.initialState && state=="")
			{
			  //this.stopListeningChanges();
				this.first(false);
			}
		},

		first: function(withTransition)
		{
			document.title = this.stateList[this.initialState].title;
			if(this.funcionament == 'iframe')
			{
				if(this.iframe == null) this.crearFrame(this.initialState,withTransition);
			}
	
			if(withTransition) this.transitionTo(this.initialState);
				else this.goTo(this.initialState);
			
			this.currentState = this.initialState;
			
			if(this.interval == null)
				this.startListeningChanges();
			
		},
		
		add: function(state)
		{
			if(!this.stateList)
				this.stateList = new Array();
			this.stateList[state.idState] = state;
		},
		
		crearFrame: function(stateID,withTransition) 
		{
			/* **********************************************************************
			 * Inicialitzem creant l'IFRAME que ha de servir per emmagatzemar l'estat.
			 * Aquest IFRAME no ser visible, noms serveix per tal que es reconeixi
			 * el canvi de la URL en l'historic.
			 * */ 
			this.iframe = document.createElement('iframe');
            		this.iframe.setAttribute('src', 'back.html');
            		this.iframe.setAttribute('name', 'ebpBackButton');
            		this.iframe.setAttribute('id', 'ebpBackButton');
            		this.iframe.style.visibility = 'hidden';
            		this.iframe.style.width = '0';
            		this.iframe.style.height = '0';
            		this.iframe.style.position = 'absolute';
            		this.iframe.style.overflow = 'hidden';
			this.iframe.setAttribute('src','back.html?state=' + stateID + '&' + (withTransition?'transition=1':'transition=0'));
            		$('bodyid').appendChild(this.iframe);
		},
		
		setState: function(stateID, withTransition)
		{
			if(this.currentState!=stateID)
			{
				if(this.funcionament == 'hash')
				{
					var auxHash = '#' + stateID;
					if(stateID == this.initialState) 
					{
						window.location.hash='';
					}
					else if(window.location.hash!= auxHash)
					 	window.location.hash = auxHash;
					this.isTransition = withTransition;
				}
	
				if(this.funcionament=='iframe')
				{
					if(this.iframe == null) 
						this.crearFrame(stateID,withTransition);
					else
						this.iframe.setAttribute('src','back.html?state=' + stateID + '&' + (withTransition?'transition=1':'transition=0'));
				}
			}
			if(this.interval == null)
					this.startListeningChanges();
		},

		changeState: function(stateID, withTransition)
		{
			if(this.currentState!=stateID)
			{
				
				document.title = this.stateList[stateID].title;

				if(this.funcionament == 'iframe')
				{
					var auxHash = '#' + stateID;
					if(stateID == this.initialState) 
					{
						window.location.hash='';
					}
					else if(window.location.hash!= auxHash)
					 	window.location.hash = auxHash;
					this.isTransition = withTransition;
				}
				
				if(withTransition) this.transitionTo(stateID);
				  else this.goTo(stateID);
				
				this.currentState = stateID;
			}
			if(this.interval == null)
				this.startListeningChanges();
		},
		
		getCurrentState: function()
		{
			return this.stateList[this.currentState];
		},

		getTitle: function(stateID)
		{
			if(this.stateList[stateID]!=null)
				return this.stateList[stateID].title;
			else
				return this.stateList[this.initialState].title;;
		},

		goTo: function(newState)
		{
			if(this.stateList[newState])
			{
				this.stateList[newState].goTo();
				this.updateBreadcrumbs(this.breadcrumbList[this.locale][newState]);
			}
		},
		
		transitionTo: function(newState)
		{
			//Existeix l'estat on volem anar
			if(this.stateList[newState])
			{
				if(this.stateList[newState].transitionTo !=null)
					this.stateList[newState].transitionTo();
				else
					this.stateList[newState].goTo();
				this.updateBreadcrumbs(this.breadcrumbList[this.locale][newState]);
			}
		},
		
		lockFunctionality: function() {
			var bodyEl = $('bodyid');
			this.newDiv = document.createElement('div');
			bodyEl.appendChild(this.newDiv);
			this.newDiv.setAttribute('id','tmpDiv');
			this.newDiv.style.left = bodyEl.getLeft() + "px";
			this.newDiv.style.top = bodyEl.getTop() + "px"; 
			this.newDiv.style.width = bodyEl.offsetWidth + 'px';
			this.newDiv.style.height = bodyEl.offsetHeight + 'px';
			this.newDiv.style.position = "absolute";
			this.newDiv.style.backgroundImage = "url(../images/transparentBackground.gif)";
			this.newDiv.style.zIndex = 1000;
		},
		
		unlockFunctionality: function () {
			if(this.newDiv!=null)
			{
				this.newDiv.parentNode.removeChild(this.newDiv);
				this.newDiv = null;
			}
		},
		
		
		updateBreadcrumbs: function(target) {
			var breads = $ES('li',this.breadcrumbContainer);
			var mainBreads = $E('ul',this.breadcrumbContainer);
			var numBreads = breads.length;
			var newBreadcrumbs = target;
			var numArgs = newBreadcrumbs.length;
			var i;
			var newBread;
			var newBreadLink;
			
			// delete breadcrumbs
			for (i=0;i<numBreads;i++)
				$(breads[i]).remove();
			
			// add new breadcrumbs
			for(i=0; i<numArgs; i=i+2) {
				newBread = new Element('li');
				
				if (i==numArgs-2) {
					// actual page
					$(newBread).appendText(newBreadcrumbs[i]);
					$(newBread).addClass(this.breadcrumbActualClass);
					$(newBread).injectInside($(mainBreads));
				}
				else {
					// hist page
					newBreadLink = new Element('a');
					$(newBreadLink).appendText(newBreadcrumbs[i]);
					//TODO: Adequar al canvi d'estat segons efectes volguts o no volguts
					newBreadLink.setAttribute('onclick','updateMenu(\''+newBreadcrumbs[i+1]+'\')');
					newBreadLink.setAttribute('href','javascript:void(0)');
					$(newBreadLink).addClass(this.breadcrumbHistoryClass);
					$(newBreadLink).injectInside($(newBread));
					$(newBread).injectInside($(mainBreads));
				}
			}
		}
	}
);

