// Reference local blank image
HOME_URL = "/";
FRONT_PAGE_PATH = "home";
Ext.BLANK_IMAGE_URL = 'javascript/ext-2.2/resources/images/default/s.gif';
Ext.Updater.defaults.indicatorText = "<div id='loadingIndicator'><div>Loading...</div><img src='" + HOME_URL + "wp-content/themes/hiro/images/large-loading.gif' /></div>";

// Create the sweet, sweet namespace
Ext.namespace('Hiro');
 
// Create application
Hiro = function() {
	// do NOT access DOM from here; elements don't exist yet

	// Private variables
	var currentDepth = -1;
	var currentPath = [];
	var mainEl;
	var mainInnerEl;

	// Private functions
	setPath = function(full_path) {
		var path = full_path.split('/');
		var newDepth = path.length - 1;

		// Go backwards through current path and figure out what's changed
		var matchDepth = currentDepth;
		var removeEl;
		while (matchDepth >= 0) {
			// Check if we should remove the current check element
			if (path[matchDepth] == undefined || path[matchDepth] != currentPath[matchDepth]) {
			// Set slide parent to current depth if it's not the same as new path
				removeEl = Ext.get("path-" + matchDepth);
				matchDepth--;
			} else {
				break;
			}
		}

		// Linkify the remaining existing locations
		var replaceEl;
		var link;
		for(var l = 0; l <= matchDepth; l++) {
			replaceEl = Ext.get("location-" + l);
			// Combine the path parts into one link path
			link = path.slice(0,l+1).join('/');
			replaceEl.child('.text').update(generateLink(link, path[l]));
		}
		
		var constructPath = function() {
			// now construct all new parts of the path
			var parentEl, pathEl, slashEl, locationEl;
			var queuedEffects = 0;
			for(var d = (matchDepth + 1); d < path.length; d++,queuedEffects++) {
				if (d == 0) {
					parentEl = Ext.get("breadcrumb");
				} else {
					parentEl = Ext.get("path-" + (d - 1));
				}

				// Create a child path element
				pathEl = parentEl.createChild({id: "path-" + d, cls: "path"});
				// Create and fade in the slash
				slashEl = pathEl.createChild({id: "slash-" + d, cls: "slash"});
				slashEl.pause(queuedEffects * 0.8)
				slashEl.hide().update("/").fadeIn({duration: 0.3});
				// Create and slide in the location for current depth
				var locationText;
				// Make all locations that are not the current one into a link
				if (d == path.length - 1) {
					locationText = path[d];
				} else {
					locationText = generateLink(path.slice(0,d+1).join('/'), path[d]);
				}
				locationText = "<span class='text'>" + locationText + "<span>";
				locationEl = pathEl.createChild({id: "location-" + d, cls: "location"});
				locationEl.pause(0.3 + (queuedEffects * 0.8));
				locationEl.hide().update(locationText).fadeIn({duration: 0.2});
				// This used to be cooler (the new text slides in) but it was bugged in Firefox.
//				locationEl.hide().update(locationText).slideIn('l', {stopFx: true, duration: 0.2});

				// Add location to internal queue
				currentPath[d] = path[d];
			}
			currentDepth = newDepth;
		}
		
		// If a remove element was found, slide it out
		if (removeEl != undefined) {
			// var removeElParent = removeEl.parent();
			removeEl.slideOut('l', { remove: true, duration: .2, callback: constructPath });
			// If removed element's parent is the new depth, make sure to un-linkify it
			if (matchDepth + 1 == path.length) {
				var lastLocationEl = Ext.get("location-" + matchDepth);
				lastLocationEl.child('.text').update(path[matchDepth]);
			}
		} else {
			constructPath();
		}

	}
	
	generateLink = function(path, text) {
		var page = HOME_URL;
		// If it's not the home page, chop off home/ from the path to produce the page name
		if (path != "home") {
			page = page + path.replace( "home/", "" );
		}
		
		return '<a href="' + page + '">' + text + "</a>";
	}
	
	// Receives an html element anchor and takes the href and converts it into an ajax link
	convertLink = function(anchor) {
		// Don't convert the link if it's already been converted
		if (anchor.onclick == undefined) {
			// Set the DOM onclick to return false so regular link is disabled
			anchor.onclick = function(){return false};

			// Add click handler to use setPage to remotely load new page
			var path;
			if (anchor.pathname == "/" ) {
				path = "home";
			} else {
				path = "home" + anchor.pathname;
			}

			Ext.get(anchor).on("click", function() {
				Hiro.setPage(path);
			});
		}
	}
	
	convertExternalLink = function(anchor) {
		Ext.get(anchor).addClass("external");
	}
	
	// Grabs all links on page and ajaxifies them
	processLinks = function() {
		// Select all links that have an href that starts with /, ie local.
		var links = Ext.DomQuery.select("a[href^=/]");

		for (var a = 0; a < links.length; a++) {
			convertLink(links[a]);
		}
		
		var externalLinks = Ext.DomQuery.select("a[href^=http]");

		for (var e = 0; e < externalLinks.length; e++) {
			convertExternalLink(externalLinks[e]);
		}
	}

	// Grab all unordered lists and nest the contents of the LI in a span.
	nestifyLists = function() {
		
		var items = Ext.DomQuery.select("li");

		var content;
		for (var i = 0; i < items.length; i++) {
			content = items[i].innerHTML;
			items[i].innerHTML = "";
			el = Ext.get(items[i]);
			el.createChild({tag: "span", html: content});
			el.addClass("fancy");
		}

	}
	
	// Public space
	return {
		// Public properties

		// Public methods
		loadPage: function(path) {
			var	page = HOME_URL;
			// If it's not the home page, chop off home/ from the path to produce the page name
			if (path == "home") {
				page = page + FRONT_PAGE_PATH;
			} else {			
				page = page + path.replace( "home/", "" );
			}

			// Preserve the current height of the main element so that we can later scale it to fit the new content
			mainEl.setHeight(mainInnerEl.getHeight());

			mainInnerEl.load({
				url: page + "?js=true",
				callback: function() {
						mainInnerEl.hide();
						mainEl.scale(undefined, mainInnerEl.getHeight(), { easing: 'easeOut', duration: .3 });
						mainInnerEl.pause(0.3);
						mainInnerEl.fadeIn({duration: 0.2});
						setPath(path);
						nestifyLists();
						processLinks();
 						setupZoom();
					}
			});
		},
		setPage: function(path) {
			Ext.History.add(path);
		},
		// The almighty init function called by onReady booya
		init: function() {

			Ext.History.init();
			//generate location elements
			mainInnerEl = Ext.get("main-inner");
			mainEl = mainInnerEl.parent();

			if (window.location.hash.length == 0) {
				// If there is no hash and no path was specified load home
				if (window.location.pathname.split("/").length > 2) {
					setPath("home" + window.location.pathname.substr(0, window.location.pathname.length-1));
					nestifyLists();
					processLinks();
					setupZoom();
				} else {
					Hiro.setPage("home");
				}
			}else{
				// Otherwise try to load the page given in the hash
				Hiro.loadPage(window.location.hash.substr(1));
			}
			
			// Handle this change event in order to restore the UI to the appropriate history state
			Ext.History.on('change', function(path){
							if(path){
								Hiro.loadPage(path);
							}else{
								Hiro.loadPage("home");
							}
					});
		}
	};
}();

Ext.onReady(Hiro.init, Hiro);
