var Sm = Sm || {};

Sm.Rotator = Class.create({
	initialize: function(rotator, bubble, image, caption, arrows) {
		this.images = new Array();
		this.bubbles = new Array();
		this.captions = new Array();
		this.bubbleUl = new Element('ul');
		this.currentImage = null;
		this.lastImage = null;
		this.highestZ = 1;
		
		// store elements
		this.rotator = $(rotator);
		this.image = $(image);
		this.caption = $(caption);

		// Rearrange DOM
		$(bubble).insert(this.bubbleUl);
		this.arrows = $(arrows);
		
		// set necessary styles
		this.rotator.setStyle({ 'position': 'relative' });

		// detect image inside rotator and use it as the first
		var domImage = this.image.select('img')[0];
		if (domImage) {
			// First image is positioned relatively
			domImage.setStyle({ position: 'relative', zIndex: this.highestZ++ });
			if (this.caption) this._addImage(domImage, this.caption.innerHTML);
			this._setCurrentImage(0);
		}
		
		// setup arrows
		var next = this.arrows.select('.next')[0];
		if (next != undefined) next.observe('click', this._incrementImage.bindAsEventListener(this, 1));
		var prev = this.arrows.select('.prev')[0];
		if (prev != undefined) prev.observe('click', this._incrementImage.bindAsEventListener(this, -1));
	},
	
	_incrementImage: function(event, step) {
		this._setCurrentImage((this.currentIndex + this.images.length + step) % this.images.length);
		event.stop();
	},
	
	addImage: function(url, caption) {
		this._addImage(new Element("img", { src: url }), caption);
	},
	
	_addImage: function(image, caption) {
		// Setup image
		if (this.images.length > 0) {
			// We are adding an image that does not exist in the DOM yet
			var pos = this.images[0].positionedOffset();
			image.
				setStyle({ 'position': 'absolute', 'zIndex': 0 }).
				setStyle({ left: pos[0] + 'px', top: pos[1] + 'px' }).
				setOpacity(0);
			this.image.insert(image);			
		}
		this.images.push(image);		
		
		// Record caption
		this.captions.push(caption);
		
		// Setup bubble for image
		var bubble = new Element('li').update('&bull;');
		bubble.observe('click', this._setCurrentImage.bind(this, this.images.length - 1));
		this.bubbles.push(bubble);
		this.bubbleUl.insert(bubble);
	},
	
	_setCurrentImage: function(index) {
		// do nothing if we haven't changed index
		if (index == this.currentIndex) return null;
		
		// do the switch
		if (this.currentImg) {
			// Animate the transition
			var nextImage = this.images[index];
			nextImage.setOpacity(0).setStyle({ zIndex: this.highestZ++ });
			new Effect.Opacity(nextImage, { from: 0.0, to: 1.0, duration: 0.15 })
		} else {
			// set the current image
			this.currentImg = this.images[index];
		}
		
		// set index
		this.currentIndex = index;			

		// set caption
		if (this.caption) this.caption.update(this.captions[index]);
		
		// manage bubbles and arrows
		var selected = this.bubbleUl.select(".selected")[0];
		if (selected != undefined) selected.removeClassName('selected');
		this.bubbles[index].addClassName('selected');		
	}
});
