// $Id: control.tabs.extend.js 8362 2010-08-31 10:35:01Z warren $
// This subclass provides extensions to the Livepipe vendor's Control.Tabs object

if (typeof(Prototype) == "undefined")
	throw "Control.Tabs requires Prototype to be loaded.";
if (typeof(Control.Tabs) == "undefined")
	throw "Control.TabsExtended requires Control.Tabs to be loaded.";

Control.TabsExtended = Class.create(Control.Tabs, {
	initialize: function ($super,tab_list_container,options) {
		// augment the base class method with additional options and events
		var subclassOptions = {
			startExpanded: false,
			expandedClassName: 'expanded',
			collapsedClassName: 'collapsed',
			paragraphNodeID: 'tabToggle',
			expandStart: Prototype.emptyFunction,
			expandEnd: Prototype.emptyFunction,
			collapseStart: Prototype.emptyFunction,
			collapseEnd: Prototype.emptyFunction
		};
		// call overridden initialize method in base class
		$super(tab_list_container, Object.extend(subclassOptions, options || {}));
		
		this.tabsContainer = $(tab_list_container.parentNode);
		this.lastActiveContainer = null;
		this.expanded = null;
		
		// start with collapsed or expanded view?
		(this.links.size() < 1 || this.options.startExpanded) ? this.expand() : this.collapse();
		
		if (this.isCollapsed() && location.hash != '') {
			if (location.hash == '#voiceBox' && $('voiceBox')) {
				if (this.activeContainer.id != 'about' && $('voiceBox').descendantOf('about')) {
					// set active tab to 'about' before jumping to voice-recording - this was applicable to narrow site layouts
					this.setActiveTab('about');
				}
				location.hash = location.hash;
			} else if (this.tabsContainer.id) {
				// jump to top of tab navigation
				location.hash = '#' + this.tabsContainer.id;
				// consider: location.replace('#' + this.tabsContainer.id);
			}
		}
		
		if ($('hasVoiceRec') && $('voiceBox') && $('voiceBox').descendantOf('about')) {
			// click-event handler to set the active tab to 'about' before jumping to a voice-recording - this was applicable to narrow site layouts
			$('hasVoiceRec').observe('click', function (event) {
				if (this.isCollapsed() && this.activeContainer.id != 'about') {
					this.setActiveTab('about');
					location.hash = '#' + $('voiceBox').id;
				}
			}.bindAsEventListener(this));
		}
	},
	addTab: function ($super,link) {
		// call overridden addTab method in base class
		$super(link);
		
		if (typeof window.haveWarned != 'undefined' && typeof window.confirmExpand != 'undefined' && link.key == 'private' && typeof $('find_morePhotos') != 'undefined') {
			// adjust the onclick/onmouseover event to selectively display the private photo warning prompt
			link[this.options.hover ? 'onmouseover' : 'onclick'] = function (link) {
				if (window.event)
					Event.stop(window.event);
				if (this.isExpandable(link))
					this.setActiveTab(link);
				return false;
			}.bind(this,link);
		}
	},
	isExpandable: function (link) {
		if (link.key == 'private' && typeof $('find_morePhotos') != 'undefined') {
			if (window.haveWarned || (window.haveWarned = window.confirmExpand())) {
				if (location.href.toQueryParams().p != '1') {
					if (link.hash == '#' + link.key) {
						var urlParts = link.toString().split('#',2);
						location.href = urlParts[0].replace(/(&?p=\w*)+/,'') + '&' + encodeURIComponent('p') + '=' + encodeURIComponent('1') + '#' + urlParts[1];
						return false;
					}
				}
				return true;
			}
			return false;
		}
		return true;
	},
	isExpanded: function () {
		return (this.expanded == true);
	},
	isCollapsed: function () {
		return !this.isExpanded();
	},
	appendTabToggle: function () {
		if (this.links.size() > 1) {
			var paragraphNode = $(this.options.paragraphNodeID);
			var paragraphNodeExists = (paragraphNode) ? true : false;
			var anchorNode = (paragraphNodeExists) ? paragraphNode.down() : null;
			var anchorNodeExists = (paragraphNodeExists && anchorNode) ? true : false;
			
			if (anchorNodeExists) {
				// if the anchor node exists in the DOM, then remove the relevant event handler that was previously set
				Event.stopObserving(anchorNode, 'click', (this.isExpanded() ? this.expandBind : this.collapseBind));
				
				// and remove the DOM anchor node itself
				anchorNode.remove();
			}
			
			if (this.isExpanded()) {
				// if the tabs are expanded, build a 'collapse' anchor
				anchorNode = Builder.node('a', {href:'#',id:'collapseAnchor',title:copyItems['collapseAnchorTitle'] || 'Collapse all tabs'}, copyItems['collapseAnchorText'] || 'Collapse tabs');
				// add an onclick event handler to call the collapse method
				this.collapseBind = this.collapse.bindAsEventListener(this);
				Event.observe(anchorNode, 'click', this.collapseBind);
			} else {
				// the default case, collapsed, then build an 'expand' anchor
				anchorNode = Builder.node('a', {href:'#',id:'expandAnchor',title:copyItems['expandAnchorTitle'] || 'Expand all tabs'}, copyItems['expandAnchorText'] || 'Expand tabs');
				// add an onclick event handler to call the expand method
				this.expandBind = this.expand.bindAsEventListener(this);
				Event.observe(anchorNode, 'click', this.expandBind);
			}
			
			// attach the anchor node to an exisitng paragraph node, or create a new paragraph node
			paragraphNode = paragraphNode || Builder.node('p', {id: this.options.paragraphNodeID});
			paragraphNode.appendChild(anchorNode);
			
			// append the paragraph child node to the tab container
			this.tabsContainer.appendChild(paragraphNode);
			
			// * sample output */
			// <p id="tabToggle"><a href="#" id="expandAnchor" onclick="return expand();">Expand xxx</a></p> | <p id="tabToggle"><a href="#" id="collapseAnchor" onclick="collapse();">Collapse xxx</a></p>
		}
	},
	expand: function (e) {
		var isInitialising = (this.expanded === null);
		if (this.isCollapsed() || isInitialising) {
			this.options.expandStart(this);
			Control.Tabs.notify('expandStart',this);
			
			var mayExpand = isInitialising || typeof window.haveWarned == 'undefined' || false;
			if (!mayExpand && typeof window.haveWarned != 'undefined') {
				this.links.each(function (link) {
					mayExpand = this.isExpandable(link);
					if (!mayExpand) {
						throw $break;
					}
				}.bind(this));
			}
			
			if (mayExpand) {
				this.tabsContainer.removeClassName(this.options.collapsedClassName).addClassName(this.options.expandedClassName);
				this.expanded = this.tabsContainer.hasClassName(this.options.expandedClassName);
				this.appendTabToggle();
				
				this.lastActiveContainer = this.activeContainer;
				this.containers.each(function (container) {
					if (container[1].hasClassName('hideOnExpand')) {
						// if a tab has class "hideOnExpand" set, then hide it at this point
						container[1].hide();
						if (this.activeContainer == container[1]) {
							this.next();
							if (this.activeContainer == container[1]) {
								this.previous();
							}
						}
					} else {
						// otherwise show each of the other tabs' content
						container[1].show();
					}
				}.bind(this));
				
				// jump to the top of the current tab
				if (!isInitialising) {
					location.href = this.activeLink;
				} else if (location.hash != '' && $(location.hash.substr(1))) {
					location.hash = location.hash;
				}
			}
			
			this.options.expandEnd(this);
			Control.Tabs.notify('expandEnd',this);
		}
		if (e) { Event.stop(e); }
	},
	collapse: function (e) {
		var isInitialising = (this.expanded === null);
		if (this.isExpanded() || isInitialising) {
			if (!isInitialising) {
				this.options.collapseStart(this);
				Control.Tabs.notify('collapseStart',this);
			}

			this.tabsContainer.removeClassName(this.options.expandedClassName).addClassName(this.options.collapsedClassName);
			this.expanded = this.tabsContainer.hasClassName(this.options.expandedClassName);
			this.appendTabToggle();

			if (!isInitialising) {
				this.containers.values().invoke('hide');
				
				// restore the previously active tab, or default to another one
				if (this.lastActiveContainer !== null) {
					this.setActiveTab(this.lastActiveContainer.id);
					this.lastActiveContainer = null;
				} else if (this.options.defaultTab == 'first') {
					this.setActiveTab(this.links.first());
				} else if (this.options.defaultTab == 'last') {
					this.setActiveTab(this.links.last());
				} else {
					this.setActiveTab(this.options.defaultTab);
				}
				
				// jump to tabs list, or worst case to the top of the container
				location.hash = (this.tabsContainer) ? this.tabsContainer.id : 'container';
				
				this.options.collapseEnd(this);
				Control.Tabs.notify('collapseEnd',this);
			}
		}
		if (e) { Event.stop(e); }
	}
});
Object.Event.extend(Control.TabsExtended);
