var Showcase = Class.create();
Showcase.prototype = {
	_options: {
		effect: 'fade', // none, fade (slide - not performed)
		effectDuration: 0.5,
		autoPlay: true,
		interval: 30000,
		canvasBg: '#fff',
		minZIndex: 1,
		slides: '.slides li',
		navigation: '.navigation li',
		navigationTitle: '.slide-title a',
		navigationText: '.slide-text p',
		textLength: 45,
		navigationThumbnail: 'img'
	},
	
	_activeSlide: 0,
	
	initialize: function(container, options)
	{
		this.container = container;
		var that = this;
		
		Object.extend(this._options, options);
		
		this._prepareNavigation();
		this._updateNavigation();
		this._prepareLayout();
		
		if (this._options.autoPlay) {
			this._start();
			$(this.container).observe('mouseover', this._stop.bind(this));
			$(this.container).observe('mouseout', this._start.bind(this));
		}
	},
	
	_prepareNavigation: function()
	{
		var that = this;
		var navigation = new Element('ul', {'class': 'navigation'});
		var prevSibling = $$(this._options.slides)[0].up();
		$$('#' + this.container + ' ' + this._options.slides).each(function(el, index){
			var navi = new Element('li');
			navi.insert(
				'<div class="description">' + 
					'<h5>' + el.select(that._options.navigationTitle)[0].innerHTML + '</h5>' +
					'<p>' + el.select(that._options.navigationText)[0].innerHTML.substr(0, that._options.textLength) + '<p>' + 
				'</div>'
			
			);
			navi.value = index;
			navigation.insert(navi);
		})
		prevSibling.insert({ 'after': navigation })
	},
	
	_prepareLayout: function()
	{
		var that = this;
		switch (this._options.effect) {
			case 'fade':
				$$('#' + this.container + ' ' + this._options.slides).each(function(el, index){
					if (index == 0) 
						zIndex = that._options.minZIndex + 2;
					else {
						zIndex = that._options.minZIndex;
                        Effect.Fade(el, {duration: 0});
						//el.fade({duration: 0});
					}
					el.setStyle({zIndex: zIndex})
				})
				
				$$('#' + this.container + ' ' + this._options.navigation).each(function(el, index){
					el.observe('click', that._fadeSlide.bind(that));
					el.observe('mouseenter', that._hoverIn); 
					el.observe('mouseleave', that._hoverOut);
				})
				
				this._addCanvas();
			break;
			
			case 'slide':
			break;
			
			default:
				$$('#' + this.container + ' ' + this._options.slides).each(function(el, index){
					if (index == 0) zIndex = that._options.minZIndex + 2;
					else zIndex = that._options.minZIndex;
					el.setStyle({zIndex: zIndex})
				})
				
				$$('#' + this.container + ' ' + this._options.navigation).each(function(el, index){
					el.observe('click', that._switchSlide.bind(that));
					el.observe('mouseenter', that._hoverIn);
					el.observe('mouseleave', that._hoverOut);
				})
                
                this._addCanvas();
			break;
		}
	},
	
	_addCanvas: function()
	{
		var prevSibling = $$('#' + this.container + ' ' + this._options.slides).last();
		var canvas = new Element('li');
		canvas.setStyle({
			background: this._options.canvasBg,
			zIndex: this._options.minZIndex + 1,
			width: $(this.container).getWidth() + 'px',
			height: $(this.container).getHeight() + 'px'
		})
		prevSibling.insert({
			'after': canvas
		});
	},
	
	_switchSlide: function(e)
	{
		var slides = $$('#' + this.container + ' ' + this._options.slides);
		
		var activeSlide = slides[this._activeSlide];
		
		if (e)
			var indexToActivate = this._getClickedIndex(e.element());	
		else 
			var indexToActivate = this._activeSlide >= slides.length - 2 ? 0 : this._activeSlide + 1;	
		
		var element = slides[indexToActivate];
		
		if (activeSlide == element)
			return;
		
		activeSlide.setStyle({
			zIndex: this._options.minZIndex
		})
		
		element.setStyle({
			zIndex: this._options.minZIndex + 2
		})
		
		this._activeSlide = indexToActivate;
		this._updateNavigation();
	},
	
	_fadeSlide: function(e)
	{
		var slides = $$('#' + this.container + ' ' + this._options.slides);
		
		var activeSlide = slides[this._activeSlide];
		
		if (e)
			var indexToActivate = this._getClickedIndex(e.element());	
		else 
			var indexToActivate = this._activeSlide >= slides.length - 2 ? 0 : this._activeSlide + 1;
		
		var element = slides[indexToActivate];
		
		if (activeSlide == element)
			return;
			
		var that = this;
		
		/*activeSlide.fade({
			duration: that._options.effectDuration,
			afterFinish: function(){
				activeSlide.setStyle({
					zIndex: that._options.minZIndex
				})
			}
		})*/
        Effect.Fade(activeSlide, {
            duration: that._options.effectDuration,
            afterFinish: function(){
                activeSlide.setStyle({
                    zIndex: that._options.minZIndex
                })
            }
        });
		
		/*element.setStyle({
			zIndex: that._options.minZIndex + 2
		}).appear({
			duration: that._options.effectDuration
		});*/
        element.setStyle({
            zIndex: that._options.minZIndex + 2
        })
        Effect.Appear(element, {
            duration: that._options.effectDuration
        })
		
		this._activeSlide = indexToActivate;
		this._updateNavigation();
	},
	
	_next: function()
	{
		switch (this._options.effect) {
			case 'fade':
				this._fadeSlide();
			break;
			
			case 'slide':
			break;
			
			default:
				this._switchSlide();
			break;
		}
	},
	
	_stop: function()
	{
		window.clearInterval(this.interval);
	},
	
	_start: function(e)
	{
		if (this._bubbledFromChild(e))
			return;
		
		this.interval = setInterval(this._next.bind(this), this._options.interval);
	},
	
	_updateNavigation: function()
	{
		$$('#' + this.container + ' ' + this._options.navigation).each(function(el, index){
			el.removeClassName('active');
		})
		$$('#' + this.container + ' ' + this._options.navigation)[this._activeSlide].addClassName('active');
	},
	
	_getClickedIndex: function(el)
	{
		while (el.tagName != 'LI')
			el = el.parentNode;
		return el.value;
	},
	
	_hoverIn: function(e)
	{
		e.element().addClassName('hover');
	},
	
	_hoverOut: function(e)
	{
		e.element().removeClassName('hover');
	},
	
	_bubbledFromChild: function(event)
	{
		if (typeof event == 'undefined')
			return false;
			
		var target = event.element();
		return (event.relatedTarget && event.relatedTarget.descendantOf(target));
	}
}
