var Carousel = {

	slides: null,
	slideBar: null,
	previewElements: null,
	hoverElements: null,
	currentSlide: null,
	executer: null,
	sliding : null,
	
	options: {
		slidePause: 6,
		slidePauseClick: 14,
		fadeDurationOneStep: 0.25,
		previewMarkerDuration: 0.25,
		slideQueueScope: 'slide'
	},
	
	initialize: function() {
		var slidesContainer = $('slides');
		this.slideBar = $('slidebar');
		if (slidesContainer && this.slideBar) {
			this.slides = slidesContainer.select('.slide');
			var btnPrev = $('button_prev');
			if (btnPrev) {
				btnPrev.observe('click', this.navButtonHandler.bindAsEventListener(this, -1));
				btnPrev.observe('mouseover', this.arrowOver.bindAsEventListener(this, true));
				btnPrev.observe('mouseout', this.arrowOver.bindAsEventListener(this, false));
			}
			var btnNext = $('button_next');
			if (btnNext) {
				btnNext.observe('click', this.navButtonHandler.bindAsEventListener(this, 1));
				btnNext.observe('mouseover', this.arrowOver.bindAsEventListener(this, true));
				btnNext.observe('mouseout', this.arrowOver.bindAsEventListener(this, false));
			}
			this.previewElements = this.slideBar.select('.preview .hand');
			this.previewElements.each(function(el, i) {
				el.previewIndex = i;
			}.bind(this));
			this.hoverElements = this.slideBar.select('.preview .hover');
			this.hoverElements.each(function(el, i) {
				el.previewIndex = i;
				el.observe('mouseover', this.previewOver.bindAsEventListener(this, true));
				el.observe('mouseout', this.previewOver.bindAsEventListener(this, false));
				el.observe('click', this.previewClick.bind(this));
			}.bind(this));			
			this.showSlide(0, false);
		}
	},
	
	arrowOver : function(ev, over) {
	    var el = Event.element(ev);	
	    if (over) {    
	    	el.style.backgroundPosition='0px -40px';
	    }
	    else {
	    	el.style.backgroundPosition='0px 0px';
	    }
	},	
	
	previewOver: function(ev, over) {
		var element = Event.element(ev);
		if (element.previewIndex != this.currentSlide) {
			new Effect.Opacity(element, {
				from: over ? 0 : 1,
				to: over ? 1 : 0,
				duration: this.options.previewMarkerDuration
			});
		}
	},
	
	previewClick: function(ev) {
		var element = Event.element(ev);
		if (element.previewIndex != this.currentSlide) {
			this.previewOver(ev, false);
			this.showSlide(Event.element(ev).previewIndex, true);
			Event.stop(ev);
		}
	},
	
	killExecuter: function() {
		if (this.executer && this.executer != null) {
			this.executer.stop();
			this.executer = null;
		}
	},
	
	initNextShow: function(manual) {
		this.killExecuter();
		this.executer = new PeriodicalExecuter(this.autoNextSlide.bind(this), !manual ? this.options.slidePause : this.options.slidePauseClick);
	},
	
	autoNextSlide: function() {
		this.showNextSlide(false);
	},
	
	showPrevSlide: function(manual) {
		this.killExecuter();
		this.showSlide(this.currentSlide > 0 ? this.currentSlide - 1 : this.slides.length - 1, manual);
	},

	showNextSlide: function(manual) {
		this.killExecuter();
		this.showSlide(this.currentSlide < this.slides.length - 1 ? this.currentSlide + 1 : 0, manual);
	},
	
	showSlide: function(slideNo, manual) {
		
		if (!this.sliding) {
			
			this.sliding = true;
			
			var oldSlide = this.currentSlide;
			if (this.currentSlide != null) {
				Effect.toggle(this.slides[this.currentSlide], 'appear', {
					duration: this.options.fadeDurationOneStep,
					queue: 'end',
					scope: this.options.slideQueueScope,
					afterFinish: function() {
						new Effect.Opacity(this.previewElements[oldSlide], {
							from: 1,
							to: 0,
							duration: this.options.previewMarkerDuration
						});				
						this.currentSlide = slideNo;
					}.bind(this)
				});
			}
			this.slides[slideNo].appear({
				duration: this.options.fadeDurationOneStep,
				queue: 'end',
				scope: this.options.slideQueueScope,
				beforeStart: function() {
					this.currentSlide = slideNo;
					new Effect.Opacity(this.previewElements[slideNo], {
						from: 0,
						to: 1,
						duration: this.options.previewMarkerDuration
					});								
				}.bind(this),
				afterFinish: function() {
					this.initNextShow(manual);
					this.sliding = false;
				}.bind(this)
			});
		}
	},
	
	navButtonHandler: function(ev, direction) {
		if (direction > 0) {
			this.showNextSlide(true);
		} else if (direction == -1) {
			this.showPrevSlide(true);
		}
		Event.stop(ev);
	}
};

document.observe('dom:loaded', function() {
	Carousel.initialize();
});
