var Loop=new Class({loopCount:0,isStopped:true,isLooping:false,loopMethod:$empty,setLoop:function(fn,delay){if(this.isLooping)this.stopLoop();this.loopMethod=fn;this.loopDelay=delay||3000;return this;},stopLoop:function(){this.isStopped=true;this.isLooping=false;$clear(this.periodical);return this;},startLoop:function(delay){if(this.isStopped){var delay=(delay)?delay:this.loopDelay;this.isStopped=false;this.isLooping=true;this.periodical=this.looper.periodical(delay,this);}
return this;},resetLoop:function(){this.loopCount=0;return this;},looper:function(){this.loopCount++;this.loopMethod(this.loopCount);return this;}});


var vCaroussel = new Class({
	
	Implements:  [Options, Loop], 
	
	//variables setup
	slides_container: null,
	images_container: null,
	slides: [],
	images: [],
	slideClass: null,
	imageClass: null,
	isSliding: 0,					//flag for animation/click prevention
	direction: -1,					//flag for direction (down(-1)/up(1))
	itemNum: 0,						//Current item number	
	numItens: 0,
	slide_height: 0,
	slide_width: 0,
	transitionTime: 0, 		   		//Transition time (1 second = 1000)	
	scroll_up: null,				// Scroll up div
	scroll_down: null,				// Scroll down div
	isPaused: false,
	prev_slide_out: null,
	previous_direction: 1,
	active_image: 0,
	transition_type: null,
	numVisibleslides: 0,
	slices : [],
	containerSize: 0,
    effects: {
		horizontal: ['fade', 'fold', 'sliceLeftUp', 'sliceLeftDown' , 'sliceLeftRightDown', 'sliceLeftRightUp', 'sliceRightDown', 'sliceRightUp'],
		vertical: ['fade','fold','sliceDownLeft','sliceDownRight','sliceUpDownLeft','sliceUpDownRight','sliceUpLeft','sliceUpRight']
	},

	
	//options
	options: {
	direction: 1,					//option for direction (down(-1)/up(1))
	slideTimer: 2000,  			    //Time between slides (1 second = 1000), a.k.a. the interval duration
	scrollTimer: 500,				//Time between slides during scrolling
	transitionTime: 500, 		    //Transition time (1 second = 1000)
	scroll_controls: true,			//Flag for scroll controls
    effect: 'fade',
	slices: 15,
	transition_orientation: 'vertical',
	pause_on_mouseover: true,
	active_image: 0,
	images_slide: true,
	transition_type: 'linear',
	scrool_up: null,
	scrool_down: null,
	scroll_height: 0,
	orientation: 'vertical'
	},	
	
	initialize: function(slides_container,images_container, slideClass, numVisibleslides,options){
		
		this.setOptions(options);
		this.active_image = this.options.active_image;
		this.numVisibleslides = numVisibleslides;
		this.slides_container = slides_container;
		this.slides_container.setStyle('overflow', "hidden");  
		this.slideClass = slideClass;
		this.slides = this.slides_container.getElements('.'+slideClass);
		for (var i=0; i< this.slides.length; i++){
			this.slides[i].addClass('vcaroussel_slide');
			this.slides[i].addEvents({ 'click': this.change_image.bind(this, i) }); 
		};
		this.numItens = this.slides.length;
		this.slide_height = this.slides[0].getSize().y;
		this.slide_width = this.slides[0].getSize().x;
		if (this.options.images_slide){
			this.images_container = images_container;
			this.containerSize = this.images_container.getSize();
			this.images_container.setStyle('overflow', "hidden");
			this.images_container.setStyle('position', "relative");
			this.images = this.images_container.getElements('img');	
			for (var i=0; i< this.images.length; i++){
				this.images[i].addClass('vcaroussel_image');
				this.images[i].setStyle('opacity', 0);
			};
		};
		
		if (this.options.orientation == 'horizontal'){
			this.slides_container.setStyle('width', this.slide_width*this.numItens);
		}
		
		this.createSlices();
		this.setBackgroundImage();
		this.images_container.setProperty('onclick', 'window.location ="'+this.images[this.active_image].get('url')+'";' );
		
		this.direction = this.options.direction;
		this.previous_direction	 = this.options.direction;
		this.transitionTime = this.options.transitionTime;	
		this.transition_type = this.options.transition_type;	
		this.setLoop(this.slideIt, this.options.slideTimer);
		this.active_image = this.options.active_image; 
		
		if (this.slides.length > numVisibleslides){
			if (this.options.pause_on_mouseover){
				this.slides_container.addEvents({ 'mouseenter': this.stop.bind(this), 'mouseleave': this.start.bind(this) });
				this.images_container.addEvents({ 'mouseenter': this.stop.bind(this), 'mouseleave': this.start.bind(this) });	
			}
			if (this.direction == -1) {	this.increment(); };
			this.startLoop(this.options.slideTimer);
			if (this.options.scroll_controls){
				this.iniciate_scroll_controls();			
			};
		}		
		else{
			this.setLoop(this.changeIt, this.options.slideTimer);
			this.startLoop(this.options.slideTimer);
		}
	},

	slideIt: function () {
		if (this.prev_slide_out) { this.prev_slide_out.destroy();}
		this.slide_out = this.slides[this.itemNum];
		this.prev_slide_out = this.slide_out;
		if (this.direction == 1) {
			if (this.options.orientation == 'vertical'){
				this.move_up(this.itemNum);
			}
			else {
				this.move_left(this.itemNum);
			};
		};
		if (this.direction == -1) {
			if (this.options.orientation == 'vertical'){
				this.move_down(this.itemNum);
			}
			else {
				this.move_right(this.itemNum);
			};
		};		
		this.increment(); 
	},

	changeIt: function () {
		this.increment(); 
		this.change_image(this.itemNum);
	},
		
	move_up: function(itemNum){
		this.slides[itemNum] = this.slide_out.clone().inject(this.slides_container,'bottom');
		this.slides[itemNum].addEvents({ 'click': this.change_image.bind(this, itemNum) });
		this.slide_out.get('tween', {property: 'margin-top', link: 'cancel', transition: this.transition_type, duration: this.transitionTime }).start(-this.slide_height);	
		if ((!this.isPaused)&&(this.options.images_slide)){ this.change_image(itemNum); };
	},

	move_down: function(itemNum){
		this.slides[itemNum] = new Element('div', { 
								'class': this.slideClass+' vcaroussel_slide', 
								'styles': { 'margin-top': -this.slide_height+'px'} 
								});
		this.slides[itemNum].inject(this.slides_container,'top');
		this.slides[itemNum].innerHTML = this.slide_out.innerHTML;
		this.slides[itemNum].addEvents({ 'click': this.change_image.bind(this, itemNum) });
		this.slides[itemNum].get('tween', {property: 'margin-top', link: 'cancel', transition: this.transition_type, duration: this.transitionTime }).start(0);	
		if ((!this.isPaused)&&(this.options.images_slide)){ 
			b = itemNum-(this.numItens - this.numVisibleslides);
			if ( b < 0 ) { b = this.numItens + b; };
			this.change_image(b);
		};
	},

	move_left: function(itemNum){
		this.slides[itemNum] = this.slide_out.clone().inject(this.slides_container,'bottom');
		this.slides[itemNum].addEvents({ 'click': this.change_image.bind(this, itemNum) });
		this.slide_out.get('tween', {property: 'margin-left', link: 'cancel', transition: this.transition_type, duration: this.transitionTime }).start(-this.slide_width);	
		if ((!this.isPaused)&&(this.options.images_slide)){ this.change_image(itemNum); };	
	},

	move_right: function(itemNum){
		this.slides[itemNum] = new Element('div', { 
								'class': this.slideClass+' vcaroussel_slide', 
								'styles': { 'margin-left': -this.slide_width+'px'} 
								});
		this.slides[itemNum].inject(this.slides_container,'top');
		this.slides[itemNum].innerHTML = this.slide_out.innerHTML;
		this.slides[itemNum].addEvents({ 'click': this.change_image.bind(this, itemNum) });
		this.slides[itemNum].get('tween', {property: 'margin-left', link: 'cancel', transition: this.transition_type, duration: this.transitionTime }).start(0);	
		if ((!this.isPaused)&&(this.options.images_slide)){ 
			b = itemNum-(this.numItens - this.numVisibleslides);
			if ( b < 0 ) { b = this.numItens + b; };
			this.change_image(b);
		};
	},

	
	scroll: function (movement) {
		
		this.isPaused = true;
		this.stopLoop();
		this.resetLoop();
		this.transition_type = 'linear'
		if (this.previous_direction != movement ) {
			this.direction = movement;
			this.previous_direction = this.direction;
			this.increment();
		};
		if (this.direction != movement) {
			this.direction = movement;
			this.previous_direction = this.direction;	
		};
		this.transitionTime = this.options.scrollTimer;
  		this.startLoop(this.options.scrollTimer);
	},	

	
	setBackgroundImage: function(){
		this.images_container.setStyle('background-image','url('+this.images[this.active_image].get('src') +')');	
	},

    change_image: function(itemNum){
		if(itemNum == this.active_image) { return; }
		if(this.isSliding == 1) { return; }
		this.isSliding = 1;
		this.setBackgroundImage();
				
		//Set new slice backgrounds
		var timeBuff = 0;
		var timeBuff_increment = this.options.transitionTime/this.options.slices;
		var slices = this.slices;
		var orientation = this.options.transition_orientation;
		
        slices.each(function(slice, i){
			var position =  slice.retrieve('position');

            slice.setStyles({
                background: 'url('+this.images[itemNum].get('src')+') no-repeat -'+ position.left +'px '+ position.top*-1 +'px',
                opacity: 0
            });
			
			var property = orientation == 'horizontal' ? 'width' : 'height';

			slice.setStyle(property, 0);
			
        }, this);
    

		var effect = this.options.effect;

		if(effect == 'random') {
            effect = this.effects[this.options.transition_orientation].getRandom();
        }

		// vertical effects
        if(['sliceDownRight', 'sliceDownLeft'].contains(effect)) {
            if(effect == 'sliceDownLeft') {
                slices = slices.reverse();
            }

            slices.each(function(slice, i){
                slice.setStyle('top', 0);

                this.animate.delay(100 + timeBuff, this, [slice, 'height', this.containerSize.y, i]);
                timeBuff += timeBuff_increment;
            }, this);
        }
        else if(['sliceUpRight', 'sliceUpLeft'].contains(effect)) {
            if(effect == 'sliceUpLeft') {
                slices = slices.reverse();
            }

            slices.each(function(slice, i){
                var fx = slice.retrieve('fxInstance');
                
                slice.setStyle('bottom', 0);

                this.animate.delay(100 + timeBuff, this, [slice, 'height', this.containerSize.y, i]);
                timeBuff+= timeBuff_increment;
            }, this);
        }
        else if(['sliceUpDownRight', 'sliceUpDownLeft'].contains(effect)) {
            if(effect == 'sliceUpDownLeft') {
                slices = slices.reverse();
            }

            slices.each(function(slice, i){
                if(i%2 == 0) {
                    slice.setStyle('top', 0);
                }
                else {
                    slice.setStyle('bottom', 0);
                }

                this.animate.delay(100 + timeBuff, this, [slice, 'height', this.containerSize.y, i]);
                timeBuff+= timeBuff_increment;
            }, this);
        }

		// horizontal effects		
		else if(['sliceLeftUp', 'sliceLeftDown' , 'sliceRightDown', 'sliceRightUp'].contains(effect)) {
			if(effect == 'sliceLeftUp' || effect == 'sliceRightUp') {
                slices = slices.reverse();
            }
			
			if(effect == 'sliceRightDown' || effect == 'sliceRightUp') {
				slices.setStyle('right', 0);
			}
			else {
				slices.setStyle('left', 0);
			}

            slices.each(function(slice, i){    
                this.animate.delay(100 + timeBuff, this, [slice, 'width', this.containerSize.x, i]);

                timeBuff+= timeBuff_increment;
            }, this);
		}
		else if(['sliceLeftRightDown', 'sliceLeftRightUp'].contains(effect)) {
            if(effect == 'sliceLeftRightUp') {
                slices = slices.reverse();
            }

            slices.each(function(slice, i){
                if(i%2 == 0) {
                    slice.setStyle('left', 0);
                }
                else {
                    slice.setStyle('right', 0);
                }

                this.animate.delay(100 + timeBuff, this, [slice, 'width', this.containerSize.x, i]);
                timeBuff+= timeBuff_increment;
				
            }, this);
        }

		// horizontal or vertical		
        else if(effect == 'fold') {
            slices.each(function(slice, i){
				if(orientation == 'horizontal') {
					var property = 'height';
					var to = slice.getHeight();
	
					slice.setStyles({
						height: 0,
						width: this.containerSize.x
					});
				}
				else {
					var property = 'width';
					var to = slice.getWidth();
	
					slice.setStyles({
						height: this.containerSize.y,
						top: 0,
						width: 0
					});
				}
				this.animate.delay(100 + timeBuff, this, [slice, property, to, i]);	
                timeBuff+= timeBuff_increment;
            }, this);
        }
        else  // if(effect == 'fade')
        {
            slices.each(function(slice, i){
				if(orientation == 'horizontal') {
					slice.setStyle('width', this.containerSize.x);
				}
				else {
					slice.setStyle('height', this.containerSize.y);
				}
                this.animate.delay(100, this, [slice, null, null, i]);
            }, this);
        }
		this.active_image = itemNum;
		this.images_container.setProperty('onclick', 'window.location ="'+this.images[this.active_image].get('url')+'";' );	
    },
    
    animate: function(slice, property, to,i)
    {
        var fx = slice.retrieve('fxInstance');
        var styles = {
            opacity: 1    
        };
		styles[property] = to;
		if (i == this.options.slices-1) {
			fx.start(styles).chain(function(){ this.isSliding = 0; }.bind(this));
		}
		else {
			fx.start(styles);
		}
			
    },
	
    createSlices: function() {
		var sliceSize = {
			x: (this.images_container.getWidth()/this.options.slices).round(),
			y: (this.images_container.getHeight()/this.options.slices).round()
		};

        this.options.slices.each(function(i){

            var slice = new Element('div', {
                'class': 'vcaroussel_slice'
            }).inject(this.images_container);

			var position = {
				left: this.options.transition_orientation == 'vertical' ? sliceSize.x*i : 0,
				top: this.options.transition_orientation == 'horizontal' ? sliceSize.y*i : 0
			};

			// set size & position
			if(this.options.transition_orientation == 'horizontal')
			{
				slice.setStyles({
					height: i == this.options.slices-1 ? this.images_container.getHeight()-(sliceSize.y*i) : sliceSize.y,
                    top: position.top,
                    width: '100%'
                });
			}
			// if vertical
			else
			{
				slice.setStyles({
					left: position.left,
                    width: i == this.options.slices-1 ? this.images_container.getWidth()-(sliceSize.x*i) : sliceSize.x
                });
			}
            slice.store('fxInstance', new Fx.Morph(slice, {
                duration: this.options.transitionTime
            })).store('position', position);
        }, this);
		this.slices = this.images_container.getElements('.vcaroussel_slice');    
    },
	
	increment: function(){
	    this.itemNum = this.itemNum + this.direction;
		if ( this.itemNum >= this.numItens ) { this.itemNum = 0;};
	    if ( this.itemNum < 0 ) { this.itemNum = this.numItens-1; };	
	},

	start: function(){
		this.stopLoop();
		this.resetLoop();
		this.isPaused = false;
		this.transition_type = this.options.transition_type;
		if ((this.previous_direction == this.direction) && (this.options.direction != this.previous_direction ) ) {
			this.direction = this.options.direction;
			this.previous_direction = this.direction;
			this.increment();
		};
		if (this.direction != this.options.direction) {
			this.direction = this.options.direction;
			this.previous_direction = this.direction;	
		};
		this.transitionTime = this.options.transitionTime;
		this.startLoop(this.options.slideTimer);
	},
	
	stop: function(over){
		if (!this.isPaused){
			this.stopLoop();
			this.resetLoop();
			this.isPaused = true;
		};
	},
	
	iniciate_scroll_controls: function(){
		var slides_container_size = this.slides_container.getSize();
		var self = this;
		var scroll_width = slides_container_size.x;
		if (this.options.scroll_height) {
			scroll_height = this.options.scroll_height;
		}
		else{
			scroll_height = (this.slide_height)/3;
		}
		var scroll_margin = slides_container_size.y - scroll_height;
		if (this.options.scrool_up) {
			this.scrool_up = this.options.scrool_up;
		}
		else{
			this.scrool_up = new Element('div', {
				 			'class': 'vcaroussel_scroll_button vcaroussel_scroll_up',
						    'styles': { 'width': scroll_width+'px', 'height': scroll_height+'px'}
							});
			this.scrool_up.inject(this.slides_container,'top');				
		};
		if (this.options.scrool_down) {
			this.scrool_down = this.options.scrool_down;
		}
		else{
			this.scrool_down = new Element('div', {
							'class': 'vcaroussel_scroll_button vcaroussel_scroll_down',
						    'styles': { 'width': scroll_width+'px', 'height': scroll_height+'px', 'margin-top':scroll_margin+'px' }
							});
			this.scrool_down.inject(this.slides_container,'top');				
		};
		this.scrool_up.addEvents( { 'mouseenter': this.scroll.bind(this,-1), 'mouseleave': function(){ self.isPaused=false; self.stop(); } });	
		this.scrool_down.addEvents({ 'mouseenter': this.scroll.bind(this,1), 'mouseleave': function(){ self.isPaused=false; self.stop(); } });
	}	
	
});


