var ViewAllTabs = new Class ({

	initialize: function (tabBoxContainer, dataURL, options) {
		this.options = {
				ajaxMethod				: 'post',
				ajaxRequest				: '',
				loadingBg				: '',
				minHeight				: '5em',
				editorsChoice			: false
			};
		Object.extend(this.options, options || {});

		var oTBC = this.tabBoxContainer = tabBoxContainer;
		this.dataURL = dataURL;

		this.tabLoading	= new Element('div').setHTML('The list is loading, please wait..').setStyles({
				textAlign			: 'center',
				fontSize			: '2em',
				backgroundImage		: this.options.loadingBg,
				backgroundRepeat	: 'no-repeat',
				backgroundPosition	: 'center center',
				display				: 'none',
				height				: this.options.minHeight
				}).injectInside(oTBC);

		this.tabLine 	= new Element('div').addClass('more_table_tab_line').injectInside(oTBC);
		new Element('div').setHTML('&nbsp;').addClass('clear').injectInside(oTBC);

		this.tabBoxes	= new Element('div').addClass('more_table_tab_container').injectInside(oTBC);

		this.tabHide	= new Element('a').setHTML('&laquo; HIDE THIS').addClass('hide').injectInside(oTBC);
		this.tabHide.onclick =  this.hide.bind(this).bindAsEventListener(this.tabHide).bind(this);

		new Element('div').setHTML('&nbsp;').addClass('clear').injectInside(oTBC);

		// start generating the tabs and boxes
		this.tabListContainers = new Array();

		new Element('a').setHTML('#').injectInside(this.tabLine);
		this.tabListContainers.push(new TabListContainer(4, this.tabBoxes));

		for (i=65; i < 91; i++) {
			new Element('a').setHTML(String.fromCharCode(i)).injectInside(this.tabLine);
			this.tabListContainers.push(new TabListContainer(4, this.tabBoxes));
		}

		var oMoreTabsDivs 	= $ES('div', this.tabBoxes);
		var oMoreTabsLinks 	= $ES('a', this.tabLine);

		// make the tabbed accordion
		var oMoreTabsOptions = {
			fps: 24,
			duration: 200,
			opacity: true,
			alwaysHide: false,
			display: 0,
			onActive: function (tog) {
					tog.addClass('more_table_tab_selected');
				},
			onBackground: function (tog) {
					tog.removeClass('more_table_tab_selected');
				}
			}

		this.moreTabsAccordion = new Accordion(oMoreTabsLinks, oMoreTabsDivs, oMoreTabsOptions);
		oMoreTabsLinks.each (function (tog) {tog.onclick = function () {return false;}});

		var	oMoreTabsSlideOptions = {
			duration: 300,
			opacity: false,
			onStart: function () {
					//oMoreTabs.display (0);
					},
			onComplete: function () {
					if (parseInt(this.element.getStyle('margin-top')) == 0) this.wrapper.setStyle('height', 'auto');
					}
			};
		this.tabBoxSlider = new Fx.Slide (this.tabBoxContainer, oMoreTabsSlideOptions).hide();
		this.tabBoxContainer.setStyles({display: 'block', marginTop: '-1px'});

		// if we have an editor's choice
		if (this.options.editorsChoice) {
			this.options.editorsChoiceSlider = new Fx.Slide (this.options.editorsChoice, {duration: 300, opacity: false});
		}
	},

	toggle: function (sWhat, bShow) {
		if (bShow) {
			// see what tab we need to show
			this.showTabNo = $chk(arguments[2]) ? arguments[2] : 0;
			// load contents with AJAX
			var sAJAX_content = this.tabBoxContainer.getProperty('AJAX_content');
			if (sAJAX_content != sWhat || sAJAX_content == '' || sAJAX_content == null) {

				// hide tabbed accordion and show a nice loading animation
				this.tabLine.setStyle('display', 'none');
				this.tabBoxes.setStyle('display', 'none');
				this.tabHide.setStyle('display', 'none');
				this.tabLoading.setStyle('display', '');

				// show the slider, if it's not already open
				if (this.tabBoxSlider.element.getStyle('margin-top').toInt() < 0) {
					if (this.options.editorsChoice) this.options.editorsChoiceSlider.toggle();
					this.tabBoxSlider.toggle();
				}

				// AJAX call
				this.tabBoxContainer.setProperty('AJAX_content', sWhat);

				var populateTabs = this.populateTabs.bind(this);
				var showError = this.showError.bind(this);
				var oAjaxOptions = {
					method: 'post',
					onComplete: populateTabs,
					onFailure: showError,
					headers: {'Referer': 'http://www.1001homes.co.uk'}
					};

				this.options.ajaxGetAllTags = new Ajax (this.dataURL + sWhat, oAjaxOptions).request();
				//console.log(this.dataURL + sWhat);
				} else if (sAJAX_content == sWhat) {
					// show the slider, if it's not already open
					if (this.tabBoxSlider.element.getStyle('margin-top').toInt() < 0) {
						if (this.options.editorsChoice) this.options.editorsChoiceSlider.toggle();
						this.tabBoxSlider.toggle();
					}
					this.switchToTab(this.showTabNo);
				}
		} else {
				this.tabBoxSlider.toggle();
				if (this.options.editorsChoice) this.options.editorsChoiceSlider.toggle();
		}
	},

	populateTabs: function (responseText, responseXML) {
		var oAllTagsJSON;

		try {
			oAllTagsJSON = Json.evaluate(responseText);
		} catch (err) {
			oAllTagsJSON = Json.evaluate('[]');
		}

		//console.log(oAllTagsJSON);

		// we don't have a valid response, return an error
		if (!oAllTagsJSON[0]) {this.showError(); return false;}

		var oMoreTabsDivs 	= $ES('div', this.tabBoxes);
		var oMoreTabsLinks 	= $ES('a', this.tabLine);
		this.tabListContainers.each (function (tab) {tab.blank();});
		oMoreTabsLinks.each ( function (tab) { tab.setStyle ('display', 'none' ); } );
		var iTagNameUFC; // upper case first char code of tag name

		oAllTagsJSON.each(
			function (tag) {
					if (tag['Name'].length > 0) {
						iTagNameUFC = tag['Name'].toUpperCase().charCodeAt(0);
						if ((iTagNameUFC > 64) && (iTagNameUFC < 91)) {
							// we have a letter
							this.tabListContainers[iTagNameUFC - 64].addLink(tag['Name'], tag['Link']);
							oMoreTabsLinks[iTagNameUFC - 64].setStyle ('display', 'block' );
						} else {
							// we have a sign / number
							this.tabListContainers[0].addLink(tag['Name'], tag['Link']);
							oMoreTabsLinks[0].setStyle ('display', 'block' );
						}
					}
				}.bind(this));

		oMoreTabsDivs.each (
			function (tab) {
				new Element ('div').addClass('clear').setHTML('&nbsp;').injectInside(tab);
				}
			);

		// remove the loading animation and show the tabs
		this.tabLoading.setStyle('display', 'none');
		this.tabLine.setStyle('display', '');
		this.tabBoxes.setStyle('display', '');
		this.tabHide.setStyle('display', '');

		this.switchToTab(this.showTabNo);
		//oMoreTabsLinks.each (function (tog) {tog.onclick = function () {return false;}});
	},

	showError: function () {
		//alert ('ERROR !!');
	},

	hide: function () {
		this.toggle('',false);
		return false;
	},

	switchToTab: function (tab) {
		// hack the accordion a bit to refresh heights
		$each(this.moreTabsAccordion.elements, function(el, i){
			el.fullOpacity = 1;
			el.fullWidth = this.options.fixedWidth || el.offsetWidth;
			el.fullHeight = this.options.fixedHeight || el.scrollHeight;
			el.setStyle('overflow', 'hidden');
		}, this.moreTabsAccordion);
		this.moreTabsAccordion.previous = -1;
		this.moreTabsAccordion.display(tab);
	}

});


var TabListContainer = new Class ({

	initialize: function (iMaxLists, oInsertWhere) {
		// create and inject the container div
		this.containerDiv = new Element('div').injectInside(oInsertWhere);
		this.lists = new Array();
		this.listIndex = 0;
		this.maxLists = iMaxLists;
	},

	getCurrentList: function () {

		var iCurrList = this.listIndex;
		// if listIndex + 1 is larger than the current number of lists available,
		// create a new list inside the container div
		if (this.lists.length < (iCurrList + 1)) {
			this.lists.push(new Element('ul').injectInside(this.containerDiv));
		}

		// increment current listIndex, but be careful not to go overboard
		this.listIndex++;
		if (this.listIndex > (this.maxLists - 1)) this.listIndex = 0;

		// return the current list
		return this.lists[iCurrList];
	},

	addLink: function (sLinkText, sLinkURL) {
		new Element('a').setHTML(sLinkText.truncate(16, '...')).setProperty('href', sLinkURL).setProperty('title', sLinkText).injectInside(new Element('li').injectInside(this.getCurrentList()));
	},

	blank: function () {
		this.listIndex = 0;
		this.lists = new Array();
		this.containerDiv.setHTML('');
	}
});