namespace("UPC.widget");

/**
 * Tab widget v1.0
 * Capabilities:
 * - create a tabbed interface from basic html markup *done*
 * - allows for multiple tabbed interfaces on one page *done*
 * - url parameters to link to specific tab page *done*
 * - store tab position in cookie *done*
 * - (optional) create new tabs via programming interface
 * - (optional) load tab content via AJAX interface
 * - (optional) use advanced effects for changing tabs
 * 
 * Requirements:
 * The HTML needs to be structured as follows
 * <div id="tab-container">
 * 	<div>
 * 		<h3 id="tab1"><a href="#tab1-content">Label 1</a></h3>
 * 		<div id="tab1-content">
 * 			Tab 1 content
 *		</div>
 * 	</div>
 * </div>
 * The label element id has to be part of the content element id 
 * 
 * Important notes:
 * - Tab selection priority: URL parameter > Cookie > default
 * 
 * Options object:
 * {
 * 		"tabCssSelector": "h3",				// CSS3 selector for the tab label element
 * 		"enhancedClassName": "enhanced",	// Class name that is added to the main container to trigger advanced styles
 * 		"activeTabClassName": "active",		// Class name given to the active tab
 * 		"contentElementIdTemplate": new Template("#{tab}-content"),		// Template for the content element id
 * 		"storeActiveTab": true,				// Whether to store the active tab in a cookie
 * 		"cookiePeriod": 30,					// Lifetime in days for the cookie
 * 		"defaultTab": 0,					// The index of the default tab (starts at 0)
 * 		"tabOffset": 0						// The horizontal offset of the labels in pixels
 * }
 * 
 * How to use:
 * In the page load event handler, add the following code:
 * UPC.widget.TabsManager.add(container);
 * 
 * where container is the main element for the tabs.
 */			

UPC.widget.TabsManager = function () {
	var tabLeftPosition = 0;
	var defaultOptions = {
		"tabCssSelector": "h3",
		"enhancedClassName": "enhanced",					
		"activeTabClassName": "active",
		"contentElementIdTemplate": new Template("#{tab}-content"),
		"storeActiveTab": true,
		"cookiePeriod": 30,
		"defaultTab": 0,
		"tabOffset": 0
	};
	var options = $H([]);
	
	var TabContainer = Class.create ({
		"container": null,
		"tabs": null,
		"maxHeight": 0,
		"activeTab": 0,
		"options": null,
		"name": "TabContainer",
		
		"initialize": function (element) {
			this.container = $(element);
			if (this.container == null) return null;
			
			this.options = options.get(this.container.id);
			
		    if (this.container.hasClassName(this.options.enhancedClassName)) {
			     return;
			}	
									
			this.container.addClassName(this.options.enhancedClassName);
			
			if (this.options.storeActiveTab) {
				this.activeTab = UPC.util.Cookie.read(this.container.id) || this.options.defaultTab;
			}	
			
			this.tabs = $A([]);
			var tabs = this.container.select(this.options.tabCssSelector);
			tabs.each(this.addTab.bind(this));
			
			this.getActiveTabFromUrl();
			
			this.container.observe("upc:onTabClick", this.selectTab.bindAsEventListener(this));

			return this;
		},
		
		"getActiveTabFromUrl": function () {
			var tab = null;
			var queryString = document.location.search.toQueryParams();
			
			if (typeof(queryString.tab) != "undefined") {
				if (typeof(queryString.tab) == "string") {
					tab = this.tabs.find(function(tab){
						return (tab.tabElement.id == queryString.tab);
					});
				} else {
					tab = this.tabs.find(function (tab) {
						return $A(queryString.tab).find(function (id) {
							return (tab.tabElement.id == id);
						})
					})
				}
			}

			if (tab != null) {
				this.selectTab(tab);
			}
		},
		
		"addTab": function (element, idx) {
			var tab = new Tab(element, this.options);

			if (element.getHeight() > this.maxHeight) {
				this.maxHeight = element.getHeight();
				this.container.setStyle({"paddingTop":this.maxHeight+"px"})
			}
			this.tabs.push(tab);	
			
			if (this.activeTab == idx) {
				this.selectTab(tab);
			}
		},
		
		"selectTab": function (e) {
			if (e.type == "dataavailable") {
				var tab = e.memo.tab;
			} else if (e.name == "Tab") {
				var tab = e;
			}
			// disable active tab
			if (!tab.isActive()) {
				this.tabs[this.activeTab].deactivate();
			}
			tab.activate();
			this.activeTab = this.tabs.indexOf(tab);
			
			if (this.options.storeActiveTab) {
				UPC.util.Cookie.write(this.container.id, this.activeTab, this.options.cookiePeriod, "/");
			}
		},
		
		"toString": function () {
			return "UPC TabContainer v1.0 (id:" + this.container.id + ")";
		}
	})
	
	var Tab = Class.create ({
		"tabElement": null,
		"contentElement": null,
		"_isActive": false,
		"options": null,
		"name": "Tab",
		
		"initialize": function (tab, options) {
			this.tabElement = $(tab);
			
			if (this.tabElement == null) {
				return false;
			}
			
			this.options = options;						
									
			var contentElementId = this.options.contentElementIdTemplate.evaluate({"tab": this.tabElement.id});
			this.contentElement = $(contentElementId);
			
			if (this.contentElement == null) {
				return false;
			}						
			
			this.tabElement.setStyle({"left":tabLeftPosition+"px"})
			tabLeftPosition = tabLeftPosition + this.tabElement.getWidth()
			
			this.tabElement.observe("click", this.onClick.bindAsEventListener(this));
			
			return true;
		},
		
		"activate": function () {
			this.tabElement.up().addClassName(this.options.activeTabClassName);
			
			this.contentElement.show();
			this._isActive = true;
			
			return true;
		},
		
		"deactivate": function () {
			this.tabElement.up().removeClassName(this.options.activeTabClassName);
			this.contentElement.hide();
			this._isActive = false;
			
			return true;
		},
		
		"isActive": function () {
			return this._isActive;
		},
		
		"toString": function () {
			return "UPC Tab interface v1.0 (id:" + this.tabElement.id + ")"			
		},
				
		"onClick": function (e) {
			// Custom event to allow other elements to react to tab click
			this.tabElement.fire("upc:onTabClick", {
				"originalEvent": e,
				"tab": this
			});
			e.stop();
		}
	})
	
	var tabContainers = $A([]);
	
	function add (element, userOptions) {
		element = $(element);
		if (element == null) return;
		
		var tmpOptions = Object.extend({}, defaultOptions);
		if (typeof(userOptions) != "undefined") {
			tmpOptions = Object.extend(tmpOptions, userOptions);
		}
		options.set(element.id, tmpOptions);
		
		tabLeftPosition = 0+options.get(element.id).tabOffset;
		var tc = new TabContainer(element);
		if (tc != null) {
			tabContainers.push(tc);
		}
	}
	
	return {
		"add": add
	}
}();

function hideAnswers() {
	// hide the answers
	$$(".answer").each(function (answer) {
		answer.hide();
	})

	// bind the event handler for clicking the question
	$$(".question").invoke("observe", "click", function (e){
		var question = e.element();
		var id = question.id.sub("q", "a"); 
		$(id).toggle();
		e.stop();
	});
	
     // bind the event handler for clicking the question
	$$(".question").invoke("observe", "mouseover", function (e){
		e.element().style.cursor = 'pointer';
	});

	// show the answer if it's set in the url hash component.
	if (window.location.hash.length > 0) {
		var answer = $('a-' + window.location.hash.substring(1))
		if (answer) {
			answer.show();
		}
	}
}

// DEPRECATED DO NOT USE ANYMORE
function toggleAnswer(a) {
	/*
	if (document.getElementById) {
		b = document.getElementById(a);
		if (b.style.display == 'none') {
			b.style.display = 'block';
		} else {
			b.style.display = 'none';
		}
	}
   */
}

document.observe("dom:loaded", function () { 
  hideAnswers();
});
