window.addEvent('domready',function(){
	/*
	$$('div.gallery').each(function(holder){
		new scrollGallery(holder);
	});
	*/
	$$('div.carousel').each(function(holder){
		new scrollGallery(holder,{
			holder:'div.reasons-holder'
		});
	});
	$$('div.gallery').each(function(holder){
		new slideshow(holder);
	});
});

var slideshow = new Class({
	Implements : [Options, Events],
	options:{
		slides:'ul.slides > li',
		nextBtn:false,
		prevBtn:false,
		pagingHolder:'div.switcher',
		pagingTag:'a',
		slidesActiveClass:'active',
		pagingActiveClass:'active',
		autoHeight:true,
		createPaging:true,
		autoPlay:true,
		dynamicLoad:false,
		imgAttr:'alt',
		effect:Browser.safari ? 'fade' : 'slideX',
		startSlide:false,
		switchTime:5000,
		animSpeed:700
	},
	initialize:function(element, options) {
		this.mainHolder = $(element);
		this.setOptions(options);
		this.slides = this.mainHolder.getElements(this.options.slides);		
		if (this.options.nextBtn) this.nextBtn = this.mainHolder.getElement(this.options.nextBtn);
		if (this.options.prevBtn) this.prevBtn = this.mainHolder.getElement(this.options.prevBtn);
		
		this.previous = -1;
		this.loadingFrame = 1;
		this.busy = false;
		this.direction = 1;
		this.timer;
		this.pagingArray = new Array;
		this.loadArray = new Array;
		this.preloader = new Array;
		this.slidesParent = this.slides[0].getParent();
		this.slideW = this.slidesParent.getSize().x;
		this.slideH = this.slidesParent.getSize().y;
		this.autoPlay = this.options.autoPlay;
		
		this.initStartSlide();
		this.initPaging();
		this.setStyles();
		this.bindEvents();
		this.showSlide();
	},
	
	initStartSlide:function(){
		if (this.options.startSlide) this.current = this.options.startSlide
		else {
			var active = -1;
			for(var i = 0; i< this.slides.length-1; i++) {
				if (this.slides[i].hasClass(this.options.slidesActiveClass)) {
					active = i;
					break;						
				}
			}
			if (active != -1) this.current = active;
			else this.current = 0;
		}
	},
	
	initPaging:function(){
		this.pagingHolder = this.mainHolder.getElements(this.options.pagingHolder);
		
		if (this.options.createPaging) {
			this.pagingHolder.each(function(paging,i){
				paging.empty();
				var list = new Element('ul');
				var html = '';
				for (var i = 0; i < this.slides.length; i++) {
					html += '<li><a href="#">' + (i + 1) + '</a></li>';
				}
				list.innerHTML = html;
				list.inject(paging);
			}.bind(this));
		}
		
		this.pagingHolder.each(function(paging){
			this.pagingArray.push(paging.getElements(this.options.pagingTag))
		}.bind(this));
	},
	
	setStyles:function(){
		//loader
		if (this.options.dynamicLoad) {
			this.loader = new Element('div').addClass('loader');
			this.loaderDiv = new Element('div').inject(this.loader);
			this.loader.inject(this.slidesParent);
		}
		
		//slides
		this.slides.each(function(slide,i){
			if (this.options.effect == 'fade') {
				if (i != this.current) slide.setStyles({display:'none'});
				else slide.setStyles({display:'block'});
			} else if (this.options.effect == 'slideX'){
				if (i != this.current) slide.setStyles({display: 'none',left:-this.slideW});
				else slide.setStyles({display:'block',left:0});
			} else if (this.options.effect == 'slideY'){
				if (i != this.current) slide.setStyles({display:'none',top:-this.slideH});
				else slide.setStyles({display:'block',top:0});
			}
		}.bind(this));
		
		if (this.options.autoHeight) {
			this.slidesParent.setStyles({
				height:this.slides[this.current].getSize().y
			});
		}
	},
	
	bindEvents:function(){
		if (this.nextBtn) this.nextBtn.addEvent('click',function(){
			if (!this.busy) this.nextSlide();
			return false;
		}.bind(this));
		
		if (this.prevBtn) this.prevBtn.addEvent('click',function(){
			if (!this.busy) this.prevSlide();
			return false;
		}.bind(this));
		this.pagingArray.each(function(paging){
			paging.each(function(btn,i){
				btn.addEvent('click',function(){
					if (i != this.current && !this.busy) {
						this.previous = this.current;
						this.current = i;
						if (this.previous > i) this.direction = -1
						else this.direction = 1;
						this.showSlide();
					}
					return false;
				}.bind(this));
			}.bind(this));
		}.bind(this));
		
		if (this.options.dynamicLoad) this.loader.addEvent('click',this.abortLoading.bind(this));
	},
	
	nextSlide:function(){
		this.previous = this.current;
		if (this.current < this.slides.length-1) this.current++
		else this.current = 0;
		this.direction = 1;
		this.showSlide();
	},
	
	prevSlide:function(){
		this.previous = this.current;
		if (this.current > 0) this.current--
		else this.current = this.slides.length-1;
		this.direction = -1;
		this.showSlide();
	},
	
	showSlide:function(){
		if (this.previous == this.current) return; 
		var _current = this.current;
		this.busy = true;
		clearTimeout(this.timer);
		if (typeof this.loadArray[_current] != 'undefined' || !this.options.dynamicLoad) {
			//slide already loaded
			this.switchSlide();
		} else {
			//slide not loaded
			this.showLoading();
			var images = this.slides[this.current].getElements(this.options.dynamicLoad);
			if (images.length) {
				var counter = 0;
				images.each(function(img){
					var preloader = new Image;
					this.preloader.push(preloader);
					preloader.onload = function(){
						counter++;
						checkImages.apply(this);
					}.bind(this);
					preloader.onerror = function(){
						//ignore errors
						counter++;
						checkImages.apply(this);
					}.bind(this);
					preloader.src = img.getProperty(this.options.imgAttr);
				}.bind(this));
				
				function checkImages(){
					if (counter == images.length) {
						images.each(function(img){
							img.setProperty('src',img.getProperty(this.options.imgAttr));
						}.bind(this));
						successLoad.apply(this);
					}
				}
			} else successLoad.apply(this);
		}
		
		function successLoad(){
			this.loadArray[_current] = 1;
			this.hideLoading();
			this.switchSlide();
		}
	},
	
	switchSlide:function(){
		var obj = this;
		
		if (this.previous != -1) {
			var nextSlide = this.slides[this.current];
			var prevSlide = this.slides[this.previous];
			nextSlide.setStyles({display:'block'});
				
				
			if (this.options.effect == 'slideX'){
				this.slideW = this.slides[this.current].getSize().x;
				var nextFx = new Fx.Morph(nextSlide,{duration:this.options.animSpeed});
				var prevFx = new Fx.Morph(prevSlide,{duration:this.options.animSpeed,onComplete:callback.bind(this)});
				
				nextSlide.setStyles({left:this.slideW*this.direction})
				nextFx.start({left:0});
				prevFx.start({left:-this.slideW*this.direction});
			} else if (this.options.effect == 'slideY'){
				this.slideH = this.slides[this.current].getSize().y
				var nextFx = new Fx.Morph(nextSlide,{duration:this.options.animSpeed});
				var prevFx = new Fx.Morph(prevSlide,{duration:this.options.animSpeed,onComplete:callback.bind(this)});
				
				nextSlide.setStyles({top:this.slideH*this.direction});
				nextFx.start({top:0});
				prevFx.start({top:-this.slideH*this.direction});
			} else {
				var nextFx = new Fx.Morph(nextSlide,{duration:this.options.animSpeed,onComplete:function(){
					nextSlide.setStyles({opacity:'auto'});
				}});
				var prevFx = new Fx.Morph(prevSlide,{duration:this.options.animSpeed,onComplete:callback.bind(this)});
				nextSlide.setStyles({display:'block',opacity:0});
				nextFx.start({opacity:1});
				prevSlide.setStyles({opacity:1});
				prevFx.start({opacity:0});
			}
			
			if (this.options.autoHeight) {
				this.slideH = this.slides[this.current].getSize().y
				var parentFx = new Fx.Morph(this.slidesParent,{duration:this.options.animSpeed});
				parentFx.start({height:this.slideH});
			}
		} else {
			if (this.autoPlay) this.startAutoPlay();
			this.busy = false;
		}
		
		this.refreshStatus();
		
		function callback(){
			prevSlide.setStyles({display:'none'});
			if (this.autoPlay) this.startAutoPlay();
			this.busy = false;
		}
	},
	
	refreshStatus:function(){
		if (this.pagingArray.length) {
			this.pagingArray.each(function(paging){
				if (this.previous != -1) paging[this.previous].removeClass(this.options.pagingActiveClass);
				paging[this.current].addClass(this.options.pagingActiveClass);
			}.bind(this));
		}
		if (this.previous != -1) this.slides[this.previous].removeClass(this.options.pagingActiveClass);
		this.slides[this.current].addClass(this.options.pagingActiveClass);
	},
	
	showLoading:function(){
		this.loader.setStyles({display:'block'});
		clearInterval(this.loadingTimer);
		this.loadingTimer = setInterval(animateLoading.bind(this), 66);
		
		function animateLoading(){
			this.loaderDiv.setStyles({'top': this.loadingFrame * -40});
			this.loadingFrame = (this.loadingFrame + 1) % 12;
		}
	},
	
	hideLoading:function(){
		this.loader.setStyles({display:'none'});
		clearInterval(this.loadingTimer);
	},
	
	abortLoading:function(){
		this.busy = false;
		this.hideLoading();
		this.current = this.previous;
		for (var i = 0; i < this.preloader.length; i++) {
			this.preloader[i].onload = null;
			this.preloader[i].onerror = null;
		}
		if (this.autoPlay) this.startAutoPlay();
	},
	
	startAutoPlay:function(){
		clearTimeout(this.timer);
		this.timer = setTimeout(this.nextSlide.bind(this),this.options.switchTime);
	}
});

var scrollGallery = new Class({
	Implements : [Options, Events],
	options:{
		holder:'div.slides-holder', 
		slider:'>ul',
		slides:'>li',
		prevBtn:'a.prev',
		nextBtn:'a.next',
		pagingHolder:'div.switcher',
		pagingBtn:'a',
		createPaging:true,
		circleSlide:true,
		switchTime:5000,
		slideSpeed:700,
		autoSlide:false,
		startSlide:false,
		horizontal:true,
		step:false
	},
	initialize:function(element,options){
		// elems
		this.setOptions(options);
		this.mainHolder = $(element);
		this.holder = this.mainHolder.getElement(this.options.holder);
		this.slider = this.holder.getElement(this.options.slider)
		this.slides = this.slider.getElements(this.options.slides);
		this.prevBtn = this.mainHolder.getElement(this.options.prevBtn);
		this.nextBtn = this.mainHolder.getElement(this.options.nextBtn);
		//variables
		if (this.options.horizontal) this.slideSize = this.slides[0].getSize().x + parseInt(this.slides[0].getStyle('marginLeft'))+parseInt(this.slides[0].getStyle('marginRight'));
		else this.slideSize = this.slides[0].getSize().y + parseInt(this.slides[0].getStyle('marginTop'))+parseInt(this.slides[0].getStyle('marginBottom'));
		if (this.options.horizontal) this.visibleStep = Math.round(this.holder.getSize().x/this.slideSize);
		else this.visibleStep = Math.round(this.holder.getSize().y/this.slideSize);
		this.options.step ? this.step = this.options.step : this.step = this.visibleStep;
		this.options.startSlide ? this.current = Math.floor(this.options.startSlide/this.step) : this.current = 0;
		this.max = this.slides.length - this.visibleStep;
		this.stepCount = Math.ceil((this.slides.length-this.visibleStep)/this.step)+1;
		this.Fx = new Fx.Morph(this.slider,{duration:this.options.slideSpeed, onComplete:function(){
			this.autoPlay();
		}.bind(this)});
		this.current = -1;
		this.previous = -1;
		this.slides.length <= this.visibleStep ? this.disable = true : this.disable = false;
		if (this.disable) {
			this.nextBtn.setStyles({visibility:'hidden'});
			this.prevBtn.setStyles({visibility:'hidden'});
		} 
		//paging
		this.pagingHolder = this.mainHolder.getElements(this.options.pagingHolder);
		if (this.pagingHolder.length) this.pagingLength = Math.ceil(this.slides.length / this.step);
		
		if (this.pagingHolder.length) {
			this.pagingBtn = new Array;
			if (this.options.createPaging) {
				this.pagingHolder.each(function(obj,i){
					obj.empty();
					var list = new Element('ul');
					var html = '';
					for (var i = 0; i < this.pagingLength; i++) html += '<li><a href="#">' + (i + 1) + '</a></li>';
					list.innerHTML = html;
					list.inject(obj);
				}.bind(this));
			}
			this.pagingHolder.each(function(obj,i){
				this.pagingBtn[i] = obj.getElements(this.options.pagingBtn); 
				var stepCount = 0;
				this.pagingBtn[i].each(function(obj,j){
					var index = stepCount;
					obj.addEvent('click',function(){
						if (index != this.current && !this.disable) {
							this.showSlide(index);
						}
						return false;
					}.bind(this));
					stepCount += this.step;
				}.bind(this));
			}.bind(this));
		}
		
		//next & prev
		if (this.nextBtn) this.nextBtn.addEvent('click',function(){
			if (!this.disable) this.nextSlide();
			return false;
		}.bind(this));
		if (this.prevBtn) this.prevBtn.addEvent('click',function(){
			if (!this.disable) this.prevSlide();
			return false;
		}.bind(this));
		
		this.showSlide(this.options.startSlide,true);
		this.autoPlay();
	},
	nextSlide:function(){
		if (this.options.circleSlide && this.current == this.stepCount - 1) {
			this.previous = this.current;
			this.current = 0;
			this.move();
		}
		else if (this.current < this.stepCount - 1) {
				this.previous = this.current++
				this.move();
			}
	},
	prevSlide:function(){
		if (this.options.circleSlide && this.current == 0) {
			this.previous = this.current;
			this.current = this.stepCount - 1;
			this.move();
		}
		else if (this.current > 0) {
			this.previous = this.current--;
			this.move();
		}
	},
	move:function(instant){
		clearTimeout(this.timer);
		var direction = this.direction;
		var offset;
		if (this.step * this.current < this.max) offset = (this.step*this.current)*this.slideSize;
		else offset = this.max * this.slideSize;
		if (instant) {
			if (this.options.horizontal) this.slider.setStyles({marginLeft:-offset});
			else this.slider.setStyles({marginTop:-offset});
		}
		else {
			this.Fx.cancel();
			if (this.options.horizontal) this.Fx.start({marginLeft:-offset});
			else this.Fx.start({marginTop:-offset});
		}
		this.refreshStatus();
	},
	showSlide:function(nextInd,instant){
		var nextCount = Math.floor(nextInd/this.step);
		if (nextCount != this.current) {
			this.previous = this.current;
			this.current = nextCount;
			if (instant) this.move(instant);
			else this.move();
		}
	},
	refreshStatus:function(){
		if (this.pagingHolder.length) {
			this.pagingBtn.each(function(obj){
				if (this.previous != -1) obj[this.previous].removeClass('active');
				obj[this.current].addClass('active');
			}.bind(this));
		}
	},
	autoPlay:function(){
		if (this.options.autoSlide) {
			clearTimeout(this.timer);
			this.timer = setTimeout(this.nextSlide.bind(this),this.options.switchTime);
		}
	}
});
