/**
 * JSON Navigation will expand the local navigation away from a (accessibility
 * friendly) flat list into a hierarchy more suitable for screen.
*/

// TODO - breadcrumb to come from nav. Then we're getting phone friendly at last...

openc.LOCAL_NAV_DEPTH = 2;

// An array (that may be specialised) of pages excluded from local navigation
openc.excludeFromJsonNavigation = new Array();


openc.jsonNavigation = function() {

	// If this page is excluded
	if(jq.inArray(openc.PATH_TO_PAGE, openc.excludeFromJsonNavigation) != -1) {
		return;
	}
	
	// If a small screen (iPhone baseline), or if no JSON to work with, do nothing
	if (screen.width <= 480 || openc.jsonstructure == undefined) {
		return;
	}
	
	var debugUL = null;
	//debugUL = jq('body').prepend('<ul id="debugJson" style="margin:0;position:absolute;top:10px;right:10px;width:300px;min-heigh400px;max-height:800px;overflow:auto;border:5px solid black;z-index:1000;background-color:black;color:green;font-family:monospace;font-size:13px;"></ul>').find('ul#debugJson');
	//debugUL.css('opacity',0.8);
	
	// Parse the structure
	openc.parseJsonStructure(openc.jsonstructure, openc.jsonstructure, null, debugUL);
	
	
	
	// Find the current node in the structure
	openc.CURRENT_NODE = openc.getNodeByPath(openc.PATH_TO_PAGE, openc.jsonstructure);
	
	
	// Node not in JSON
	if(!openc.CURRENT_NODE) {
		return;
	}
	
	// Walk up from the current node to a child of root, or stay on home if 
	// current is root
	openc.TOP_SECTION_NODE = openc.CURRENT_NODE;
	while(openc.TOP_SECTION_NODE.parent && !openc.TOP_SECTION_NODE.parent.root) {
		openc.TOP_SECTION_NODE = openc.TOP_SECTION_NODE.parent;
	}
	
	// Find local navigation root (if any)
	var startingNode = openc.findLocalNavRoot(openc.CURRENT_NODE, openc.CURRENT_NODE.children ? openc.LOCAL_NAV_DEPTH - 2 : openc.LOCAL_NAV_DEPTH - 1);

	
	// If there is a starting node
	if(startingNode) {
	
		// Dispatch event proclaiming the new object
		openc.eventMediator.dispatchEvent("beforeJsonNavigation");
	
		var localNavDiv = openc.getLocalNavContainer();
		
		// Replace contents initially with title of starting node
		localNavDiv.html('<h2><a href="' + startingNode.path + '"><span>' + startingNode.title + '</span></a></h2><ul></ul>');
		
		// Recursive function called for each child
		function build(ul, node, lastChild, firstChild) {
			ul.append('<li><a href="' + node.path + '"><span>' + node.title + '</span></a></li>');
			var li = ul.find('li:last');
			// last child class
			if(lastChild) {
				li.addClass('lst');
			}
			// First child class
			if(firstChild) {
				li.addClass('fst');
			}
			// open class
			if(node.children) {
				li.addClass('opn');
			}
			if(node == openc.CURRENT_NODE) {
				li.addClass('cur').find('span').addClass('cur');
			} else {
				// Otherwise add handlers
				li.find('span').mouseover(openc.onLocalNavLiSpanOver);
				li.find('span').mouseout(openc.onLocalNavLiSpanOut);
			}
			// If this node is on path to the current node and has children
			if(node.onPath && node.children) {
				li.addClass('opn');
				// Call recursively
				li.append('<ul></ul>');
				var ul = li.find('ul:last');
				for(var i = 0 ; i < node.children.length ; i++) {
					build(ul, node.children[i], i == node.children.length - 1, i == 0);
				};
			}
		}
		
		// Start the process with the children of the starting node
		var ul = localNavDiv.find('ul');
		var length = startingNode.children.length;
		for(var i = 0 ; i < length ; i++) {
			build(ul, startingNode.children[i], i == length - 1, i == 0);
		};
	}
}

/**
 * Local navigation mouse handlers
*/
openc.onLocalNavLiSpanOver = function() {
	jq(this).addClass('cur').parents('li:first').addClass('cur');
}
openc.onLocalNavLiSpanOut = function() {
	jq(this).removeClass('cur').parents('li:first').removeClass('cur');
}
 
 /**
  * Assosiated top section nodes paths with jQuery selectors
 */
 openc.pageLocalNavContainer = {};
 
 
 /**
  * Get local nav container. Returns div#local-navigation-flat by default. If
  * necessary this is created, and if necessary, so is portal-column-two to 
  * contain it. However, a path in openc.sectionLocalNavContainer may point to a
  * different container. It's checked against openc.PATH_TO_PAGE. Note that 
  * the contents of the container are wiped out, so any nav that existed there 
  * is replaced.
 */
 openc.getLocalNavContainer = function() {
 
 	// Delete existing local navigation (if any)
 	jq('div#local-navigation-flat').remove();
 
 	// If this page's path name is in sectionLocalNavContainer
 	var path = openc.PATH_TO_PAGE;
 	
 	for(var i in openc.pageLocalNavContainer) {
 		if(i == path) {
 			var mapping = openc.pageLocalNavContainer[i];
 			// Find the container
 			var container = jq(mapping.container);
 			// The HTML used to inject the local nav container
 			var insertHTML = '<div id="local-navigation-flat"></div>';
 			// Append/prepend the local nav container
 			if(mapping.append) {
 				container.append(insertHTML);
 			} else {
 				container.prepend(insertHTML);
 			}
 			// If portal column two is empty
 			if(jq('div#portal-column-two *').length == 0) {
 				// Remove it
 				jq('div#portal-column-two').remove();
 				// Change column classes
				jq('body, div#columns').removeClass('cols-mr').addClass('cols-m');
 			}
 			// Return the newly created container
 			return container.find('div#local-navigation-flat');
 		}
 	}
	// Look for portal-column-two
	var portalColumnTwo = jq('div#portal-column-two');
	// If it doesn't exist
	if(portalColumnTwo.length == 0) {
		// Change body class and div#columns class to two column
		// TODO - this should cater for three column layouts
		jq('body, div#columns').removeClass('cols-m').addClass('cols-mr');
		jq('div#portal-column-content').after('<div id="portal-column-two"></div>');	
	}
		
	// Prepend local nav container to portal-column-two
	jq('div#portal-column-two').prepend('<div id="local-navigation-flat"></div>').find('div#local-navigation-flat');
	return jq('div#local-navigation-flat');
 }
 
 
/**
 * Constants for debugging
*/

/**
 * Recursive function pases JSON expanding it with verbose property names and 
 * more references
*/
openc.parseJsonStructure = function(structure, node, parent, debugUL) {
	
	// Give verbose names to short names
	node.name = node.nme;
	node.title = node.ttl;
	node.type = node.typ;
	node.children = node.cdn;
		
	// Add parent reference
	node.parent = parent;
	
	// Give the node a path
	node.path = node.path != undefined ? node.path : (node.parent == undefined) ? '/' : (node.parent.path == "/") ? ('/' + node.name) : (node.parent.path + '/' + node.name);
	
	// If this node's path starts the current node's path
	if(openc.PATH_TO_PAGE.indexOf(node.path) == 0) {
		node.onPath = true;
	}
		
	// Use structure as a hash, use a safe key (replace '/' characters)
	structure[node.path.replace(/\//g, '__')] = node;
	
	// If there are not children remove the array
	if(node.children.length == 0) {
		// Remove empty array
		node.children = node.cdn = null;
	}
	
	// If debugging output
	if(debugUL) {
		debugUL.append('<li style="color:#ccc"><a style="color:#ccc" href="' + node.path + '">' + node.title + '(' + (node.children != undefined) + ')' + '</a></li>');
	}
		
	// If there are children
	if(node.children != undefined) {
	
		// If debugging output
		if(debugUL) {
			// Prepare a list for the recursive call
			debugUL = debugUL.append('<ul>').find('ul:last');
		}

		// Call recursively
		jQuery.each(node.children, function(index, value) {
			openc.parseJsonStructure(structure, value, node, debugUL);
		});
	}
		
}

/*******************************************************************************
Get node by path
*******************************************************************************/

// Return node object matching path
openc.getNodeByPath = function(path, structure){

	return structure[path.replace(/\//g,'__')];
}


/*******************************************************************************
Find local nav root
*******************************************************************************/

// Find the local nav start node. Never start on a class of 'Home' and try to 
// reach up as far as reach
openc.findLocalNavRoot = function(start, reach) {

	// If start is Home, or parent is a class of 'Home' and there are 
	// no children, return null
	if(start.root == true || (start.parent.root == true && start.children == undefined)) {
		return null;
	} else {
		// if reach > 0 and parent is not root, decrement reach and look up
		if(reach > 0 && start.parent && start.parent.root == false) {
			return openc.findLocalNavRoot(start.parent, reach - 1);
			
		// Otherwise this is the start
		} else {
			return start;
		}
	}
}
/**
* DOM loaded
*/
jq(function() {

	if(openc.IS_RIA_CLIENT && !openc.IS_EDIT_PAGE && openc.IS_DESKTOP) {
		openc.jsonNavigation();
	}
});






