SpecsTableController = Class.create();
SpecsTableController.prototype =
{
	initialize: function(container)	{
		this.container = $(container);
		this.pages = new Array();
		this.paginator = null;

		// init pages
		var self = this;
		$A(this.container.getElementsByTagName('table')).each(
			function(page) {
				self.pages.push(new SpecsTable(page));
			}
		);

		// init paginator
		if (this.container.getElementsByTagName('ul')[0]) {
			this.paginator = new SpecsTablePaginator(this, this.container.getElementsByTagName('ul')[0]);
		}
	},

	switchPage: function(index)	{
		if (index >= this.pages.length) return;
		this.pages.each(
			function(page, pageIndex) {
				(pageIndex == index) ? Element.show(page.table) : Element.hide(page.table);
			}
		);
	}
}

SpecsTablePaginator = Class.create();
SpecsTablePaginator.prototype =
{
	initialize: function(oController, eList) {
		this.controller = oController;
		this.element = $(eList);
		this.tabs = new Array();
		this.initializeTabs();
	},

	initializeTabs: function() {
		var els = $A(this.element.getElementsByTagName('a'));
		var self = this;
		els.each(
			function(el) {
				self.tabs.push(el);
				Event.observe(el, 'click', self.switchTab.bindAsEventListener(self));
			}
		)
	},

	switchTab: function(e) {
		var target = Event.element(e);
		var self = this;
		this.tabs.each(
			function(tab, index) {
				if (tab == target) {
					self.controller.switchPage(index);
					Element.addClassName(tab, 'on');
				} else {
					Element.removeClassName(tab, 'on');
				}
			}
		);
	}
}

SpecsTablePaginatorTab = Class.create();
SpecsTablePaginatorTab.prototype =
{
	initialize: function(oController, el) {
		this.controller = oController;
		this.element = $(el);
		alert(this.element);
		return;
		Event.observe(this.element, 'click', this.controller.switchTab.bindAsEventListener(this.element));
		//alert(this.controller);
	}
}


/**
 * Control class to manage the redrawing of the specs table, to allow for
 * the hiding of entire columns, and doing the necessary class reassignments
 * to keep the vertical alternate column striping.
 */
SpecsTable = Class.create();
SpecsTable.prototype =
{
	initialize: function(table)
	{
		this.table = $(table);
		this.tableGroups = new Array();
		this.initializeGroups();
	},

	initializeGroups: function()
	{
		var tbodies = $A(this.table.getElementsByTagName('tbody'));
		var parent = this;
		tbodies.each(
			function(node) {
				parent.tableGroups.push(new SpecsTableGroup(node));
			}
		)
	},

	hideColumn: function(index) {
		this._setColumnState(index, true);
	},

	showColumn: function(index) {
		this._setColumnState(index, false);
	},

	_controlItem_onClick: function(index, checked) {
		if (index >= 0) {
			(checked) ? this.showColumn(index) : this.hideColumn(index);
		}
	},

	_setColumnState: function(index, hide) {
		var rows = $A(this.table.getElementsByTagName('tbody')[0].getElementsByTagName('tr'));
		rows.each (
			function (row)
			{
				var cols = $A(row.getElementsByTagName('td'));
				(hide) ? Element.addClassName(cols[index],'hidden') : Element.removeClassName(cols[index],'hidden');

				// re-colour the columns, if they aren't headers
				if (Element.hasClassName(row,'thead')) return;
				// get a new array of visible cols
				cols = cols.partition(function(col){return Element.hasClassName(col,'hidden')})[1];
				cols.each (
					function(col,i)	{
						(i % 2 != 0) ? Element.addClassName(col,'dark') : Element.removeClassName(col,'dark');
					}
				);
			}
		);
	}
}

/**
 * Control class to manage the expanding and collapsing of rows within
 * a TBODY element. The first row in the array of child TRs is assumed
 * to be the "control row", and is not collapsed.
 */
SpecsTableGroup = Class.create();
SpecsTableGroup.prototype = {

	initialize: function(el)
	{
		this.element = $(el);
		this.rows = $A(this.element.getElementsByTagName('tr'));
		this.header = this.rows.shift();
		var parent = this;
		Event.observe(this.header, 'click', function() {parent.toggle()});
	},

	isOpen: function() {
		return Element.visible(this.rows[0]);
	},

	collapse: function() {
		this._setOpenState(false);
	},

	expand: function() {
		this._setOpenState(true);
	},

	toggle: function() {
		(this.isOpen()) ? this.collapse() : this.expand();
	},

	_setOpenState: function(open)
	{
		var parent = this;
		if (this.rows.length > 0)
		{
			this.rows.each
			(
				function(row)
				{
					if (open) {
						Element.show(row);
						Element.removeClassName(parent.header, 'closed');
					} else {
						Element.hide(row);
						Element.addClassName(parent.header, 'closed');
					}
				}
			)
		}
	}
}