/*
---
name: ElementSwap.js
description: Slide show interface to swap between any group of elements.
authors: Shaun Freeman
requires:
    core/1.2.4:
    - Class
    - Class.Extras
    - Element
    - Element.Event
    - Selectors
provides: [ElementSwap]
license: MIT-style license
version: 1.0.1
...
*/

var ElementSwap = new Class({
	
	Implements: [Options, Events, Chain],
	
	slides: [],
	
	isLooping: false,
	
 	options: {
		selectedClass: 'active',
		elementSwapDelay: 3,
		panelWrap: 'elementSwapWrap',
		panelWrapClass: 'elementSwap',
		events: true,
		activateOnLoad: 0,
		autoPlay: false,
		onActive: $empty,
		onClickView: $empty,
		onNext: $empty,
		onPrevious: $empty
	},
 
 	initialize: function(elements, options) {
		this.setOptions(options);
		
		this.slides = $$(elements);
		
		this.wrap = new Element('div', {
			'id': this.options.panelWrap,
			'class': this.options.panelWrapClass
		}).inject(this.slides[0], 'before').adopt(this.slides);
		
		this.activate(this.options.activateOnLoad);
		
		if (this.options.autoPlay) this.start();
	},
	
	attach: function(elements) {
		$$(elements).each(function(el) {
			var enter = el.retrieve('elementSwap:enter', this.elementEnter.bindWithEvent(this, el));
			var leave = el.retrieve('elementSwap:leave', this.elementLeave.bindWithEvent(this, el));
			var mouseclick = el.retrieve('elementSwap:click', this.elementClick.bindWithEvent(this, el));
			el.addEvents({
				mouseenter: enter,
				mouseleave: leave,
				click: mouseclick
			});
		}, this);
		return this;
	},
	
	detach: function(elements) {
		$$(elements).each(function(el) {
			el.removeEvent('mouseenter', el.retrieve('elementSwap:enter') || $empty);
			el.removeEvent('mouseleave', el.retrieve('elementSwap:leave') || $empty);
		});
	},
	
	activate: function(index) {
		if ($type(index) == 'string') index = this.slides.indexOf(this.slides.filter('[id='+index+']')[0]);
		if ($type(index) != 'number') return;
		this.show(index);
	},
	
 	show: function(index) {
		if ($type(index) != 'number') return;
		this.now = index;
		this.slides.removeClass(this.options.selectedClass);
		this.slides[this.now].addClass(this.options.selectedClass);
		this.fireEvent('onActive', [this.now, this.slides[this.now]]);
		//return this.now;
	},
	
	start: function() {
		if (this.options.events) this.attach(this.slides);
		this.isLooping = true;
		this.slideShow = this.next.periodical(this.options.elementSwapDelay * 1000, this);
	},
	
	stop: function(notPause) {
		this.clearChain();
		$clear(this.slideShow);
		this.isLooping = false;
		if (notPause) this.detach(this.slides);
	},
	
	next: function() {
		var el = this.slides[this.now].getNext();
		if (!el) el = this.slides[0];
		this.activate(this.slides.indexOf(el));
		this.fireEvent('onNext');
		return this;
	},
	
	previous: function() {
		var el = this.slides[this.now].getPrevious();
		if (!el) el = this.slides[this.slides.length - 1];
		this.activate(this.slides.indexOf(el));
		this.fireEvent('onPrevious');
		return this;
	},

	elementClick: function(e, el) {
		this.fireEvent('onClickView', [this.now, el]);
	},
	
	elementEnter: function(e, el) {
		this.stop();
	},
 
	elementLeave: function(e, el) {
		this.start();
	}
});

/*
---
name: Tabs.js
description: Handles the scripting for a common UI layout; the tabbed box. 
authors: Shaun Freeman
requires:
    elementswap/1.0.1:
    - ElementSwap
provides: [Tabs]
license: MIT-style license
version: 1.0
...
*/

var Tabs = new Class({
	Implements: [Options, Events],
 
	options: {
		tabs: '.tabs_title li',
		panels: '.tabs_panel',
		selectedClass: 'active',
		elementSwapOptions: {
			selectedClass: 'active',
			panelWrap: 'tabsPanelWrap',
			panelWrapClass: 'tabs_panelwrap',
			activateOnLoad: 0,
			events: true,
			autoPlay: false
		},
		mouseOverClass: 'over',
		onActive: $empty,
		onBackground: $empty
	},
		
	initialize: function(options) {
		this.setOptions(options);
		
		this.tabs = $$(this.options.tabs);
		
		this.getSwap();
		
		this.attach(this.tabs);
		
		if($type(this.options.elementSwapOptions.activateOnLoad) == 'number') {
			this.activateTab(this.options.elementSwapOptions.activateOnLoad);
		}
	},
	
	getSwap: function(){
		this.elSwap = new ElementSwap(this.options.panels, this.options.elementSwapOptions).addEvent('onActive', this.showTab.bindWithEvent(this));
	},
	
	attach: function(elements) {
		$$(elements).each(function(element) {
			var enter = element.retrieve('tab:enter', this.elementEnter.bindWithEvent(this, element));
			var leave = element.retrieve('tab:leave', this.elementLeave.bindWithEvent(this, element));
			var mouseclick = element.retrieve('tab:click', this.elementClick.bindWithEvent(this, element));
			element.addEvents({
				mouseenter: enter,
				mouseleave: leave,
				click: mouseclick
			});
		}, this);
		return this;
	},
	
	activateTab: function(index) {
		this.showTab(index);
		this.elSwap.activate(index);
	},
	
	showTab: function(index) {
		this.now = index;
		this.tabs.removeClass(this.options.selectedClass);
		this.tabs[this.elSwap.now].addClass(this.options.selectedClass);
		this.fireEvent('onActive', [index, this.tabs[this.now]]);
		return this;
	},
	
	elementEnter: function(event, element) {
		if(element != this.tabs[this.now]) {
			element.addClass(this.options.mouseOverClass);
		}
	},
 
	elementLeave: function(event, element) {
		if(element != this.tabs[this.now]) {
			element.removeClass(this.options.mouseOverClass);
		}
	},
	
	elementClick: function(event, element) {
		event.stop();
		if(element != this.tabs[this.now]) {
			if (this.elSwap.isLooping) this.elSwap.stop(true);
			this.fireEvent('onBackground', [this.tabs[this.now]]);
			this.activateTab(this.tabs.indexOf(element));
		}
	}
});

