/*
	Class managing navigation widgets 

	- Process cms documents tree (as a js tree)
	- offer a set of methods genrating the html for navigation widgets.
	- html for widgets is handled by another objet holdign the callback functions. 
	  That second objet is different for each skin in js/nav_handler.js file.

	  v 2.2
	  v2.1 : fixed empty footer
	  v2.2 : add support for nav_tree
	  v2.3 : compatible with prototype.js
	  v2.4 : added branch parameter in branch display
	  v2.6 : added branch parameter in zone and leaf display
	  v2.7 : fixed issue with prototype on docs arrays
	  v2.8 : fixed branch.docs iterator 
	  v2.9 : display of main nav even in footer page.
*/

function NxNav(desc) {
	this.tree=desc.tree;
	this.treeByPath={};
	this.treeTop={};
	this.treeZones={};
	this.treeArray=[];
	this.nbZones=0;

// base URL for displaying an article
	this.baseUrl="";
	this.cssClass='nav';

	for(var b in this.tree)
	{
		var branch=this.tree[b];

		// create lookup by path
		this.treeByPath[branch.path]=branch;

		// create tree as array
		this.treeArray[this.treeArray.length]=branch;

		// collect top level branches
		if (branch.level<=1 && branch.id.charAt(0)!='_')
		{
			this.treeTop[branch.path]=branch;
			this.nbZones++;
		}
		
		// group branches by top level path
		zone=NxNav.prototype._getZoneFromPath(branch.path);
		if (!this.treeZones[zone])
		{
			this.treeZones[zone]=new Array();
		}
		this.treeZones[zone][this.treeZones[zone].length]=branch;
	}
}

NxNav.prototype._getZoneFromPath=function(path)
{
	return path.replace(/^[?]-([^-]+)(-.*)?$/,'$1');
}

NxNav.prototype._getZoneName= function(zone)
{
	with (this)
		try {
			return treeByPath['?-'+zone].name;
		} catch(e) {
			return zone;
		}
}

NxNav.prototype._getBranchUrl=function(branch)
{
	with (this)
	{
		//if has docs, pick first one
		if (typeof(branch.docs)!='undefined' && branch.docs[0])
			return baseUrl+branch.docs[0].id+'.html';

		// else if top branch, pick first doc in the zone
		if (branch.level<=1)
		{
			var zone=_getZoneFromPath(branch.path);
			for (var i=0; i<treeZones[zone].length;i++)
			{
				var branch2=treeZones[zone][i];
				if (typeof(branch2.docs[0])!='undefined')
					return baseUrl+branch2.docs[0].id+'.html';
			}
		}

		// else no url
		return '#';
	}
}

NxNav.prototype._getTopMenu= function(path_code,hdler,barCB,linkCB,widget) {
	with (this)
	{
		// get direct children as links
		// debugger;
		var i2=0;
		var n=0;
		var current=-1;
		var aLinks=new Array();
		for (var p in treeTop)
		{
			var branch=treeTop[p];
			var is_current=(path_code.indexOf(branch.path)!=-1)?true:false;
			if (is_current)
				current=n;
			n++;
		}
		for (p in treeTop)
		{
			branch=treeTop[p];
			is_current=(path_code.indexOf(branch.path)!=-1)?true:false;
			aLinks[i2]=hdler[linkCB](branch.name,_getBranchUrl(branch),i2,is_current,n-1,current,'top',branch);
			i2++;
		}
		
		// display array of links
		var s=hdler[barCB](aLinks,widget);
		return s;
	}
}

NxNav.prototype._disp_zone= function(zone,aid,path_code,hdler,disp_zone,disp_branch,disp_leaf,widget)
{
	with (this)
	{
		var branches=treeZones[zone];
		var base_node=branches[0];

		// get zone name
		var zone_name='';
		if (typeof(base_node.fullName)!='undefined')
			zone_name=base_node.fullName;
		else if (typeof(base_node.name)!='undefined')
			zone_name=base_node.name;

		// display link table with zone header if any
		var s='';
		for (var i=0; i< branches.length;i++)
		{
			s+=_nav_zone_branch(zone,aid,branches[i],hdler,disp_branch,disp_leaf,widget);
		}

		// alert(s);
		var zone_name=_getZoneName(zone);
		return hdler[disp_zone](zone_name,s,widget,base_node);
	}
}

// nav in current zone
NxNav.prototype._nav_zone_branch= function(zone,aid,branch,hdler,disp_branch,disp_leaf,widget)
{
	with(this)
	{
		// display docs
		var s='';
		var is_cur_branch=false;
		var aLinks=new Array();
		var i=0;
		var n=0;
		var current=-1;

		for (var d=0; d< branch.docs.length;d++)
		{
			var doc=branch.docs[d];
			if (doc.name)
			{
				if(aid==doc.oid)
					current=n;
				n++;
			}
		}

		for (var d=0; d< branch.docs.length;d++)
		{
			var doc=branch.docs[d];
			if (doc.name)
			{
				doc.branch=branch;

				if (doc.id)
					url=baseUrl+doc.id+'.html';
				else
					url=document.location;

				var is_current=(aid==doc.oid);
				if (is_current)
					is_cur_branch=true;

				aLinks[i]=hdler[disp_leaf](zone,doc.name,url,i,is_current,widget,n-1,current,doc);
				i++;
			}
		}

		var s = aLinks.join("");
		var url=_getBranchUrl(branch);
		var zone_name=_getZoneName(zone);
		return hdler[disp_branch](zone, branch.name, branch.fullName, url, branch.id, branch.level, is_current,s,aLinks,widget, branch);
	}
}

// ======== VIEW: top navigation ===========

// getting level 0 of the tree
NxNav.prototype.nav_top= function(path_code,hdler,returnit) {
	with (this)
	{
		// if only one zone
		if (nbZones <=1)
		{
			// prefered method for displaying only one branch is top nav ?
			if (typeof(hdler.properties)!="undefined" && 
					typeof(hdler.properties.one_branch_only)!="undefined" && hdler.properties.one_branch_only=="top")
				return nav_top_links(path_code,hdler);
			else
				// no? => no point displaying top menu
				return "&nbsp;";
		}


		var s = this._getTopMenu(path_code,hdler,"top_menu_bar","top_menu_link");

		if (typeof(returnit)!="undefined" && returnit==true)
		{
			return s;
		}
		if (s!='')
			document.write(s);
	}
}

// when only one branch and prefered choice for displaying is top
NxNav.prototype.nav_top_links= function(path_code,hdler) {
	with (this)
	{
		var i2=0;
		var aLinks=new Array();
		var last=-1;
		var current=-1;
		for (var p in treeTop)
		{
			var branch=treeTop[p];

			// count docs
			i2=0;
			for (var d=0; d< branch.docs.length;d++)
			{
				var doc=branch.docs[d];
				if (doc.name)
				{
					if(aid==doc.oid)
						current=i2;
					i2++;
				}
			}
			last=i2-1;

			// display docs
			i2=0;
			var is_cur_branch=false;
			for (var d=0; d< branch.docs.length;d++)
			{
				var doc=branch.docs[d];
				if (doc.name)
				{
					if (doc.id)
						url=baseUrl+doc.id+'.html';
					else
						url=document.location;

					var is_current=(aid==doc.oid);
					aLinks[i2]= hdler.top_menu_link(doc.name,url,i2,is_current,last,current);
					i2++;
				}
			}

			// display array of links
			return hdler.top_menu_bar(aLinks);
		}
	}
}

// ======== VIEW: banner title ===========
NxNav.prototype.getDocSection= function(node,path) 
{
	with (this)
	{
		var branch=treeByPath[path];
		if (branch)
			return branch.name;
		else
			return '';
	}
}

// ======== VIEW: navigation path ===========

// getting level 0 of the tree
NxNav.prototype.nav_path= function(path_code,hdler) 
{
	with (this)
	{
		if (!hdler)
			return '';

		// split up path
		var apath=path_code.split('-');
		var path='?';
		var i2=0;
		var aLinks=new Array();
		for(var i=1;i<apath.length;i++)
		{
			// create path node
			path=path+'-'+apath[i];

			// get url and name
			var branch=treeByPath[path];
			if (branch)
			{
				var url=_getBranchUrl(branch);
				var name=branch.fullName;
				if (name=='')
					name=branch.name;
		
				// add link into array
				aLinks[i2++]=hdler.path_link(branch.id,url,name);
			}
		}
		
		// display array of links
		var s=hdler.path_bar(aLinks);
		return s;
	}
}

// ===== JS VIEW: navigation tree ==========

// displaying navigation tree related to current zone
NxNav.prototype.nav_zone= function(aid,path_code,hdler) 
{
 // debugger;
	with (this)
	{
		// if only one zone, check if zone to be displayed
		if (nbZones <=1 && typeof(hdler.properties)!="undefined" && typeof(hdler.properties.one_branch_only)!="undefined" && hdler.properties.one_branch_only=="top")
				return '';

		// get current zone name
		var zone=_getZoneFromPath(path_code);
		if (zone=='?')
			zone='home';

		// check if all zones are to be displayed
		var zone_mode;
		if (typeof(hdler.zone_mode)!="undefined")
			zone_mode=hdler.zone_mode(nbZones,zone);
		else
			zone_mode="current_zone";

		// if system zone (?-_header/?-_footer), display home
		if (path_code.match(/^[?]-_/))
			// return '';
			zone='home';

		// current zone doesnt exist?
		if (!treeZones[zone])
			return '';

		// get collection of branches for this branch
		var branches;
		var s='';
		if (zone_mode=='all_zones')
		{
			for (z in treeZones)
			{
				if (z.charAt(0)!='_')
				{
					s+=_disp_zone(z,aid,path_code,hdler,'disp_zone','disp_branch','disp_leaf','zone');
				}
			}
		}
		else
			s=_disp_zone(zone,aid,path_code,hdler,'disp_zone','disp_branch','disp_leaf','zone');

		// v2.2 added support for tree root
		if (typeof(hdler['disp_tree'])!="undefined")
		{
			return hdler['disp_tree'](s,'zone');
		}

		return s;
	}
}

// displaying navigation tree related to a widget
NxNav.prototype.nav_widget= function(aid,path_code,hdler,widget) 
{
	with (this)
	{
		// get current zone name
		var zone=_getZoneFromPath(path_code);
		if (zone=='?')
			zone='home';

		// current zone doesnt exist?
		if (!treeZones[zone])
			return '';

		// get collection of branches for this branch
		var branches;
		var s='';
		s=_disp_zone(zone,aid,path_code,hdler,'disp_zone_'+widget,'disp_branch_'+widget,'disp_leaf_'+widget,widget);

		return s;
	}
}

// compatibility with previous API
function nav_top(tree,path_code,hdler) {
	document.write(window.nav_object.nav_top(code_article_path,nav_handler,true));
}

function getDocSection(node,path) 
{
	return window.nav_object.getDocSection(node,path);
}

function nav_path(tree,path_code,hdler) 
{
	document.write(window.nav_object.nav_path(path_code,hdler));
}

function nav_zone(aid,tree,path_code,hdler) 
{
	document.write(window.nav_object.nav_zone(aid,code_article_path,nav_handler));
}

function nav_header(aid,tree,hdler) 
{
	if (hdler.disp_zone_header)
		document.write(window.nav_object.nav_widget(aid,'?-_header',nav_handler,'header'));
}

function nav_footer(aid,tree,hdler) 
{
	if (hdler.disp_zone_footer)
		document.write(window.nav_object.nav_widget(aid,'?-_footer',nav_handler,'footer'));
}

function nav_menu(aid,tree,nav_handler,widget) 
{
	document.write(window.nav_object.nav_widget(aid,'?-_'+widget,nav_handler,widget));
}

// init nav
if (typeof(window.nav_pages)!="undefined")
{
	window.nav_object=new NxNav(window.nav_pages);
}

