var Slides = Class.create();

Slides.prototype = {
	// Slides methods:
	// initialize: 	Sets up the initial periodical executor that will allow us to move
	// 							the arrow and flip between different slides
	// stop: Stops the periodical executor and therefore stops the slides
	initialize : function(settings) {
		if (settings) { Object.extend(this.settings, settings); }
		
		var controlElements = $(this.settings.slideControlElement).childElements();
		for(i=0; i<controlElements.length; i++) {
			if(controlElements[i].identify()==this.settings.slideControlStatus) { 
				controlElements.splice(i, 1);	
				break;
			}
		}
		
		var slideElements = $(this.settings.slidePane).childElements();
		if(controlElements.length != slideElements.length) { throw this.slideLengthMismatch(controlElements, slideElements) }
		
		controlElements.first().addClassName('current');
		slideElements.first().addClassName('current');
		slideElements.first().show();
		
		this.controlElements = controlElements;
		this.slideElements = slideElements;
	},
	
	setPe : function(pe) {
		this.slidesPe = pe;
		return true;
	},
	
	stop : function() {
		this.slidesPe.stop();
	},
	
	advanceSlide : function() {
		numSlides = this.controlElements.length;
		currIdx = this.currIdx();
		nextIdx = (i+1 == numSlides) ? 0 : i+1;
		
		[this.controlElements[currIdx], this.slideElements[currIdx]].invoke('removeClassName', 'current');
		[this.controlElements[nextIdx], this.slideElements[nextIdx]].invoke('addClassName', 'current');
		
		coordDiff = this.generateCoordinateDifferences(currIdx, nextIdx);
		return this.animateMove(coordDiff[0], coordDiff[1], currIdx, nextIdx);
	},
	
	move : function(e) {
		this.stop();
		currNode = e.parentNode;
		currIdx = this.currIdx();
		
		numSlides = this.controlElements.length;
		for(i=0; i<numSlides; i++) {
			if(this.controlElements[i] == currNode) { var nextIdx = i; break; }
		}
		
		[this.controlElements[currIdx], this.slideElements[currIdx]].invoke('removeClassName', 'current');
		[this.controlElements[nextIdx], this.slideElements[nextIdx]].invoke('addClassName', 'current');
		
		coordDiff = this.generateCoordinateDifferences(currIdx, nextIdx);
		return this.animateMove(coordDiff[0], coordDiff[1], currIdx, nextIdx);
	},
	
	animateMove : function(xDiff, yDiff, currIdx, nextIdx) {
		new Effect.Parallel([
			new Effect.Move($(this.settings.slideControlStatus), { sync:true, x: xDiff, y: yDiff, mode: 'relative' }),
			new Effect.Fade($(this.slideElements[currIdx]), {sync:true}),
			new Effect.Appear($(this.slideElements[nextIdx]), {sync:true})
		]);
	},
	
	generateCoordinateDifferences : function(currIdx, nextIdx) {
		currCoordinates = this.controlElements[currIdx].cumulativeOffset();
		nextCoordinates = this.controlElements[nextIdx].cumulativeOffset();
		
		xDiff = nextCoordinates[0] - currCoordinates[0];
		yDiff = nextCoordinates[1] - currCoordinates[1];
		
		return [xDiff, yDiff]
	},

	currIdx : function() {
		numSlides = this.controlElements.length;
		for(i=0; i<numSlides; i++) {
			if(this.controlElements[i].hasClassName('current')) { currIdx = i; break; }
		}

		return currIdx;
	},
	
	settings : {
		slidePane: 'slides_pane',
		slideControlElement: 'slides_control',
		slideControlStatus: 'homepage_callout_arrow',
		transitionTime: 1,
		slideTime: 3
	},
	
	slideLengthMismatch : function(controlElements, slideElements) {
		return 'SlideLengthMismatch: Expected same number of slideElements and controlElements, found ' + 
			slideElements.length + ' slide elements, but found ' + controlElements.length + ' control elements.'
	}
}