/**
 * Lucid Tabs
 * Easy tabs with minimal markup.
 *
 * Copyright (c) 2009 PJ Dietz
 * Version: 1.00
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * http://pjdietz.com/jquery-plugins/lucid-tabs/
 */

/*global jQuery */

(function ($) {

		var TabSet, Tab, Page;


		////////////
		// TabSet //
		////////////

		TabSet = function (elem, options) {

				var domTabs,
						domPage, domTab,
						tab,
						i, u;


				this.options = $.extend({}, TabSet.defaultOptions, options);
				this.selected = this.options.selected;
				this.tabs = [];

				// Store a refernce to the TabSet object in data.
				elem.data("TabSet", this);

				// Use selector to locate the container element.
				// Find all contained anchors that may reference an element by ID.
//				domTabs = elem.find("a[href^=#]");
//				domTabs = elem.find("input[rel^=#],label[rel^=#],span[rel^=#]");
				domTabs = elem.find("[rel^=#]");

				// Iterate over the selected tabs.
				// Create a new Tab for each element and store it in this.tabs;
				for (i = 0, u = domTabs.length; i < u; i += 1) {

						domTab = $(domTabs[i]);
//						domPage =  $(domTab.attr("href"));
						domPage =  $(domTab.attr("rel"));

						if (domPage.length === 1) {

								// Hide the page
								domPage.hide();

								tab = new Tab(domTab, domPage, this);
								this.tabs.push(tab);
						}

				}

				// Set the initial selection
				this.tabs[this.selected].select();

		};

		TabSet.prototype = {

				select: function (index) {

						// Index is an object. Retrieve its index (or -1).
						if (typeof index === "object") {
								index = this.getIndex(index);
						}

						// Ensure the index is in range.
						if (index < 0 || index > this.tabs.length) {
								return false;
						}

						// Don't select the selected tab
						if (index === this.selected) {
								return false;
						}

						// Show the new before hiding the old to avoid scrolling when the
						// browser momentarily sees a shorter page.
						this.tabs[index].select();
						this.tabs[this.selected].deselect();
						this.selected = index;

						return true;
				},

				// Return the index of the passed tab
				getIndex: function (tab) {

						var i, u;

						for (i = 0, u = this.tabs.length; i < u; i += 1) {
								if (this.tabs[i] === tab) {
										return i;
								}
						}

						return -1;

				}

		};

		// Default Options for tab sets.
		//
		// To customize a tab set on creation, pass an object containing the
		// members to redefine.
		//
		TabSet.defaultOptions = {

				// Index of the initially selected tab
				selected: 0,

				// Name of the CSS class to add to tab anchors when selected
				cssSelected: 'selected',

				// Function called to display a page
				showPage: function (elem) {
						elem.show();
				},

				// Function called to hide a page
				hidePage: function (elem) {
						elem.hide();
				}

		};



		/////////
		// Tab //
		/////////

		Tab = function (domTab, domPage, tabSet) {

				this.domTab = domTab;
				this.tabSet = tabSet;

				// Store a reference to the wrapper Tab
				domTab.data('Tab', this);

				// Bind the event handler.
				domTab.click(Tab.handleClick);
				domTab.children('input label').click(Tab.handleClick);
//				domTab.children().click(Tab.handleClick);

				this.page = new Page(domPage, this);
		};

		Tab.prototype = {

				select: function () {

						var cls = this.tabSet.options.cssSelected;

						if (!this.domTab.hasClass(cls)) {
								this.domTab.addClass(cls);
						}

						this.page.show();

				},

				deselect: function () {

						var cls = this.tabSet.options.cssSelected;

						if (this.domTab.hasClass(cls)) {
								this.domTab.removeClass(cls);
						}

						this.page.hide();
				}

		};

		Tab.handleClick = function (event) {

				var tab = $(event.target).data('Tab');
				tab.tabSet.select(tab);

				return false;
		};



		//////////
		// Page //
		//////////

		Page = function (domPage, tab) {

				this.domPage = domPage;
				this.tab = tab;

				// Store a reference to the wrapper Page
				domPage.data('Page', this);
		};

		Page.prototype = {

				show: function () {
						if (this.domPage.is(":hidden")) {
								this.tab.tabSet.options.showPage(this.domPage);
						}
				},

				hide: function () {
						if (this.domPage.is(":visible")) {
								this.tab.tabSet.options.hidePage(this.domPage);

						}
				}
		};



		// Extend jQuery -----------------------------------------------------------

		$.fn.extend({
				tabs: function (options) {
						return this.each(function () {
								var dummy = new TabSet($(this), options);
						});
				}
		});

}(jQuery));


/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true,
	eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true */
