/*jslint onevar: true, undef: true, nomen: true, browser: true, maxerr: 50, indent: 4 */
/*global Ext HoverFade */

var Carouse = function (config) {
	Ext.apply(this, config);
	this.el = Ext.get(this.el);
	if (!this.height) {
		this.height = 'auto';
	}
	else if (typeof this.height === 'number') {
		this.height = this.height + 'px';
	}

	this.slideSize = this.width + 2 * this.slideGap;
	// create a wrapper for the list
	this.wrap = this.el.wrap({ tag: 'div', cls: 'carouse' });
	// create the inner 'stage'
	this.stage = this.el.wrap({tag: 'div', cls: 'carouse-stage' });
	this.stage.setStyle({
		width: this.slideSize + 'px',
		height: this.height
	});
	// get a handle on the slides
	this.slides = this.el.select('> li');
	// set the parent big enough to hold them all
	this.numSlides = this.slides.getCount();
	this.lastSlide = this.numSlides - 1;
	this.el.addClass('carouse-slides');
	this.el.setStyle({
		width: (this.slideSize * this.numSlides) + 'px',
		height: this.height
	});
	// set each slide to the right size
	this.slides.addClass('slide').setStyle({
		width: this.width + 'px',
		height: this.height,
		marginLeft: this.slideGap + 'px',
		marginRight: this.slideGap + 'px'
	});
	this.slides.each(function (el, self, idx) {
		el.setLeft(this.slideSize * idx);
		el.addClass('carouse-slide-' + idx);
	}, this);
	// Add the next/prev links
	if (this.prevImage) {
		this.prev = this.wrap.insertFirst({ tag: 'img', src: this.prevImage });
		if (this.prevImageHover) {
			this.prev = HoverFade(this.prev, this.prevImageHover);
		}
		this.prev.addClass('carouse-prev');
		this.prev.on('click', this.prevSlide, this);
	}
	if (this.nextImage) {
		this.next = this.wrap.insertFirst({ tag: 'img', src: this.nextImage });
		if (this.nextImageHover) {
			this.next = HoverFade(this.next, this.nextImageHover);
		}
		this.next.addClass('carouse-next');
		this.next.on('click', this.nextSlide, this);
	}
	// index?
	if (this.showIndex) {
		this.index = this.wrap.insertFirst({ tag: 'ul', cls: 'carouse-index' });
		this.slides.each(function (el, self, idx) {
			this.index.createChild({
				tag: 'li',
				html: (idx + 1).toString(),
				cls: 'carouse-index-' + idx
			}).on('click', this.updateSlide.createDelegate(this, [idx]), this);
		}, this);
	}
	// Check if the anchor is a child of ours
	this.currentSlide = 0;
	if (document.location.hash) {
		var i, current = this.el.down(document.location.hash);
		if (current) {
			for (i = 0; i < this.numSlides; i++) {
				if (current.hasClass('carouse-slide-' + i)) {
					this.currentSlide = i;
					break;
				}
			}
		}
	}
	this.updateSlide(this.currentSlide);
	if (this.autoScroll) {
		if (typeof this.autoScroll === 'number') {
			this.autoScroll = {
				interval: this.autoScroll
			};
		}
		if (typeof this.autoScroll !== 'object') {
			this.autoScroll = {};
		}
		Ext.applyIf(this.autoScroll, {
			run: this.doAutoScroll,
			scope: this,
			interval: this.autoScrollSpeed || 4000
		});
		Ext.TaskMgr.start(this.autoScroll);
		if (this.scrollPause == 'over') {
			this.stage.on('mouseenter', function () {
				this.pauseScroll = true;
			});
			this.stage.on('mouseleave', function () {
				this.pauseScroll = false;
			});
		} else if (this.scrollPause == 'index') {
			this.index.on('mouseenter', function () { this.pauseScroll = true; }, this);
			this.index.on('mouseleave', function () { this.pauseScroll = false; }, this);
		}
	}
};

Ext.extend(Carouse, Ext.util.Observable, {
	slideGap: 10,
	prevImage: '',
	prevImageHover: '',
	nextImage: '',
	nextImageHover: '',
	updateSlide: function (pos) {
		this.currentSlide = pos;
		var actions = {
			marginLeft: { 'to': -(this.slideSize * this.currentSlide), unit: 'px' }
		};
		if (this.height === 'auto') {
			actions.height = { 'to': this.el.select('.slide').item(pos).getHeight() };
		}
		this.el.stopFx().animate(
			actions,
			1, // duration
			null, // callback
			'easeBothStrong', // easing method
			'run'
		);
		if (this.showIndex) {
			this.index.down('.carouse-index-' + pos).radioClass('carouse-index-selected');
		}
	},
	prevSlide: function (wrap) {
		var end = this.currentSlide === 0;
		if (!end || wrap) {
			this.updateSlide(end ? this.lastSlide : this.currentSlide - 1);
		}
		return this.currentSlide === 0;
	},
	nextSlide: function (wrap) {
		var end = this.currentSlide === this.lastSlide;
		if (!end || wrap) {
			this.updateSlide(end ? 0 : this.currentSlide + 1);
		}
		return this.currentSlide === this.lastSlide;
	},
	doAutoScroll: function () {
		if (this.pauseScroll === true) { return; }
		var dir = this.autoDirection === 'reverse',
		    mode = this.autoScrollMode === 'bounce',
		    end = this[dir ? 'prevSlide' : 'nextSlide'](!mode);
		if (mode && end) {
			this.autoDirection = dir ? 'forward' : 'reverse';
		}
	}
});

