var Vroom = new Class({

	Implements: [Events, Options],

	options: {
		'auto': false,
		'autoDelay': 4000,
		'caption': false,
		'thumbs': true
	},

	initialize: function(element, options){
		this.setOptions(options);

		this.element = $(element);

		if(this.element.retrieve('vroom'))
			return this.element.retrieve('vroom');
		this.element.store('vroom', this);

		this.auto = false;
		this.current = -1;
		this.preloaded = false;
		this.createSlides();
		this.preloadSlides();

		this.caption = this.options.caption ? $(this.options.caption) : false;

		if(! this.options.auto) {
			this.element.on('click', this.next.bind(this));
			this.element.setStyle('cursor', 'pointer');
		}

		this.deactivate();

		return this;
	},

	activate: function(id){
		if(this.activated)
			return this;

		if(! this.preloaded) {
			this.addEvent('preload', this.activate.pass(id, this));
			return this;
		}

		this.activated = true;
		this.element.setStyle('border-width', '1px').fade('in');

		if(this.thumbs)
			this.thumbs.fade('hide').inject('header').fade('in');

		this.show(id ? id : 0);

		if(this.options.auto && this.slides.length > 1)
			this.auto = this.next.periodical(this.options.autoDelay, this);

		return this;
	},

	deactivate: function(){
		if(! this.activated)
			return this;

		this.activated = false;

		if(this.auto)
			$clear(this.auto);

		if(this.caption)
			this.caption.fade('hide');

		if(this.image) {
			this.image.dispose();
			this.image = null;
		}

		if(this.thumbs)
			this.thumbs.dispose().getChildren('li').removeClass('active').fade(0.3);

		this.current = -1;
		this.element
			.empty()
			.morph({
				'border-width': '0px',
				'height': '0px',
				'width': '0px'
			})
			.fade('out');

		return this;
	},

	createSlides: function(){
		this.slides = this.element.getChildren('img').map(function(img){
			return {
				'src': img.get('src'),
				'caption': img.get('title')
			};
		});

		this.element.empty();
	},

	preloadSlides: function(){
		this.preload = [];
		this.slides.each(function(slide){
			this.preload.push(slide.src);
		}, this);

		this.images = new Asset.images(this.preload, {
			onComplete: this.onPreload.bind(this)
		});
	},

	onPreload: function(){
		this.preloaded = true;

		if(this.options.thumbs)
			this.createThumbs();

		this.createFxs();
	},

	createThumbs: function(){
		this.thumbs = new Element('ul', {
			'class': 'thumbs'
		});

		for(var i = 0; i < this.images.length; i++) {
			var li = new Element('li')
				.adopt(
					this.images[i]
						.clone()
						.setStyles({ 'height': '', 'width': '' })
						.erase('height')
						.erase('width')
				)
				.fade(0.3)
				.inject(this.thumbs);

			li.addEvents({
				'click': this.show.pass(i, this),
				'mouseenter': (function(){ this.fade(1); }).bind(li),
				'mouseleave': (function(){ if(! this.hasClass('active')) this.fade(0.3); }).bind(li)
			});

			this.images[i].store('thumb', li);
		}

		this.thumbs.store('slideFx', new Fx.Tween(this.images[0].retrieve('thumb'), { property: 'margin-left'}));
	},

	createFxs: function(){
		this.images.each(function(image){
			image.store('hideFx', new Fx.Tween(image, { onComplete: image.dispose.bind(image) }));
			image.store('showFx', new Fx.Tween(image, { duration: 'long' }));
		});

		this.fireEvent('preload');
		this.removeEvents('preload');
	},

	show: function(id){
		if(! this.activated)
			return this;

		if(this.current == id)
			return this;

		if(! this.slides[id])
			return this;

		// make the old img exit, then remove it from the DOM
		if(this.image) {
			// thumb fading
			if(this.options.thumbs)
				this.image.retrieve('thumb').removeClass('active').fade(0.3);

			this.image.retrieve('showFx').cancel();
			this.image.retrieve('hideFx').start('left', - (this.image.getSize().x + 50));
		}

		this.current = id;

		// load the new image, on the right
		this.image = this.images[this.current]
			.setStyles({
				'left': '1000px',
				'position': 'absolute',
				'top': '10px'
			})
			.inject(this.element);

		// thumb sliding after the 4th image
		if(this.options.thumbs) {
			this.image.retrieve('thumb').fade(1).addClass('active');
			this.thumbs.retrieve('slideFx')
				.start(- this.thumbs.getChildren('li')[id > 3 ? id - 3 : 0].getPosition(this.thumbs.getChildren('li')[0]).x);
		}

		// animate the container, then the image
		imgSize = this.image.getSize();
		this.element.morph({
			'height': imgSize.y + 20,
			'width': imgSize.x + 20
		});

		this.image.retrieve('showFx').start('left', '10px');

		// animate the caption
		if(this.caption)
			this.caption.fade('hide').set('html', this.slides[this.current].caption).fade('in');

		return this;
	},

	next: function(){
		if(this.current < this.slides.length - 1)
			this.show(this.current + 1);
		else
			this.show(0);

		return this;
	},

	toElement: function(){
		return this.element;
	}
});

Element.implement({
	vroom: function(options) {
		return new Vroom(this, options);
	}
});
