/**
 * carousel.js - Carousel extension for Prototype JS library
 * --------------------------------------------------------
 *
 * v1.2, June 30th 2011
 *
 */
										
var Carousel = Class.create({
	initialize: function(wrapper, options) {
		
		// Accepts an element, a collection of elements, or a css query string.
		if (wrapper instanceof Array){
			wrapper.each(function(el){ new Carousel(el, options); });
			return true;
		} else if(typeof(wrapper) == 'string') {
			new Carousel($$(wrapper), options);
			return true;
		} else if (!wrapper) {
			return false;
		}
		
		this.options = {
			speed: 1, // pixels to move per frame
			pauseOnHover: true, // pause animation when the mouse moves over the container div
			direction: 'horizontal', // which direction to scroll, can be horizontal or vertical.
			directionControls: true, // displays controls which let the user manually advance/reverse the carousel
			fps: 30, // frames per second
			advancingMultiplier: 4, // make the carousel scroll 4x faster when activating advance control
			reversingMultiplier: 3, // make the carousel scroll 3x faster when activating reverse control
			wrapperClass: 'carousel-wrapper',
			height: 'auto',
			width: 'auto'
		}
		Object.extend(this.options, options || {}); 
		
		// set some class properties
		this.speed = this.options.speed;
		this.container = $(wrapper).wrap('div', { 'class': this.options.wrapperClass });
		
		this.wrapper = wrapper;
		
		var parentHeight = this.container.up().getHeight();

		// set some styles on the container and wrapper
		this.container.setStyle({overflow: 'hidden', position: 'relative', height: parentHeight+'px'});
		this.wrapper.setStyle({position: 'absolute'});
		
		// set the exact width/height of the wrapper container
		this.wrapperDimension = this.getWrapperDimensions();
			
		if (this.options.direction == 'horizontal'){
			var containerDimension  = this.container.getWidth();
			if(this.wrapperDimension <= containerDimension) return false;
			this.wrapper.setStyle({left: '-'+this.wrapperDimension+'px'});
		} else {
			var containerDimension  = this.container.getHeight();
			if(this.wrapperDimension <= containerDimension) return false;
			this.wrapper.setStyle({top: '-'+this.wrapperDimension+'px'});
		}
		
		this.wrapper.innerHTML+= this.wrapper.innerHTML + this.wrapper.innerHTML; // double up the content
		
		this.wrapper.observe('mouseover', function(){
			this.speed = 0;
		}.bind(this));
		
		this.wrapper.observe('mouseout', function(){
			this.speed = this.options.speed;
		}.bind(this));
		
		// create the direction controls
		if (this.options.directionControls) this.createDirectionControls();
		        
        this.distance = 0;
        this.interval = setInterval(this.frame.bind(this), Math.round(1000/this.options.fps));
	},
	
	frame: function()
	{
		if (!this.speed) return true;
		
		this.distance += this.speed;
		
		var offset = 0 - this.wrapperDimension - this.distance;
		
		if (this.options.direction == 'horizontal'){
			this.wrapper.setStyle({left: offset+'px'});
		} else {
			this.wrapper.setStyle({top: offset+'px'});
		}
		
		if (this.distance > this.wrapperDimension || this.distance < (0-this.wrapperDimension)){
			this.resetWrapperPosition();
		}

	},
	
	createDirectionControls: function()
	{
		var div1 = new Element('div', {'class': 'control-advance'});
		this.container.insert(div1);
		div1.hide();
		div1.innerHTML = '◄';
		div1.observe('mouseover', function(){ this.speed = (this.options.speed*this.options.advancingMultiplier);  }.bind(this));
		div1.observe('mouseout', function(){ this.speed = this.options.speed; }.bind(this));
		
		var div2 = new Element('div', {'class': 'control-reverse'});
		this.container.insert(div2);
		div2.hide();
		div2.innerHTML = '►';
		div2.observe('mouseover', function(){ this.speed = -(this.options.speed*this.options.reversingMultiplier); }.bind(this));
		div2.observe('mouseout', function(){ this.speed = this.options.speed; }.bind(this));
		
		this.container.observe('mouseout', function(){ 
			div1.hide();
			div2.hide();
		});
		
		this.container.observe('mouseover', function(){ 
			div1.show();
			div2.show();
		});
	},
	
	resetWrapperPosition: function()
	{
		this.distance = 0;
		
		if (this.options.direction == 'horizontal'){
			this.wrapper.setStyle({left: '-'+(this.wrapperDimension)+'px'});
		} else {
			this.wrapper.setStyle({top: '-'+(this.wrapperDimension)+'px'});
		}	
	},
	
	getWrapperDimensions: function()
	{
		var dimension = 0;
		var styles = [];
		this.wrapper.childElements().each(function(el){
		
			if (this.options.direction == 'horizontal'){
				dimension += el.getWidth();
				styles = ['margin-left', 'margin-right', 'padding-left', 'padding-right', 'border-left-width', 'border-right-width'];
			} else {
				dimension += el.getHeight();
				styles = ['margin-top', 'margin-bottom', 'padding-top', 'padding-bottom', 'border-top-width', 'border-bottom-width'];
			}
			
			for(var i = 0; i < styles.length; i++){
				var style_val = parseInt(el.getStyle(styles[i]));
				
				if (!isNaN(style_val)) 
				{
					dimension += style_val; 
				}
			}
		
		}.bind(this));
				
		if (this.options.direction == 'horizontal'){
			this.wrapper.setStyle({width: (dimension*3)+'px'});
		} else {
			this.wrapper.setStyle({height: (dimension*3)+'px'});
		}
		
		return dimension;
	}
});
