/**
 * carousel.js - Carousel extension for Prototype JS library
 * --------------------------------------------------------
 *
 * v1.0, August 6th 2010
 *
 */
										
var Carousel = Class.create({
	initialize: function(wrapper, options) {
		
		// this lets users pass an element, a collection of elements, or a css query (as a 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;
		}
		
		// the container doesnt exist then return false
		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 3x faster when activating advance control
			reversingMultiplier: 3, // make the carousel scroll 2x faster when activating reverse control
			wrapperClass: 'carousel-wrapper'
		}
		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;

		
		// set some styles on the container and wrapper
		this.container.setStyle({overflow: 'hidden', position: 'relative'});
		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()
	{
		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;
		
		this.wrapper.childElements().each(function(el){
		
		
			if(this.options.direction == 'horizontal')
			{
				dimension += el.getWidth();
				
				dimension += parseInt(el.getStyle('margin-left'));
				dimension += parseInt(el.getStyle('margin-right'));
				
				dimension += parseInt(el.getStyle('padding-left'));
				dimension += parseInt(el.getStyle('padding-right'));
				
				dimension += parseInt(el.getStyle('border-left-width'));
				dimension += parseInt(el.getStyle('border-right-width'));
			}
			else
			{
				dimension += el.getHeight();
				
				dimension += parseInt(el.getStyle('margin-top'));
				dimension += parseInt(el.getStyle('margin-bottom'));
				
				dimension += parseInt(el.getStyle('padding-top'));
				dimension += parseInt(el.getStyle('padding-bottom'));
				
				dimension += parseInt(el.getStyle('border-left-top'));
				dimension += parseInt(el.getStyle('border-right-bottom'));
			}
		
		}.bind(this));
		
		if(this.options.direction == 'horizontal')
		{
			this.wrapper.setStyle({width: '15000px'});
		}
		else
		{
			this.wrapper.setStyle({height: '15000px'});
		}
		
		return dimension;
	}
});
