/* @Project: Javascript Breadcrumb Creation System */
/* @File:  	 lib.bcns.js */
/* @Author:  Gregory Patmore */
/* @Contact: mail at gregorypatmore dot com */
/* @Created: Mon Jun 11 10:31:26 EDT 2007 */
/* @Notes:   Defines objects needed to create DOM scripted breadcrumbs*/
	

/* Lowest level object, keeps data for a single folder */
/******************************************************************************
 ******************************************************************************
 * BCS_FolderRefItem definition ***********************************************
 ******************************************************************************
 ******************************************************************************/
function BCS_FolderRefItem(folder, txtName, linkURL, subFolderDictionary){
	this.folder = folder;
	this.txt = txtName;
	this.link = linkURL;
	this.subFolderDictionary = subFolderDictionary;
}

/******************************************************************************
 ******************************************************************************
 * END BCS_FolderRefItem definition *******************************************
 ******************************************************************************
 ******************************************************************************/


/* level 2 object, keeps track of a group of related folders */
/******************************************************************************
 ******************************************************************************
 * BCS_FolderDictionary definition ********************************************
 ******************************************************************************
 ******************************************************************************/
function BCS_FolderDictionary(refItemAry){
	
	this._ref = {};	
	
	/* if any  BCS_FolderRefItem objects were passed as an argument to the constructor */
	if(typeof refItemAry != 'undefined'){
		if(refItemAry instanceof BCS_FolderRefItem){
			this._ref[refItemAry.folder] = refItemAry;
		}else if(refItemAry instanceof Array){
			for(var i = 0; i < refItemAry.length; ++i)
				if(refItemAry[i] instanceof BCS_FolderRefItem)
					if(!this.addFolder(refItemAry[i])) throw new Error('Invalid argument passed as argument position ' + i + ' not a valid BCS_FolderRefItem');	
		}else throw new Error('BCS_FolderDictionary constructor reports invalid argument passed as refItemAry');
	}
}

/************************************************************************
/************************************************************************
/* @PROTO:  bool BCS_FolderDictionary.addFolder(BCS_FolderRefItem refItem)
/* @DESC:   Adds a folder to the dictionary object
/* @RETURN: Boolean success
/* @PARAM:  BCS_FolderRefItem refItem -> adds a BCS_FolderRefItem to the list of folders
/************************************************************************
/************************************************************************/
BCS_FolderDictionary.prototype.addFolder = function(refItem){
	if(typeof refItem == 'undefined') return false;
	if(refItem instanceof BCS_FolderRefItem){ 
		if(typeof this._ref[refItem.folder] != 'undefined')	return false;
		this._ref[refItem.folder] = refItem;
		return true;
	}else return false;
}

/************************************************************************
/************************************************************************
/* @PROTO:  BCS_FolderRefItem BCS_FolderDictionary.getFolder(String folder)
/* @DESC:   Retrieves a folder object from the reg	
/* @RETURN: Returns the folder object or false if its not found
/* @PARAM:  String folder -> the name of the folder object you want to get
/************************************************************************
/************************************************************************/
BCS_FolderDictionary.prototype.getFolder = function(folder){ return (typeof this._ref[folder] != 'undefined') ? this._ref[folder] : false;}

BCS_FolderDictionary.prototype.hasSubFolderDictionary = function(folder){
	return typeof this._ref[folder] != 'undefined' && this._ref[folder].subFolderDictionary instanceof BCS_FolderDictionary;
}
/******************************************************************************
 ******************************************************************************
 * END BCS_FolderDictionary definition ****************************************
 ******************************************************************************
 ******************************************************************************/



/* Top Level Object used to create the breadcrumbs, and load them into the page */
/******************************************************************************
 ******************************************************************************
 * BCS_BreadCrumbManager definition *******************************************
 ******************************************************************************
 ******************************************************************************/
function BCS_BreadCrumbManager(targetElemId, folderDictionary, loadNav){	
	this.tid;
	this.fdo;
	this.trailLinkClass = 'bcs_trailLink';
	this.activeLinkClass = 'bcs_activeLink';
	this.separatorClass = 'bcs_separator';
	this.separator = '>';	
	this.defaultPage = 'index.html';
	this.domain = "http://www.ito-y.com";
	this.domainTitle = 'Home';
	this.getPageTitleFunction = false;
	this.clearNode = false;
	
	if(typeof targetElemId!= 'undefined')
		this.setTargetElement(targetElemId);

	if(typeof folderDictionary != 'undefined')
		if(!this.setFolderDictionary(folderDictionary)) 
			throw new Error('BCS_BreadCrumbManager constructor reports invalid second argument. Must be a valid instance of BCS_FolderDictionary');	
			
	if(loadNav == true) this.writeToPage();
}

BCS_BreadCrumbManager.prototype.setTargetElement = function(targetId){
	this.tid = String(targetId);
}

BCS_BreadCrumbManager.prototype.setFolderDictionary = function(fDict){
	if(fDict instanceof BCS_FolderDictionary){
		this.fdo = fDict;
		return true;
	}else return false;
}

BCS_BreadCrumbManager.prototype.write = function(){
	var nodeRef = document.getElementById(this.tid);
	if(!nodeRef) return false;
	if(this.clearNode) while(nodeRef.hasChildNodes()) nodeRef.removeChild(nodeRef.firstChild);
	var elm = this.makeTrailLink(this.domain, this.domainTitle);
	if(elm) nodeRef.appendChild(elm);
	var refs = this.findAllRefItems();
	if(!refs || !refs.length){ 
		return true;
	}else{
		var sep = this.makeSeparator();
		if(sep) nodeRef.appendChild(sep);
	}
	while(refs.length){
		var r = refs.shift();
		if(r instanceof BCS_FolderRefItem){
			elm =  this.makeTrailLink(r.link, r.txt);
		}else if(this.getPageTitleFunction && typeof this.getPageTitleFunction == 'function'){
			elm = this.makeActiveLink(location.href, this.getPageTitleFunction());
		}else{			
			if(document.getElementsByTagName('title') && document.getElementsByTagName('title')[0]){
				title = (document.getElementsByTagName('title')[0].innerHTML) ? document.getElementsByTagName('title')[0].innerHTML : 'Current';
			}else title = 'Current';	
			elm = this.makeActiveLink(location.href, title);
		}
		if(elm) nodeRef.appendChild(elm);
		if(refs.length)nodeRef.appendChild(sep.cloneNode(true));
	}
}

BCS_BreadCrumbManager.prototype.findAllRefItems = function(){
	if(typeof this.fdo == 'undefined')return false;
	if(typeof this.pathAry == 'undefined') var pathAry = this.parseURL();
	var refAry = new Array();
	
	if(pathAry && this.fdo instanceof BCS_FolderDictionary){
		var fd = this.fdo;
		while(pathAry.length && fd){
			var tf = pathAry.shift();
			var fi = fd.getFolder(tf);
			if(fi){
				refAry.push(fi);
				fd = (fd.hasSubFolderDictionary(tf)) ? fi.subFolderDictionary : false;
			}
			if(!fd) refAry.push(pathAry.shift());
		}
		return refAry;
	}else return false;
	
}

BCS_BreadCrumbManager.prototype.parseURL = function(){	
	var paths = location.href.split('/').slice(3);
	if(!paths.length) return false;
	if(paths[paths.length - 1] == '') paths[paths.length - 1] = this.defaultPage;
	return  paths;
}

BCS_BreadCrumbManager.prototype.makeTrailLink = function(linkAddr, txt){
	return this.makeLink(linkAddr, txt, this.trailLinkClass);
}

BCS_BreadCrumbManager.prototype.makeActiveLink = function(linkAddr, txt){
	return this.makeLink(linkAddr, txt, this.activeLinkClass);
}

BCS_BreadCrumbManager.prototype.makeLink = function(linkAddr, txt, elementClass){
	if(typeof linkAddr != 'string' || typeof txt != 'string') return false;
	var e = document.createElement('a');
	e.className = elementClass;
	e.href = linkAddr;
	e.appendChild(document.createTextNode(txt));
	return e;
}

BCS_BreadCrumbManager.prototype.makeSeparator = function(){
	var s = document.createElement('span');
	s.className = this.separatorClass;
	s.appendChild(document.createTextNode(this.separator));
	return s;
}


/******************************************************************************
 ******************************************************************************
 * END BCS_BreadCrumbManager definition ***************************************
 ******************************************************************************
 ******************************************************************************/