/**
*jQuery plugin - Ajax Container
*
*/
(function($){
	
	//tmp function
	var outpSetup=false;
	function setupOutp(){
		var elem=$(
			'<div id="outpElem" style="position:fixed; top:10px; right:10px; width:300px; height:400px; z-index:9999; color:#fff">'+
			'<div style="position:absolute; left:0px; top:0px; cursor:pointer; background-color:#ff0; width:15px; height:15px; z-index:2" '+
			'onclick="$(\'#outpContent\').html(\'\')"></div>'+
			'<div style="position:absolute; left:285px; top:0px; cursor:pointer; background-color:#f00; width:15px; height:15px; z-index:2" '+
			'onclick="$(this).parent().hide()"></div>'+
				'<div id="outpContent" style="position:absolute; left:0px; top:15px; width:300px; height:385px; overflow:auto; z-index:3"></div>'+
				'<div id="outpBg" style="position:absolute; left:0px; top:0px; width:100%; height:100%; z-index:0; background-color:#000;"></div>'+
			'</div>'
		);
		elem.find('#outpBg').css({opacity:0.8});
		$(document.body).append(elem);
		outpSetup=true;
	}
	function outp(){
		if(!outpSetup)
			setupOutp();
		var content=$('#outpContent');
		for(var i=0,l=arguments.length;i<l;i++)
			content.html(arguments[i]+'<br/>'+content.html());
		$('#outpElem').show();
	}
	
	
	
	
	
	
	
	
	/**
	*Public namespace object
	*@var object
	*/
	var ajaxNav={};
	var config={
		pagePath:null,
		mode:'passive',	// values	full - all links are treated as ajax links
						//			passive - only links in ajax mode are treated as ajax
		linkClass:'ajax-link',
		ignoreClass:'ajax-ignore',
		containerClass:'ajax-container',
		requestFlag:'ajax',
		silent:'non-main',// values - [ none - all ajax links are display in the address bar
						  // 			non-main - ajax links outside of the main content are not display in the address bar
						  //			all - no ajax links are display in the address bar ]
		mainContent:'ajax-main-content',// main content class
		trans:'replace',// value - [ replace, slide-up, slide-right, slide-down, slide-left, fade ]
		getExternal:'/external/?url=',
		loadingOverlay:'<span class="ajax-nav-loading-overlay"><span class="ajax-nav-loading-wheel"></span></span>',
		theme:'ajax-theme-light'
	}
	var setupComplete=false;
	var pageDir=null;
	var hashPath=null;
	var hashData=null;
	var hashDomain=null;
	var hashProtocol=null;
	var hashMethod=null;
	var setHashI=0;
	var hashListenerI=0;
	var requestGroups=new Array();
	var contentLoadListeners=new Array();
	
	
	
	/**
	*Sets up the ajaxNav plugin
	*@return boolean  Returns TRUE if the plugins is successfully setup
	*/
	function setup(_config){
		if(setupComplete) return false;
		setupComplete=true;
		
		if(_config)
			$.extend(true,config,_config);
		
		if(!checkPagePath()) return false;
		
		addLinkListener();
		
		addFormListener();
		
		initHash();
		
		$('[ajax-src]').ajaxContainer();
		
		return true;
	}
	
	/**
	*Called when new content is loaded into an element
	*/
	function onContentLoad(element){
		for(var i=0,l=contentLoadListeners.length;i<l;i++){
			contentLoadListeners[i](element);
		}
	}
	function onTransComplete(target,transComplete){
		
		var oTransData=target.data('ajax-otrans-data');
		if(oTransData && oTransData.afterremove)
			callCallback(oTransData.afterremove,target);
		
		if(transComplete)
			callCallback(transComplete,target);
	}
	
	function addContentLoadListener(listener){
		contentLoadListeners.push(listener);
	}
	function removeContentLoadListener(listener){
		for(var i=0,l=contentLoadListeners.length;i<l;i++){
			if(contentLoadListeners[i]===listener){
				contentLoadListeners.splice(i,1);
				i--;
				l--;
			}
		}
	}
	
	
	
	/**
	*Sets the initial hash path and hash directory. If the hash path is not an empty string the hash path is loaded 
	*/
	function initHash(){
		hashPath=window.location.hash;
		
		if(hashPath!=='' && hashPath!=='#')
			load(hashPath);
		
		hashListenerI=setInterval(checkHash,200);
	}
	/**
	*Checks to see if the URL hash in the address bar has changed, if it has the hash is loaded as a page.
	*/
	function checkHash(){
		if(window.location.hash!=hashPath){
			load(window.location.hash,hashData,hashMethod,true,null,hashDomain,hashProtocol);
			hashData=null;
			hashMethod=null;
			hashDomain=null;
			hashProtocol=null;
		}
	}
	
	
	
	
	
	
	
	
	
	
	
	
	function addLinkListener(){
		$(document.body).click(onLinkClick);
	}
	
	function addFormListener(){
		$(document.body).submit(onFormSubmit);
	}
	
	function onLinkClick(e){
		var target=null;
		if(e.target.nodeName.toLowerCase()!=='img' && e.target.href){
			target=$(e.target);
		}else{
			var parent=e.target.parentNode;
			while(parent &&  (!parent.href || parent.nodeName.toLowerCase()==='img'))
				parent=parent.parentNode;
			if(parent && parent.href)
				target=$(parent);
		}
		
		if(!target)
			return;
		
		
		var targetName=target.attr('target');
		targetName=targetName?targetName:'';
		if(!target || targetName.charAt(0)==='_' ||target.attr('href').toLowerCase().indexOf('javascript:')===0)
			return;
		
		return redirectAjaxTarget(target);
	}
	function onFormSubmit(e){
		return redirectAjaxTarget($(e.target));
	}
	
	function redirectAjaxTarget(target){
		var container=$(target.parents('.'+config.containerClass)[0]);
		var linkTarget=target.attr('target');
		var isForm=target[0].nodeName.toLowerCase()==='form';
		if(	( !isForm && !target.attr('href') ) ||
			( config.mode=='passive' &&  !target.hasClass(config.linkClass) && !container.length &&  (!linkTarget || linkTarget.search(/\w/)===0) ) ||
			target.hasClass(config.ignoreClass)
		){
			return;
		}
		if(linkTarget && linkTarget.charAt(0)==='#')
			linkTarget=linkTarget.substr(1);

		var pathname=isForm?target.attr('action'):target.attr('href');
		var protocol=null;
		var domain=null;
		if(pathname.search(/^\w+:\/\//)===0){// check for external links
			var i=pathname.indexOf(':');
			var dei=pathname.indexOf('/',i+3);
			protocol=pathname.substr(0,i).toLowerCase();
			domain=pathname.substring(i+3,dei===-1?pathname.length:dei).toLowerCase();
			pathname=dei===-1?'/':pathname.substr(dei);
			
			if(domain!==window.location.host.toLowerCase() && !target.hasClass('ajax-link'))
				return;
			
		}
		
		container.ajaxContainer();
		
		if(pathname.charAt(0)!=='/'){
			if(container.length){
				pathname=container.data('ajaxContainer').dir+pathname;
			}else{
				pathname=pageDir+pathname;
			}
		}
		
		if(pathname.indexOf(pageDir)===0)
			pathname=pathname.substr(pageDir.length);
		
		if(linkTarget!==config.mainContent)
		if(linkTarget){
			pathname+='@'+(linkTarget.charAt(0)==='#'?linkTarget.substr(1):linkTarget);
		}else if(container.length && container.attr('id')!==config.mainContent){
			if(!container.attr('id'))
				container.attr('id',createTargetId())
			pathname+='@'+(linkTarget=container.attr('id'));
		}else{
			linkTarget=config.mainContent;
		}
		
		var data=null;
		var method=null;
		if(isForm){
			method=String(target.attr('method') || 'GET').toUpperCase();
			data=target.serializeArray();
		}
		
		if(
			linkTarget!==config.mainContent && (
				( config.silent==='none' && (container.hasClass('ajax-silent') || target.hasClass('ajax-silent')) ) ||
				( config.silent==='non-main' && (!container.hasClass(config.mainContent) || target.hasClass('ajax-silent')) ) ||
				( config.silent==='all' )
			)
		){
			setTimeout(function(){
				load(pathname,data,method,false,null,domain,protocol);
			},100);
		}else{
			clearInterval(setHashI);
			setHashI=setTimeout(function(){
				hashData=data;
				hashMethod=method;
				hasDomain=domain;
				hasProtocol=protocol;
				if((pathname===hashPath || '#'+pathname===hashPath) && (isForm || target.hasClass('ajax-dynamic')))
					hashPath=null;
				window.location.hash=pathname;
			},100);
		}
		
		return false;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	//do not call directly. Change the hash to load a new hash or click a link or submit a form.
	function load(newHashPath,data,method,updateHash,targetObj,domain,protocol){
		if(updateHash!==false)
			hashPath=newHashPath;
		
		if(newHashPath && newHashPath.charAt(0)==='#')
			newHashPath=newHashPath.substr(1);
		var target,i;
		i=newHashPath.indexOf('@');
		if(i===-1){
			target='';
		}else{
			target=newHashPath.substr(i+1);
			newHashPath=newHashPath.substr(0,i);
		}
		
		var loadPath=(newHashPath && newHashPath.charAt(0)==='/')?newHashPath:pageDir+newHashPath;
		if(loadPath.charAt(0)==='#')
			loadPath=loadPath.substr(1);
		if(method==='POST'){
			if(!data)
				data=new Array();
			data.push({name:config.requestFlag,value:'1'});
		}else{
			var qi=loadPath.indexOf('?');
			if(qi>-1){
				var query=loadPath.substr(qi+1)
				var loadPath=cleanPath(loadPath.substr(0,qi));
				if(query.indexOf(config.requestFlag+'=1',qi)===-1)
					query+=(query?'&':'')+config.requestFlag+'=1';
				loadPath+='?'+query;
			}else{
				loadPath=cleanPath(loadPath)+'?'+config.requestFlag+'=1';
			}
		}
		if(targetObj){
			target=targetObj;
		}else{
			if(!target)
				target=config.mainContent;
			if(target.charAt(0).search(/^\w/)===0)
				target='#'+target;
			target=$(target);
			if(target.length===0)
				target=$(document.body)
		}
		target.ajaxContainer();
		removeFromRequestGroups(target);
		target.ajaxContainer('show-loading');
		var requestGroup=null;
		var request=$.ajax({
			url:	(domain && domain!==window.location.host.toLowerCase()?config.getExternal:'')+
					(protocol?protocol+'://':(domain?window.location.protocol+'//':''))+
					(domain?domain:'')+
					loadPath,
			data:data?data:null,
			type:method?method:'GET',
			cache:false,
			success:function(data){
				target.ajaxContainer('hide-loading');
				requestGroup.target.ajaxContainer({path:loadPath,dir:dirName(loadPath)});
				insertTargetData(requestGroup.target,processTargetData(target,data));
				removeRequestGroup(requestGroup);
				requestGroup.target.find('[ajax-src]').ajaxContainer();
			},
			error:function(){
				target.ajaxContainer('hide-loading');
				//todo error message
				removeRequestGroup(requestGroup);
			}
		});
		requestGroup=createRequestGroup(request,target);
	}
	
	/*
	*Events
	* ajax-beforeinsert		called before page is inserted
	* ajax-oninsert			called after page has been inserted and before transition has started
	* ajax-ontrans			called after pages has transitioned
	* ajax-beforeremove		called before page is transitioned out
	* ajax-afterremove		called after pages has been removed from the document
	*/
	function processTargetData(target,data){
		var rData=new Object();
		if(data.search(/^\s*<div\s*class\s*=\s*"\s*ajax-targets\s*"/i)===0){
			var l=0;
			$($.trim(data)).children().each(function(){
				var $this=$(this);
				var id=$this.attr('ajax-target-id');
				if(!id)
					id='__AJAX_MAIN_CONTENT__';
				else if(id.charAt(0).search(/\w/)===0)
					id='#'+id;
				rData[id]={
					data:$this.contents(),
					trans:$this.attr('ajax-trans'),
					beforeinsert:$this.attr('ajax-beforeinsert'),
					oninsert:$this.attr('ajax-oninsert'),
					ontrans:$this.attr('ajax-ontrans'),
					beforeremove:$this.attr('ajax-beforeremove'),
					afterremove:$this.attr('ajax-afterremove')
				}
				l++;
			});
			rData.__targetLenth__=l;
		}else{
			rData={
				"__AJAX_MAIN_CONTENT__":{
					data:$('<div>'+data+'</div>').contents()
				},
				__targetLenth__:1
			}
		}
		
		return rData;
	}
	
	function insertTargetData(target,data){
		var mainTarget=target;
		var i=0;
		var l=data.__targetLenth__;
		
		for(var selector in data){
			if(selector==='__targetLenth__')
				continue;
			i++;
			if(selector!=="__AJAX_MAIN_CONTENT__"){
				target=$(selector);
			}else{
				target=mainTarget;
			}
			target.each(function(){
				var target=$(this);
				target.stop(true,true);
				var trans=target.attr('ajax-trans') || data[selector].trans || config.trans;
				if(!transEffects[trans])
					trans='replace';
				
				var beforeInsert=data[selector].beforeInsert;
				if(beforeInsert)
					callCallback(beforeInsert,target);
					
				var oTransData=target.data('ajax-trans-data');
				if(oTransData && oTransData.beforeremove)
					callCallback(oTransData.beforeremove,target);
				

				target.data('ajax-otrans-data',oTransData)
				target.data('ajax-trans-data',data[selector]);
				
				transEffects[trans](target,i===l?data[selector].data:data[selector].data.clone(),data[selector].ontrans);
				
				var onInsert=data[selector].oninsert;
				if(onInsert)
					callCallback(onInsert,target);
				
			});
		}
	}
	function callCallback(callback,target){
		var applyToTarget=false;
		if(typeof(callback)==='string'){
			applyToTarget=true;
			try{
				eval('callback=function(){'+callback+'}');
			}catch(e){
				//todo - log to concel
				callback=false;
			}
		}
		if(callback){
			if(applyToTarget)
				callback.apply(target[0],[target]);
			else
				callback(target);
		}
	}
	/**
	*Transition effects
	*/
	var transEffects={
		replace:function(target,data,transComplete){
			target.html(data);
			setTimeout(function(){
				onContentLoad(target);
				onTransComplete(target,transComplete);},50);
				
				
		},
		fade:function(target,data,transComplete){
			
			target.each(function(){
				var p=transEffects.prepTarget(target,data);
				var wDif=p.nw-p.ow;
				var hDif=p.nh-p.oh;
				p.oldInner.css({opacity:1,position:'absolute'});
				p.newInner.css({opacity:0});
				target
					.append(p.oldInner)
					.append(p.newInner)
					.css({ajaxNavTrans:0})
					.animate(
						{ajaxNavTrans:100},
						{
							duration:500,
							queue:false,
							step:function(now){
								target.css({height:p.oh+now*hDif/100,width:p.ow+now*wDif/100});
								p.oldInner.css({opacity:1-now/100});
								p.newInner.css({opacity:now/100});
							},
							complete:function(){
								transEffects.unprepTarget(target,p.oldInner,p.newInner);
								onTransComplete(target,transComplete);
							}
						}
					);
			});
		},
		"slide-left":function(target,data,transComplete){
			var p=transEffects.prepTarget(target,data);
			var wDif=p.nw-p.ow;
			var hDif=p.nh-p.oh;
			var w=p.ofw>p.nfw?p.ofw:p.nfw;
			p.newInner.css({position:'absolute',top:p.padT,left:-w});
			p.oldInner.css({position:'absolute',top:p.padT,left:p.padL});
			target
				.css({ajaxNavTrans:0})
				.addClass('ajax-nav-hidden-overflow ajax-nav-relative')
				.append(p.oldInner)
				.append(p.newInner)
				.animate(
					{ajaxNavTrans:100},
					{
						duration:500,
						queue:false,
						step:function(now){
							target.css({height:p.oh+now*hDif/100,width:p.ow+now*wDif/100});
							p.newInner.css({left:(p.padL*now/100)+w-w*now/100});
							p.oldInner.css({left:(p.padL-p.padL*now/100)-w*now/100});
						},
						complete:function(){
							transEffects.unprepTarget(target,p.oldInner,p.newInner);
							onTransComplete(target,transComplete);
						}
					}
				);
			
		},
		"slide-right":function(target,data,transComplete){
			var ot=target;
			var p=transEffects.prepTarget(target,data);
			var str='';
			for(var e in data)
				str+=e+' = '+data[e]+'\n\r';
			var wDif=p.nw-p.ow;
			var hDif=p.nh-p.oh;
			var w=p.ofw>p.nfw?p.ofw:p.nfw;
			p.newInner.css({position:'absolute',top:p.padT,left:w});
			p.oldInner.css({position:'absolute',top:p.padT,left:p.padL});
			target
				.css({ajaxNavTrans:0})
				.addClass('ajax-nav-hidden-overflow ajax-nav-relative')
				.append(p.oldInner)
				.append(p.newInner)
				.animate(
					{ajaxNavTrans:100},
					{
						duration:500,
						queue:false,
						step:function(now){
							target.css({height:p.oh+now*hDif/100,width:p.ow+now*wDif/100});
							p.newInner.css({left:(p.padL*now/100)-w+w*now/100});
							p.oldInner.css({left:(p.padL-p.padL*now/100)+w*now/100});
						},
						complete:function(){
							transEffects.unprepTarget(target,p.oldInner,p.newInner);
							onTransComplete(target,transComplete);
						}
					}
				);
		},
		"slide-up":function(target,data,transComplete){
			var p=transEffects.prepTarget(target,data);
			var wDif=p.nw-p.ow;
			var hDif=p.nh-p.oh;
			var h=p.ofh>p.nfh?p.ofh:p.nfh;
			p.newInner.css({position:'absolute',top:h,left:p.padL});
			p.oldInner.css({position:'absolute',top:p.padT,left:p.padL});
			target
				.css({ajaxNavTrans:0})
				.addClass('ajax-nav-hidden-overflow ajax-nav-relative')
				.append(p.oldInner)
				.append(p.newInner)
				.animate(
					{ajaxNavTrans:100},
					{
						duration:500,
						queue:false,
						step:function(now){
							target.css({height:p.oh+now*hDif/100,width:p.ow+now*wDif/100});
							p.newInner.css({top:(p.padT*now/100)+h-h*now/100});
							p.oldInner.css({top:(p.padT-p.padT*now/100)-h*now/100});
						},
						complete:function(){
							transEffects.unprepTarget(target,p.oldInner,p.newInner);
							onTransComplete(target,transComplete);
						}
					}
				);
		},
		"slide-down":function(target,data,transComplete){
			var p=transEffects.prepTarget(target,data);
			var wDif=p.nw-p.ow;
			var hDif=p.nh-p.oh;
			var h=p.ofh>p.nfh?p.ofh:p.nfh;
			p.newInner.css({position:'absolute',top:-h,left:p.padL});
			p.oldInner.css({position:'absolute',top:p.padT,left:p.padL});
			target
				.css({ajaxNavTrans:0})
				.addClass('ajax-nav-hidden-overflow ajax-nav-relative')
				.append(p.oldInner)
				.append(p.newInner)
				.animate(
					{ajaxNavTrans:100},
					{
						duration:500,
						queue:false,
						step:function(now){
							target.css({height:p.oh+now*hDif/100,width:p.ow+now*wDif/100});
							p.newInner.css({top:(p.padT*now/100)-h+h*now/100});
							p.oldInner.css({top:(p.padT-p.padT*now/100)+h*now/100});
						},
						complete:function(){
							transEffects.unprepTarget(target,p.oldInner,p.newInner);
							onTransComplete(target,transComplete);
						}
					}
				);
		},
		
		/**
		*This is not a transition effect plugin. This function preps the target
		*@param  Elem	target
		*@param  string	data
		*@return object			{
		*							oldInner:[ old innerHTML ], newInner:[ new innerHTML ],
		*							ow:[ old width ], oh:[ old height], nw:[ new width ], nh:[ new height ],
		*							ofw: [ old offset width ], ofh: [ old offset height ], nfw: [ new offset width ], nfh: [ new offset height ],
		*							padR: [ padding right ], padL: [ padding left ], padT: [ padding top ], padB: [ padding bottom ] 
		*						}
		*/
		prepTarget:function(target,data){
			var ow=target.width();
			var oh=target.height();
			target.data('ajaxNavPreData',{w:target[0].style.width,h:target[0].style.height});
			target.wrapInner('<span class="ajax-nav-innerWrap"></span>');
			var oldInner=$(target.children()[0]);
			oldInner.remove();
			target.append(data);
			onContentLoad(target);
			var nw=target.width();
			var nh=target.height();
			target.wrapInner('<span class="ajax-nav-innerWrap"></span>');
			var newInner=$(target.children()[0]);
			newInner.remove();
			oldInner.css({width:ow,height:oh});
			newInner.css({width:nw,height:nh});
			target.css({width:ow,height:oh});
			var padR=Number(target.css('padding-right').replace('px',''));
			var padL=Number(target.css('padding-left').replace('px',''));
			var padT=Number(target.css('padding-top').replace('px',''));
			var padB=Number(target.css('padding-bottom').replace('px',''));
			return {
				oldInner:oldInner,newInner:newInner,
				ow:ow,oh:oh,nw:nw,nh:nh,
				ofw:ow+padL+padR,ofh:oh+padT+padB,nfw:nw+padL+padR,nfh:nh+padT+padB,
				padR:padR,padL:padL,padT:padT,padB:padB
				
			};
		},
		unprepTarget:function(target,oldInner,newInner){
			if(!target.data('ajaxNavPreData'))//todo tmp - remove
				debugger
			if(target)
				target.css({width:target.data('ajaxNavPreData').w,height:target.data('ajaxNavPreData').h});
			if(oldInner)
				oldInner.remove();
			if(newInner){
				newInner.before(newInner.contents());
				newInner.remove();
			}
		}
	}
	
	
	
	
	
	function removeFromRequestGroups(target){
		target.each(function(){
			for(var i=0,l=requestGroups.length;i<l;i++){
				var group=requestGroups[i];
				if(group.target.is(target)){
					group.target=group.target.not(target);
					if(group.target.length===0){
						requestGroups.splice(i,1);
						i--;
						l--;
						group.request.abort();
					}
				}
			}
		});
	}
	function createRequestGroup(request,target){
		var group={request:request,target:target};
		requestGroups.push(group);
		return group;
	}
	function removeRequestGroup(group){
		for(var i=0,l=requestGroups.length;i<l;i++){
			if(requestGroups[i]===group){
				requestGroups.splice(i,1);
				return;
			}
		}
	}
	
	
	
	
	
	
	
	
	function dirName(pathname){
		var dir=pathname.substr(0,pathname.lastIndexOf('/')+1);
		if(!dir)
			return '/';
		if(dir.charAt(dir.length-1)!=='/')
			return dir+'/';
		return dir;
	}
	
	function cleanPath(path){
		var a=(path && path.charAt(0)=='/')?'/':'';
		var b=(path && path.charAt(path.length-1)=='/')?'/':'';
		var bfIsLast=false;
		path=path.split('/');
		for(var i=0,l=path.length;i<l;i++){
			var p=path[i];
			bfIsLast=false;
			if(!p || p==='.'){
				path.splice(i,1);
				i--;
				l--;
			}else if(p==='..'){
				path.splice(i-1,2);
				i-=2;
				l-=2;
				bfIsLast=true;
			}
				
		}
		if(bfIsLast)
			b='/';
		path=a+path.join('/')+b;
		if(path==='//')
			return '/';
		return path;
		
	}
	
	/**
	*Checks if the pathname of the page matches config.basePage.
	*If the page pathname does not match config.basePage the page is redirected to config.basePage.
	*If config.basePage is NULL no check is made.
	*@return boolean 	Returns TRUE if the current page matches config.basePage
	*/
	function checkPagePath(){
		
		if(config.pagePath===null || window.location.pathname==config.pagePath){
			config.pagePath=window.location.pathname;
			pageDir=dirName(config.pagePath);
			return true;
		}
		
		var hash;
		var dir=dirName(config.pagePath);
		
		if(window.location.pathname.indexOf(dir)===0)
			hash=window.location.pathname.substr(dir.length)
		else
			hash=window.location.pathname;
		
		window.open(
			window.location.protocol+'//'+
			window.location.host+
			((window.location.port && window.location.port!=80)?':'+window.location.port:'')+
			config.pagePath+
			window.location.search+
			'#'+hash,'_self');
		
		return false;
	}
	
	/**
	*Returns a unique ID
	*@param  string		prefix		ID Prefix
	*@return string
	*/
	function createTargetId(prefix){
		if(!prefix)
			prefix='id'
		var i=1;
		while(document.getElementById(prefix+i))
			i++;
		return prefix+i;
	}
	
	
	
	
	
	
	$.fn.ajaxContainer=function(options){
		var returnValue;
		this.each(function(){
			var $this=$(this);
			var data;
			if(!$this.data(config.containerClass)){
				$this.addClass(config.containerClass);
				data=new Object();
				data.showLoading=false;
				data.loadingOverlay=null;
				data.showLoadingI=0;
				var parent=$($this.parents('.'+config.containerClass)[0]);
				if(parent.length){
					parent.ajaxContainer();
					var pdata=parent.data(config.containerClass);
					data.path=pdata.path;
					data.dir=pdata.dir;
				}else{
					data.path=pageDir;
					data.dir=pageDir;
				}
				$this.data(config.containerClass,data);
				if($this.attr('ajax-src')){
					load($this.attr('ajax-src'),null,null,false,$this);
					$this.removeAttr('ajax-src');
				}
			}
			if(typeof(options)==='object'){
				data=$this.data(config.containerClass);
				var i;
				if(options.path.substr(i=options.path.length-(config.requestFlag.length+2))===config.requestFlag+'=1')
					options.path=options.path.substr(0,i-1);
				data.path=options.path;
				data.dir=options.dir;
			}else if(options==='show-loading'){
				data=$this.data(config.containerClass);
				if(!data.showLoading){
					var theme=$this.ajaxContainer('theme');
					if(!data.loadingOverlay){
						data.loadingOverlay=$(config.loadingOverlay).addClass(theme);
						data.loadingOverlay.find('.ajax-nav-loading-wheel').addClass(theme);
					}
					$this.addClass('ajax-nav-relative-loading');
					clearInterval(data.showLoadingI);
					data.showLoadingI=setTimeout(function(){$this.append(data.loadingOverlay)},200);
					data.showLoading=true;
				}
			}else if(options==='hide-loading'){
				data=$this.data(config.containerClass);
				if(data.showLoading){
					clearInterval(data.showLoadingI);
					data.loadingOverlay.remove();
					$this.removeClass('ajax-nav-relative-loading');
					data.showLoading=false;
				}
			}else if(options==='theme'){
				var theme=config.theme;
				if($this.attr('ajax-theme'))
					theme=$this.attr('ajax-theme');
				if($this.hasClass('ajax-theme-light'))
					theme='ajax-theme-light';
				else if($this.hasClass('ajax-theme-dark'))
					theme='ajax-theme-dark'
				returnValue=theme;
			}
		});
		return returnValue===undefined?this:returnValue;
	}
	
	
	/// set public members
	ajaxNav.setup=setup;
	ajaxNav.dirName=dirName;
	ajaxNav.cleanPath=cleanPath;
	ajaxNav.transEffects=transEffects;
	ajaxNav.addContentLoadListener=addContentLoadListener;
	ajaxNav.removeContentLoadListener=removeContentLoadListener;
	ajaxNav.load=load;
	window.ajaxNav=ajaxNav;
	
})(jQuery);
