//static singleton
var PageManager = (function() {
	
	//private static vars
	var cache = {},
		EXPANDED_FOOTER_HEIGHT = 550,
		currentPage,
		redirectTimeout,
		HASH_BANG = /[#!]/g,
		ENDING_SLASH = /\/$/;
	
	//private static funcs
	function isFooterPage(url) {
		return !!url.match(/\/footer/);
	}
	
	function parseURL(fullURL) {
		var segments = fullURL.split(':'),
				params = {},
				url = segments.shift();
				
		url = url.replace(HASH_BANG, '');
		if(url.length > 2) {
			url = url.replace(ENDING_SLASH, '');
		}
		
		if(segments.length) {
			params = {};
			
			segments[0].split('&').forEach(function(keyval) {
				var splitted = keyval.split('=');
				params[splitted[0]] = $defined(splitted[1]) ? unescape(splitted[1]) : true;
			});
		}
		
		return {
			params: params,
			url: url
		};
	}
	
	
	
	//public api
	return {
		
		getPage: function(url, options) {
			var segments = parseURL(url);
			var page = cache[segments.url] || (cache[segments.url] = new Page(segments.url, options));
			/*if(segments.params) {
				page.setParams(segments.params);
			}*/
			return page;
		},
		
		loadPage: function(url) {
			return this.getPage(url).load();
		},
		
		showPage: function(url) {
			var page,
				options = {};
				
			if(url instanceof Page) {
				page = url;
				url = page.getURL();
			} 
			
			//parse the url for language, params, etc
			var segments = parseURL(url),
				path = segments.url,
				params = segments.params;
			
			//default index to /landing	
			if (!path || path == '#' || path == '/') {
				path = '/landing';
			}
			

			
			//handle FooterPages
			if(isFooterPage(path)) {
				PageManager.expandFooter();
				options.container = 'FooterContent';
			} else {
				PageManager.contractFooter();
			}
			
			
			//get the page, and set the params
			page = this.getPage(path, options);
			page.setParams(params);
			
			if(currentPage == page) {
				clearTimeout(redirectTimeout);
				return;
			}
			
			//unload the current page
			if(currentPage) {
				currentPage.remove(function() {
					page.insert();
				});				
			} else {
				page.insert();
			}
			
			//clearTimeout(redirectTimeout);
			
			return this.setCurrentPage(page);
		},
		
		getCurrentPage: function() {
			return currentPage;
		},
		
		setCurrentPage: function(page) {
			//is this a good idea?
			//shouldn't the currentPage *always* be the visible page?
			//meaning you should call showPage() instead?
			
			return currentPage = page;
		},
		
		contractFooter: function() {
			var nav = $('Nav'),
				footer = $('Footer');
				
			if(footer.getStyle('height').toInt() < EXPANDED_FOOTER_HEIGHT) {
				return;
			}
			
			footer.removeClass('open');
			nav.tween('bottom', nav.getStyle('bottom').toInt() - EXPANDED_FOOTER_HEIGHT);
			footer.morph({
				'height': footer.retrieve('original:height'),
				'background-color': footer.retrieve('original:bg')
			}).get('morph').chain(function() {
				PageManager.getCurrentPage().ifShouldCenter();
			});
		},
		
		expandFooter: function() {
			var nav = $('Nav'),
				footer = $('Footer');
				
			if(footer.getStyle('height').toInt() >= EXPANDED_FOOTER_HEIGHT) {
				return;
			}
			
			footer.addClass('open');
			nav.tween('bottom', nav.getStyle('bottom').toInt() + EXPANDED_FOOTER_HEIGHT);
			footer.store('original:height', footer.getStyle('height'));
			footer.store('original:bg', footer.getStyle('background-color'));
			footer.morph({
				'height': EXPANDED_FOOTER_HEIGHT,
				'background-color': '#fff'
			});
		},
		
		redirect: function(location, delay) {
			delay = $defined(delay) ? delay : 3000;
			clearTimeout(redirectTimeout);
			redirectTimeout = setTimeout(function() {
				window.location.hash = '!' + location;
			}, delay)
		}
		
	}
})();



window.addEvent('domready', function() {
	//setup history for deep-linking ajax
	window.addEvent('hashchange', function(hash) {
		PageManager.showPage(hash);
	});
	
	//load initial page
	PageManager.showPage(window.location.hash);
});