function NavSys(aData, parentPath) {
	var SELF = this;
	var TYPE = {
		MAIN_NAV: 'mainNav',
		NO_LINK: 'noLink'
	}
	var HTML = {
		NAV_ITEM: "<a href='{url}' rel='{filename}'>{label}</a>",
		//SUBNAV_PARENT_TITLE: "<div class='subnav-title'>{label}</div>",
		SUBNAV_PARENT_TITLE: "",
		SUBNAV_ITEM: "<a href='{url}' class='subnav-item {selectedClass}'>{label}</a>",
		BREADCRUMB_ITEM: "<span><a href='{url}' class='breadcrumb-item'>{label}</a></span>",
		BREADCRUMB_HOME: "<span><a href='{url}' class='breadcrumb-item'>{label}</a></span>",
		BREADCRUMB_NOLINK: "<span><a>{label}</a></span>"
	}
	var SITE_ROOT = aData[0].path;
	var PAGE_PATH = parentPath || location.pathname.replace(new RegExp('^' + SITE_ROOT), '') + location.search;
	if (!_getRoute(aData[0])) PAGE_PATH = location.pathname.replace(new RegExp('^' + SITE_ROOT), '');
	var _hideTimer, _showTimer;
	var EventHandlers = {
		mainNav: {
			onMouseOut: function() {
				clearTimeout(_showTimer);
				_hideTimer = setTimeout(function() { SELF.drawSubNav(); }, 1000);
			},
			onMouseOver: function(e) {
				var oTarget = Event.getTarget(e);
				if (oTarget.tagName !== 'A') return;
				var sFilename = oTarget.getAttribute('rel');
				clearTimeout(_hideTimer);
				clearTimeout(_showTimer);
				_showTimer = setTimeout(function() { SELF.drawSubNav(sFilename); }, 200);
			}
		},
		subNav: {
			onMouseOut: function() {
				_hideTimer = setTimeout(function() { SELF.drawSubNav(); }, 1000);
			},
			onMouseOver: function() {
				clearTimeout(_hideTimer);
			}
		}
	}
	var Registers = {
		Containers: { mainNav: null, subNav: null, breadcrumb: null }
	}
	
	
	function _getNode(root, optionalPath) {
		var findPath = optionalPath || PAGE_PATH;
		if (findPath == root.path) return [root];
		if (!root.children) return;
		for (var i=0, len=root.children.length; i<len; i++) {
			var foundNode = _getNode(root.children[i], optionalPath);
			if (foundNode) return foundNode;
		}
	}
	
	function _getRoute(root, optionalPath) {
		var findPath = optionalPath || PAGE_PATH;
		if (findPath == root.path) return [root];
		if (!root.children) return;
		for (var i=0, len=root.children.length; i<len; i++) {
			var foundNode = _getNode(root.children[i], optionalPath);
			if (foundNode) return [root.children[i]].merge(foundNode);
		}
	}
	
	function _showSubNav() {
		var oSubNav = $(Registers.Containers.subNav);
		var styleSet = {'marginTop': '0px'}
		var options = {duration: 200, accelerate: -1}
		setTimeout(function() {oSubNav.transformStyleSet(styleSet, options);}, 100);
	}
	
	function _hideSubNav() {
		var oSubNav = $(Registers.Containers.subNav);
		var styleSet = {'marginTop': '-'+oSubNav.getHeight()+'px'}
		var options = {duration: 200, accelerate: -1}
		setTimeout(function() {oSubNav.transformStyleSet(styleSet, options);}, 100);
	}
	
	this.drawMainNav = function(container) {
		var aRoute = _getRoute(aData[0]);
		var currentNode = aRoute[aRoute.length -1];
		var parentNode = aRoute[aRoute.length -2];
		var fromNode = parentNode || currentNode; // mainNav node
		var sHTML = '';
		
		var aMainNavItems = [];
		aData[0].children.each(function() {
			if (this.type == TYPE.MAIN_NAV) aMainNavItems.push(this);
		});

		aMainNavItems.each(function(ar, index) {
			if (this.type !== TYPE.MAIN_NAV) return;
			sHTML += HTML.NAV_ITEM.supplant({
				url: aData[0].path + this.path,
				filename: this.path,
				label: this.label
			});
		});
		$(container).setHTML(sHTML);
	}
	
	this.drawSubNav = function(optionalPath) {
		var findPath = optionalPath || PAGE_PATH;
		if (findPath == aData[0].path) {
			_hideSubNav();
			return;
		}
		var aRoute = _getRoute(aData[0], findPath);
		var currentNode = aRoute[aRoute.length -1];
		var parentNode = aRoute[aRoute.length -2];	
		var fromNode = parentNode || currentNode; // mainNav node
		var oSubNav = $(Registers.Containers.subNav);
		
		if (fromNode.children) {
			var sHTML = '';
			fromNode.children.slice(0).reverse().each(function() {
				var subnavClassName = (sHTML == '')? 'first ' : '';
				sHTML += HTML.SUBNAV_ITEM.supplant({
					url: aData[0].path + this.path,
					selectedClass: (this.path == PAGE_PATH)? subnavClassName + 'selected' : subnavClassName,
					label: this.label
				});
			});
			var sParentTitleHTML = (!!optionalPath)? HTML.SUBNAV_PARENT_TITLE.supplant({ label: fromNode.label }) : '';
			oSubNav.setHTML(sParentTitleHTML + sHTML);
			_showSubNav();
		} else {
			_hideSubNav();
		}
	}
	
	this.drawBreadCrumb = function(optionalPath) {
		if (!Registers.Containers.breadcrumb) return;
		var aRoute = _getRoute(aData[0]);
		var sHTML = HTML.BREADCRUMB_HOME.supplant({ url: aData[0].path, label: aData[0].label });
		aRoute.each(function(ar, index) {
			sHTML += (this.type !== TYPE.NO_LINK) 
				? HTML.BREADCRUMB_ITEM.supplant({ url: aData[0].path + this.path, label: this.label })
				: HTML.BREADCRUMB_NOLINK.supplant({ label: this.label });
		});
		$(Registers.Containers.breadcrumb).setHTML(sHTML);
	}
	
	this.init = function(containers) {
		Registers.Containers = containers;
		
		var aRoute = _getRoute(aData[0]);
		
		var currentNode = aRoute[aRoute.length -1];
		var parentNode = aRoute[aRoute.length -2];
		
		var fromNode = parentNode || currentNode; // mainNav node
		
		this.drawMainNav(containers.mainNav); // draw mainNav
		// setting selected class in main nav/foot nav
		if (PAGE_PATH != aData[0].path && _getNode(aData[0])[0].type != TYPE.NO_LINK ) {
			try {
				var fromNodeMainNav = $('header-nav').getElementsByAttribute("rel", fromNode.path)[0];
				fromNodeMainNav.className = fromNodeMainNav.className + " selected";
			} catch(e) {
				var fromNodeMainNav = $('functions-footnav').getElementsByAttribute("rel", fromNode.path)[0];
				fromNodeMainNav.className = fromNodeMainNav.className + " selected";
			}
		}
		this.drawSubNav(); // draw subNav
		this.drawBreadCrumb(); // draw breadCrumb
		
		$(containers.mainNav).addListener('mouseover', EventHandlers.mainNav.onMouseOver);
		$(containers.mainNav).addListener('mouseout', EventHandlers.mainNav.onMouseOut);
		$(containers.subNav).addListener('mouseover', EventHandlers.subNav.onMouseOver);
		$(containers.subNav).addListener('mouseout', EventHandlers.subNav.onMouseOut);
	}
}
