/* This Page Loader application is build using Prototype framework.
	note: comment console.debug if dojo.js is removed from main page
*/

var Loader = Class.create({
/*
	it is responsible to load the page for the given url by 
	adding a new page/div to the main div. 
	We are using url name as the page name for uniqueness
*/
//	pageMap : undefined, /* it holds all the pagename and pageobject maps*//
//	pageContainerNode : undefined, /* reference to the main Div, should be initialised*/
//	currentPageObj : undefined,
//	progressBarNode : undefined, /*progress bar div id*/

	initialize : function(pageContainerDiv,progressDiv,isBrowserHistoryEnabled){
		/* constructore method*/
		console.debug("PageLoader : Loader : initialize : pageContainerDiv:"+pageContainerDiv);
		if(!pageContainerDiv){
			pageContainerDiv = document.createElement("div");
			document.body.appendChild(pageContainerDiv);
		}		
		this.pageContainerNode = $(pageContainerDiv);	
		//To Do : need to add correct class/style

		this.pageMap = new Hash();
		this.currentPageObj=undefined;

		if(progressDiv){
			this.progressBarNode = $(progressDiv);
		}else{
			this.progressBarNode = $(document.createElement("div"));
			this.progressBarNode.innerHTML = "Loading.........";
		}		
		this.isBrowserHistoryEnabled = isBrowserHistoryEnabled == false ? false : true;
	},
	
	load : function(url){
		/* creates a page object(child div) and adds it to main page container.
			Then triggers an Ajax call to load the page and calls the call back handler.
		 */		
		var pageName = (url.split('/'))[2]; // getting url from "/url/t=1234"
		console.debug("PageLoader : Loader : load : pageName:"+pageName);

		if(this.pageContainerNode){

			if(this.currentPageObj) {this.currentPageObj.hide();}
			if(this.progressBarNode){ this.progressBarNode.show();}
			
			var page = this.pageMap.get(pageName);
			if(page){
			    console.debug("PageLoader :Loader : load : removing existing page :"+pageName);
				this.removePage(page);
			}
			
			page = new Page(url);
			this.currentPageObj = page;
			this.addPage(page);
			
			var thisObj = this; 			
			new Ajax.Updater({ success: pageName, failure: 'errorbox' }, url, 
				{	/*we should add one errorbox div to hold the error text if any.*/
					evalScripts: true, 
					onComplete: function(){ /* will be called at the end of all(script eval),but not sure in firefox*/
						console.debug("PageLoader : Loader : load : Ajax.Updater : onComplete handler :");					
						thisObj.onLoadCompleteHandler(pageName);
					}
				});
		}	
	},
	
	onLoadCompleteHandler : function(pageName){
		console.debug("PageLoader : Loader :  onLoadCompleteHandler :pageName : "+pageName+this);	
		//this.showPage(pageName);
		if(this.progressBarNode){
				this.progressBarNode.hide();
		}
		this.currentPageObj.isLoaded = true;
		this.currentPageObj.show();
		console.debug("PageLoader : Loader :  onLoadCompleteHandler :ends");
	},
	
	addPage : function(page){
		/* adds the passed page to the main div and fills the page hash*/
		console.debug("PageLoader : Loader :  addPage : start");	
		if(!page) return;
		console.debug("PageLoader : Loader :  addPage : "+page.name);	
		this.pageContainerNode.appendChild(page.contentPane);
		//To Do : need to add correct class/style
		this.pageMap.set(page.name,page);
		
		/*Back button implementation starts*/
		
		if(!this.isBrowserHistoryEnabled) return;

		var state = new historyState(page.name);
		
		if(this.pageMap.keys().length == 1){
			console.debug("Loader : addPage : setting this as application start page in BROWSER HISTORY: "+page.name);
			dojo.back.setInitialState(state);
		}else{
			dojo.back.addToHistory(state);
		}
		/*Back button implementation ends*/
		
	},
	removePage : function(page){
		/* removes the page div from the main div and also from the page hash*/
		console.debug("PageLoader : Loader :  removePage : start");
		if(!page) return;	
		console.debug("PageLoader : Loader :  removePage : pagename : "+page.name);
		this.pageContainerNode.removeChild(page.contentPane);
		this.pageMap.unset(page.name)
	},
	showPage : function(page,isAddToHistory){
		/* hides the current page and shows the requested page*/
		if(this.currentPageObj){
			this.currentPageObj.hide();
		}
		this.currentPageObj = page;
		this.refreshPageTitle();
		page.show();
		if(this.isBrowserHistoryEnabled == true && isAddToHistory == true){
				dojo.back.addToHistory(new historyState(page.name));
		}
	},
	
	showPageByName : function(pageName){
		/* hides the current page and shows the requested page*/
		console.debug("PageLoader : Loader :  showPage  pagename :"+pageName);	
		if(pageName && this.getPage(pageName)){
			this.showPage(this.getPage(pageName))
		}
	},

	getPage : function(pageName){
		if(pageName){
			return	this.pageMap.get(pageName);
		}
	},
	getCurrentPage : function(){
		return this.getPage(this.currentPageObj.name);
	},
	refreshPageTitle: function(){
		/* refreshes the window title by using the page object title*/
	
		var page = this.currentPageObj;
		console.debug("Loader : refreshPageTitle : title "+page.title);
		if(page.title == '') return;
		document.title = page.title;
		
		if(this.pageMap.keys().length == 1){
			console.debug("Loader : refreshPageTitle : we are skipping Omniture call since this is the first page and the main page already did this.");
		}else{
			this.omnitureTrack(page);
		}
	},
	omnitureTrack:function(page){
		/* triggers the omniture calls*/
		console.debug("Loader : omnitureTrack : spageName : "+ page.sPageName);
	    if(window.s && window.s_account)
	    {
	        s.un = s_account;
          	s.pageName = s.pageNamePrefix+ page.sPageName;
          	
          	if(page.events){
          	 s.events = page.events;
          	 page.events = undefined;
          	}          	
          	if(page.sEvar55)
          	{
          		s.eVar55 = page.sEvar55;
          	}
          	if(page.sProducts)
          	{
          		s.products = page.sProducts;
          	} 
	        s.t();
	    }
	}
	
});

var Page = Class.create({

	url : undefined,
	name : undefined,
	contentPane : undefined,
	isLoaded : false,

	initialize : function(url){
		console.debug("PageLoader : Page :  initialize url :"+url);	
		if(Object.isElement(url)){
			/* if a div or span element passed to create a page*/
			this.contentPane = $(url);
			this.name = this.contentPane.id;
			this.isLoaded = true;
		}else{
			/* if a url is passed to create a div*/
			this.url = url;
			this.name = (url.split('/'))[2]; // getting url from "/url/t=1234"
			this.contentPane = $(document.createElement('div'));
			this.contentPane.hide();
			this.contentPane.setAttribute("id",this.name);		
			this.isLoaded = false;
		}
		
		this.title = "";
		this.sPageName  = "";
	
	},
	show: function(){
		this.contentPane.show();
	},
	hide: function(){
		this.contentPane.hide();
	}
});

var CTabContainerViewComponent = Class.create(Loader,{
	/* It extends Loader Class. If default tab/div id is not initialized it shows the first tab.
		what ever tab we have to add to this, need give the class name "tab" for that div, and the remaining divs are ignored.
	*/
	firstPage:undefined,
	initialize : function($super, pageContainerDiv, tabButtonsDiv, progressDiv, defaultDivId){
		console.debug("PageLoader : CTabContainerViewComponent : initialize : pageContainerDiv  :"+pageContainerDiv);	
		$super(pageContainerDiv,progressDiv,false/*isBrowserHistoryEnabled*/);
		this.tabButtonsDiv = $(tabButtonsDiv);
		console.debug("PageLoader : CTabContainerViewComponent : initialize : calling build()");	
		this.firstPage=undefined;
		this.build();
		if(defaultDivId){
			this.showPageByName(defaultDivId);
		}else{
			this.showPage(this.firstPage);
		}
		this.childs = new Array();
		console.debug("PageLoader : CTabContainerViewComponent : initialize :ends");
	},
	build : function(){
		console.debug("PageLoader : CTabContainerViewComponent :  build :start");
		this.childs = this.pageContainerNode.select(".tab");;//this.pageContainerNode.childNodes; 
		var firstPage;
		for(i=0; i < this.childs.length; i++){
			var page = new Page(this.childs[i]);
			this.addPage(page);
			if(!firstPage){
				firstPage = page;
				this.currentPageObj = page;
			}
		}
		this.firstPage = firstPage;
		console.debug("PageLoader : CTabContainerViewComponent :  build :ends");
	},
	// overriding parent class(Loader) method to work with tab buttons
	showPageByName : function($super,pageName){

		var currentPageName = this.currentPageObj.name;
		
		if(currentPageName == pageName) return;
		
		var prevTab = $(currentPageName+"Tab");
		var currentTab = $(pageName+"Tab");

		if(currentTab == null) return;
		
		var unSelectClass = currentTab.readAttribute("class");
		var selectClass = prevTab.readAttribute("class");

		// selecting newly selected tab i.e. pageName tab
		currentTab.removeClassName(unSelectClass);
		currentTab.addClassName(selectClass);
		
		// unselecting current selected tab
		prevTab.removeClassName(selectClass);
		prevTab.addClassName(unSelectClass);
		
		if($(pageName)){
			console.debug("PageLoader : CTabContainerViewComponent  showPageByName:   showing existing/loaded tab page : "+pageName);
			$super(pageName);
		}else{
			var url = currentTab.readAttribute("url");
   		console.debug("PageLoader : CTabContainerViewComponent  showPageByName:   loading tab page with url  : "+url);
			this.load(url);
		}
	},
	hideTab : function(id){
		var tabId = id+"Tab";
		var tabNodes = this.tabButtonsDiv.childElements();
		for(var i = 0 ; i < tabNodes.length; i++){
			var tabNode = tabNodes[i];
	  		if(tabId == tabNode.id){
	  			tabNode.hide(); 
	  		}
		}
	}
});

/*this state object used for dojo back/forward History implementation
	when clicked on the back button previous state object will be used to call
	and when clicked on the forward button next state object will be called*/
	historyState = function(currPageName){
		this.pageName = currPageName;
		//this.changeUrl = currPageName;
		this.back = function() { 
			loader.showPageByName(this.pageName);
			console.debug("Loader : historyState : Browser History BACK : showing "+this.pageName);
		}
		this.forward = function() {
			loader.showPageByName(this.pageName);
			console.debug("Loader : historyState : Browser History FORWORD: showing "+this.pageName);
		}
	};

