/*
 * HTMLSlideshow
 * Eine einfache Slideshow, die durch eine Reihe von HTML-Elementen mit beliebigem Inhalt rotiert
 * Copyright (c) 2009 Peter Kröner, <http://www.peterkroener.de>, MIT License
 */

var HTMLSlideshow = new Class({

	Implements: [Options, Events],
	options: {
		slides: [],
		interval: 4000,
		start: 0,
		wait: true,
		showFunction: false,
		hideFunction: false
	},
	container: false,
	slides: [],
	index: 0,
	timer: 0,

	initialize: function(el, options){
		this.setOptions(options);
		el = document.id(el);
		this.index = this.options.start;
		this.setupContainer(el);
		this.setupslides(el);
		return this;
	},

	// TODO: Was wenn der Container neu ist, aber noch nicht injected?
	setupContainer: function(el){
		if(!this.options.container){
			this.container = new Element('div', {
				'class': 'slideshowContainer'
			});
			this.container.inject(el, 'top');
		} else {
			this.container = $(this.options.container);
		}
		if(this.options.wait === true){
			var that = this;
			this.container.addEvents({
				'mouseover': function(){
					that.stop();
				},
				'mouseout': function(){
					that.start();
				}
			});
		}
	},

	setupslides: function(el){
		if($type(this.options.slides) === 'collection'){
			this.slides = this.options.slides();
		} else if($type(this.options.slides) === 'string') {
			this.slides = $$(this.options.slides);
		}
		this.container.adopt(this.slides);
		var maxHeight = 0;
		var maxWidth = 0;
		this.slides.each(function(element){
			var size = element.getSize();
			element.store('height', size.y);
			element.store('width', size.x);
			if(size.y > maxHeight){
				maxHeight = size.y;
			}
			if(size.x > maxWidth){
				maxWidth = size.x;
			}
		});
		this.container.setStyles({
			position: 'relative',
			height: maxHeight + 'px'
		});
		this.slides.each(function(element){
			var height = element.retrieve('height');
			var width = element.retrieve('width');
			var top = Math.round((maxHeight - height) / 2);
			var left = Math.round((maxWidth - width) / 2);
			element.setStyles({
				position: 'absolute',
				top: top + 'px',
				left: left + 'px'
			});
			if(element != this.slides[this.options.start]){
				element.setStyle('opacity', 0);
			}
		}.bind(this));
	},

	start: function(i){
		if(i){
			this.index = i;
		}
		this.timer = this.slide.periodical(this.options.interval, this);
	},

	stop: function(){
		$clear(this.timer);
	},

	slide: function(){
		this.hideSlide('slide');
		if(this.slides[this.index] == this.slides.getLast()){
			this.index = 0;
		} else {
			this.index = ++this.index;
		}
		this.showSlide(null, 'slide');
	},

	slideBack: function(){
		this.hideSlide('slideBack');
		if(this.index == 0){
			this.index = this.slides.length - 1;
		} else {
			this.index = --this.index;
		}
		this.showSlide(null, 'slideBack');
	},

	slideTo: function(i){
		this.hideSlide('slideTo');
		this.showSlide(i, 'slideTo');
	},

	showSlide: function(i, func){
		if(i){
			this.index = i;
		}
		if($type(this.options.showFunction) === 'function'){
			this.options.showFunction(this.slides[this.index], func);
		} else {
			this.slides[this.index].fade('in');
		}
		this.fireEvent('slide', this.index);
	},

	hideSlide: function(func){
		if ($type(this.options.hideFunction) === 'function') {
			this.options.hideFunction(this.slides[this.index], func);
		} else {
			this.slides[this.index].fade('out');
		}
		this.fireEvent('hide', this.index);
	}

});
