/**
 * History manager
 * Based on statemanager by matthew john tretter
 */
 
ProtoHistory = function(){
	this.rate = 100;
	this.cancelLoad = false;
	this.active = true;			//Set this to false if you want to turn off event triggers temporarily.
	
	this.init = function(){
		if(!defined(this.rate)) {ProtoHistoryObj.init(); return false;};
		//Sniff browser to determine what method to use
		if(browsers.ie) this.method = 'iframe';
		else if(browsers.saf) this.method = 'link';
		else this.method = 'hash';
		
		switch(this.method){
			case 'iframe':
				this.refreshPage = false;
				//create the iframe
				this.iframe = document.createElement('iframe');
				this.iframe.setAttribute('src', 'about:blank');
				this.iframe.setAttribute('name', 'ProtoHistory-iframe');
				this.iframe.setAttribute('id', 'ProtoHistory-iframe');
				this.iframe.style.visibility = 'hidden';
				this.iframe.style.width = '0px';
				this.iframe.style.height = '0px';
				this.iframe.style.position = 'absolute';
				this.iframe.style.overflow = 'hidden';				
				
				document.body.appendChild(this.iframe);
				var hash = this.getHash();
				if(hash) setTimeout(function(){ProtoHistoryObj.fire(hash)}, 0);
				
				//Sync the iframe and the main page
				//Can't use this.iframe because it triggers a security error
				frames['ProtoHistory-iframe'].document.open();
				if(hash) frames['ProtoHistory-iframe'].document.write('<script>parent.document.location.hash="'+(hash ? hash : '')+'"; parent.ProtoHistoryObj.updateIFrame("'+hash+'");</script>');
				else frames['ProtoHistory-iframe'].document.write('<script>parent.document.location.hash=""; parent.ProtoHistoryObj.updateIFrame();</script>');
				frames['ProtoHistory-iframe'].document.close();
			break;
			case 'link':
				document.location.ProtoHistory = document.location.ProtoHistory || {};
				var loc = document.location.ProtoHistory;
				window.onunload = function(){loc.oldHistoryLength = -1;};
				if(loc.deepLink){
					loc.oldHistoryLength = -1;
					loc.deepLink = false;
				}
				//Create state list
				if(typeof loc.stateList == 'undefined'){
					loc.stateList = [this.getHash()];
					loc.deepLink = loc.stateList[0];
					loc.offset = history.length-1;
					while(loc.offset){
						loc.stateList.unshift(null);
						loc.offset--;
					}
					delete loc.offset;
					loc.oldHistoryLength = document.location.hash ? -1 : history.length;
				}
				
				//Watch to see if the length of the history object changes
				var checkHistory = function(){
					var loc = document.location.ProtoHistory;
					if(this.cancelLoad){
						this.cancelLoad = false;
						loc.oldHistoryLength = history.length;
						return;
					}
					if(history.length != loc.oldHistoryLength){
						var hash = loc.stateList[history.length - 1];
						ProtoHistoryObj.fire(hash);
						loc.oldHistoryLength = history.length;
					}
				}
				this.checkInterval = setInterval(checkHistory, this.rate);
			break;
			case 'hash':
				this.oldHash = this.getHash();
				
				//See if the hash changes
				var checkHash = function(){
					var hash = ProtoHistoryObj.getHash();
					if(hash != ProtoHistoryObj.oldHash){
						ProtoHistoryObj.oldHash = hash;
						ProtoHistoryObj.fire(hash);
					}
				}
				
				this.checkInterval = setInterval(checkHash, this.rate);			
			break;
		};
	};
	
	this.setState = function(stateID, title){
		//Sets a state.  StateID is a unique ID, title is the title you want to appear on the page for this state
		//If you don't want the title to change, just don't pass a new one in.
		if(!this.active) return false;
		if(defined(title)) this.setTitle(title);
		
		//prevent loops
		if(this.event) return;
		
		switch(this.method){
			case 'hash':
				document.location.hash = stateID == false ? '#' : stateID;
				this.oldStateID = stateID;
			break;
			case 'iframe':
				this.setIFrame(stateID);
			break;
			case 'link':
				this.cancelLoad = true;
				
				var a = document.createElement('a');
				a.setAttribute('href', stateID == false ? '#' : '#' + stateID);
				var evt = document.createEvent('MouseEvents');
				evt.initEvent('click', true, true);
				a.dispatchEvent(evt);
				
				document.location.ProtoHistory.stateList.push(stateID);
			break;
		};
		this.fire(stateID, true);
	};
	
	this.fire = function(stateID, manual){
		//Trigger the event for this state
		stateID = stateID || false;
		
		//Call the appropriate handler
		this.event = {id: stateID};
		if(this.stateChangeHandler) this.stateChangeHandler(this.event);
		if(manual) if(this.stateSetHandler) this.stateSetHandler(this.event);
		else if(this.stateRevistedHandler) this.stateRevistedHandler(this.event);
		
		this.event = null;	
		return false;
	};
	
	this.setIFrame = function(stateID){
		//sets the iFrame to a state
		this.refreshPage = false;
		frames['ProtoHistory-iframe'].document.open();
		frames['ProtoHistory-iframe'].document.write('<script>parent.document.location.hash = "' + (stateID == false ? '#' : stateID) + '"; setTimeout( function(){ parent.ProtoHistoryObj.updateIFrame("' + stateID + '"); }, 0);</script>');
		frames['ProtoHistory-iframe'].document.close();
	};
	
	this.updateIFrame = function(stateID){
		//updates the iframe
		if(this.refreshPage) this.fire(stateID == '' || stateID == false ? false : stateID);
		else this.refreshPage = true;
	};
	
	this.setTitle = function(title){
		//sets the title
		window.document.title = title || '';
	};
	
	this.getHash = function(){
		return document.location.href.split('#')[1] || false;
	};
	return this;
};

ProtoHistoryObj = new ProtoHistory();

//Moved this to the body onload
//window.onload = 'ProtoHistoryObj.apply(ProtoHistoryObj.init); ';

//Pool specific additions
ProtoHistoryObj.savePool = function(state){
	//processes the state array for a basin and triggers ProtoHistory.setState when it's done	

	var serialized = new Array();
	
	//First, look at the axes
	//All axes settings start with 'a'
	for(var setting in state.axes){
		serialized.push('a' + setting + '=' + encodeURIComponent(state.axes[setting]));			
	};
	//Then filters
	//All filter settings start with 'f'
	for(var i=0; i<state.filters.length; i++){
		serialized.push('f=' + state.filters[i][0] + '|' + encodeURIComponent(state.filters[i][1]));	
	};
	//Then panels
	//All panel settings start with a 'p' (do you see a pattern yet?)
	for(var i=0; i<state.panels.length; i++){
		serialized.push('p=' + state.panels[i][0] + '|' + state.panels[i][1]);	
	};
	
	var stateString = serialized.join('&');
	//alert(stateString);
	
	ProtoHistoryObj.setState(stateString);
};