//init page
$(function(){
	initGalleries();
});

//init galleries
function initGalleries(){
	// homepage gallery
	$('div.gallery').gallery({
		duration: 500,
		autoRotation: 8000,
		effect: true,
		listOfSlides: '.frame > ul > li'
	});
	var switcher = jQuery('div.slider-holder').scrollGallery();
	$('div.page-holder').slideshow({
		autoPlay:true,
		switchTime:10000, //ms
		onChange:function(slideInd){
			switcher.showSlide(slideInd);
		}
	});
};

//gallery plugin
(function($) {
	$.fn.gallery = function(options) {
		var args = Array.prototype.slice.call(arguments);
		args.shift();
		this.each(function(){
			if(this.galControl && typeof options === 'string') {
				if(typeof this.galControl[options] === 'function') {
					this.galControl[options].apply(this.galControl, args);
				}
			} else {
				this.galControl = new Gallery(this, options);
			}
		});
		return this;
	};
	function Gallery(context, options) { this.init(context, options); };
	Gallery.prototype = {
		options:{},
		init: function (context, options){
			this.options = $.extend({
				duration: 700,
				slideElement:1,
				autoRotation: false,
				effect: false,
				listOfSlides: '.list > li',
				switcher: false,
				autoSwitcher: false,
				disableBtn: false,
				nextBtn: 'a.link-next, a.btn-next, a.next',
				prevBtn: 'a.link-prev, a.btn-prev, a.prev',
				circle: true,
				clone: false,
				direction: false,
				event: 'click'
			}, options || {});
			var self = this;
			this.context = $(context);
			this.els = this.context.find(this.options.listOfSlides);
			this.list = this.els.parent();
			this.count = this.els.length;
			this.autoRotation = this.options.autoRotation;
			this.direction = this.options.direction;
			this.duration = this.options.duration;
			if (this.options.clone) {
				this.list.append(this.els.clone());
				this.list.prepend(this.els.clone());
				this.els = this.context.find(this.options.listOfSlides);
			}
			this.wrap = this.list.parent();
			if (this.options.nextBtn) this.nextBtn = this.context.find(this.options.nextBtn);
			if (this.options.prevBtn) this.prevBtn = this.context.find(this.options.prevBtn);

			this.calcParams(this);
			
			if (this.options.autoSwitcher) {
				this.switcherHolder = this.context.find(this.options.switcher).empty();
				this.switchPattern = $('<ul class="'+ (this.options.autoSwitcher == true ? '' : this.options.autoSwitcher) +'"></ul>');
				for (var i=0;i<this.max+1;i++){
					$('<li><a href="#">'+i+'</a></li>').appendTo(this.switchPattern);
				}
				this.switchPattern.appendTo(this.switcherHolder);
				this.switcher = this.context.find(this.options.switcher).find('li');
				this.active = 0;
			} else {
				if (this.options.switcher) {
					this.switcher = this.context.find(this.options.switcher);
					this.active = this.switcher.index(this.switcher.filter('.active:eq(0)'));
				}
				else this.active = this.els.index(this.els.filter('.active:eq(0)'));
			}
			if (this.active < 0) this.active = 0;
			this.last = this.active;
			if (this.options.switcher) this.switcher.removeClass('active').eq(this.active).addClass('active');
			if (this.options.clone) this.active += this.count;
			
			if (this.options.effect) this.els.css({opacity: 0}).removeClass('active').eq(this.active).addClass('active').css({opacity: 1}).css('opacity', 'auto');
			else {
				if (this.direction) this.list.css({marginTop: -(this.mas[this.active])});
				else this.list.css({marginLeft: -(this.mas[this.active])});
			}
			
			
			if (this.options.nextBtn) this.initEvent(this, this.nextBtn,true);
			if (this.options.prevBtn) this.initEvent(this, this.prevBtn,false);
			
			this.initWindow(this,$(window));
			
			if (this.autoRotation) this.runTimer(this);
			
			if (this.options.switcher) this.initEventSwitcher(this, this.switcher);
			if (this.options.disableBtn && !this.options.circle && !this.options.clone) this.disableControls();
		},
		calcParams: function(self){
			this.mas = [];
			this.sum = 0;
			this.max = this.count-1;
			this.width = 0;
			this.els.each(function(){self.mas.push(self.width);self.width += self.direction?$(this).outerHeight(true):$(this).outerWidth(true);self.sum+=self.direction?$(this).outerHeight(true):$(this).outerWidth(true);});
			this.finish = this.direction?this.sum-this.wrap.outerHeight():this.sum-this.wrap.outerWidth();
			for (var i=0;i<this.count;i++){
				if (this.mas[i]>=this.finish) {
					this.max = i;
					break;
				}
			}
		},
		changeSettings: function(set,val){
			this[set] = val;
		},
		fadeElement: function(){
			this.els.eq(this.last).animate({opacity:0}, {queue:false, duration: this.duration});
			this.els.removeClass('active').eq(this.active).addClass('active').animate({
				opacity:1
			}, {queue:false, duration: this.duration, complete: function(){
				$(this).css('opacity','auto');
			}});
			if (this.options.switcher) this.switcher.removeClass('active').eq(this.active).addClass('active');
			this.last = this.active;
		},
		scrollElement: function(f){
			if (this.direction) this.list.animate({marginTop: f ? -this.finish : -(this.mas[this.active])}, {queue:false, duration: this.duration});
			else this.list.animate({marginLeft: f ? -this.finish : -(this.mas[this.active])}, {queue:false, duration: this.duration});
			if (this.options.switcher) this.switcher.removeClass('active').eq(this.options.clone ? this.active < this.count ? this.active/this.options.slideElement : this.active >= this.count*2 ? (this.active - this.count*2)/this.options.slideElement : (this.active - this.count)/this.options.slideElement : this.active/this.options.slideElement).addClass('active');
		},
		runTimer: function($this){
			if($this._t) clearTimeout($this._t);
			$this._t = setInterval(function(){
				$this.nextStep();
			}, this.autoRotation);
		},
		initEventSwitcher: function($this, el){
			el.bind($this.options.event, function(){
				if (!$(this).hasClass('active')){
					$this.active = $this.switcher.index($(this)) * $this.options.slideElement;
					if ($this.options.clone) $this.active += $this.count;
					$this.initMove();
				}
				return false;
			});
		},
		initEvent: function($this, addEventEl, dir){
			addEventEl.bind($this.options.event, function(){
				if (dir) $this.nextStep();
				else $this.prevStep();
				if($this._t) clearTimeout($this._t);
				if ($this.autoRotation) $this.runTimer($this);
				return false;
			});
		},
		disableControls: function(){
			this.prevBtn.removeClass(this.options.disableBtn);
			this.nextBtn.removeClass(this.options.disableBtn);
			if (this.active>=this.max) this.nextBtn.addClass(this.options.disableBtn);
			if (this.active<=0) this.prevBtn.addClass(this.options.disableBtn);
		},
		initMove: function(){
			var f = false;
			if (this.active >= this.max && !this.options.clone) {
				f = true;
				this.active = this.max;
			}
			if(this._t) clearTimeout(this._t);
			if (!this.options.effect) this.scrollElement(f);
			else this.fadeElement();
			if (this.autoRotation) this.runTimer(this);
			if (this.options.disableBtn && !this.options.circle && !this.options.clone) this.disableControls();
		},
		nextStep:function(){
			var f = false;
			this.active = this.active + this.options.slideElement;
			if (this.options.disableBtn && !this.options.circle && !this.options.clone) this.disableControls();
			if (this.options.clone){
				if (this.active > this.count*2) {
					if (this.direction) this.list.css({marginTop:-this.mas[this.count]});
					else this.list.css({marginLeft:-this.mas[this.count]});
					this.active = this.count+this.options.slideElement;
				}
			} else {
				if (this.active >= this.max) {
					if (this.options.circle) {
						if (this.active > this.max) this.active = 0;
						else {
							this.active = this.max;
							f = true
						}
					}
					else {
						this.active = this.max;
						f = true;
					}
				}
			}
			if (!this.options.effect) this.scrollElement(f);
			else this.fadeElement();
		},
		prevStep: function(){
			var f = false;
			this.active = this.active - this.options.slideElement;
			if (this.options.disableBtn && !this.options.circle && !this.options.clone) this.disableControls();
			if (this.options.clone){
				if (this.active < 0) {
					if (this.direction) this.list.css({marginTop:-this.mas[this.count]});
					else this.list.css({marginLeft:-this.mas[this.count]});
					this.active = this.count-1;
				}
			} else {
				if (this.active < 0) {
					if (this.options.circle) {
						this.active = this.max;
						f = true;
					}
					else this.active = 0;
				}
			}
			if (!this.options.effect) this.scrollElement(f);
			else this.fadeElement();
		},
		initWindow: function($this,$window){
			$window.focus($.proxy(this.play,this));
			$window.blur($.proxy(this.stop,this));
		},
		stop: function(){
			if (this._t) clearTimeout(this._t);
		},
		play: function(){
			if (this._t) clearTimeout(this._t);
			if (this.autoRotation) this.runTimer(this);
		}
	}
}(jQuery));

//create jQuery plugin
$.fn.slideshow = function(options){return new slideshow(this, options);}

//constructor
function slideshow(obj, options){this.init(obj,options)}

//prototype
slideshow.prototype = {
	init:function(obj, options) {
		this.options = $.extend({
			slides:'div.slide-show > ul >li',
			nextBtn:false,
			prevBtn:false,
			pagingHolder:'div.mask > ul',
			pagingTag:'> li',
			createPaging:false,
			autoPlay:false,
			dynamicLoad:false,
			imgAttr:'alt',
			effect:'fade',//fade, slideX, slideY,
			startSlide:0,
			switchTime:9000,
			animSpeed:500,
			onChange:null
		},options);
		
		this.mainHolder = $(obj);
		this.slides = $(this.options.slides,this.mainHolder);		
		this.nextBtn = $(this.options.nextBtn,this.mainHolder);
		this.prevBtn = $(this.options.prevBtn,this.mainHolder);
		this.dynamicLoad = this.options.dynamicLoad;
		this.imgAttr = this.options.imgAttr;
		this.animSpeed = this.options.animSpeed;
		this.switchTime = this.options.switchTime;
		this.effect = this.options.effect;
		this.autoPlay = this.options.autoPlay;
		this.previous = -1;
		this.current = this.options.startSlide;
		this.onChange = this.options.onChange;
		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.eq(0).parent();
		this.slideW = this.slidesParent.width();
		this.slideH = this.slidesParent.height();
		this.initPaging();
		this.setStyles();
		this.bindEvents();
		this.showSlide();
	},
	
	initPaging:function(){
		this.pagingHolder = $(this.options.pagingHolder,this.mainHolder);
		
		if (this.options.createPaging) {
			this.pagingHolder.each(function(i,obj){
				var _this = $(obj);
				_this.empty();
				var list = $('<ul>');
				for (var i = 0; i < this.slides.length; i++) $('<li><a href="#">' + (i + 1) + '</a></li>').appendTo(list);
				_this.append(list);
			}.bind(this));
		}
		
		this.paging = $(this.options.pagingTag, this.pagingHolder);
		var ratio = Math.ceil(this.paging.length / this.slides.length);
		for (var i = 0; i < ratio; i++) {
			this.pagingArray.push(this.paging.slice(i*this.slides.length, (i*this.slides.length)+this.slides.length));
		}
	},
	
	setStyles:function(){
		//loader
		if (this.dynamicLoad) {
			this.loader = $('<div class="loader">');
			this.loaderDiv = $('<div>').appendTo(this.loader)
			this.loader.append(this.loaderDiv).appendTo(this.mainHolder);
		}
		
		//slides
		if (this.effect == 'fade') {
			this.slides.css({display:'none',opacity:0});
			this.slides.eq(this.current).css({display:'block',opacity:1});
		} else if (this.effect == 'slideX'){
			this.slides.css({display: 'none',left:-this.slideW});
			this.slides.eq(this.current).css({display:'block',left:0});
		} else if (this.effect == 'slideY'){
			this.slides.css({display:'none',top:-this.slideH});
			this.slides.eq(this.current).css({display:'block',top:0});
		}
	},
	
	bindEvents:function(){
		this.nextBtn.bind('click',function(){
			if (!this.busy) this.nextSlide();
			return false;
		}.bind(this));
		
		this.prevBtn.bind('click',function(){
			if (!this.busy) this.prevSlide();
			return false;
		}.bind(this));
		
		for (var i = 0; i < this.pagingArray.length; i++) {
			this.pagingArray[i].each(function(i,obj){
				$(obj).bind('click',function(){
					if (i != this.current && !this.busy) {
						this.busy = true;
						this.previous = this.current;
						this.current = i;
						this.showSlide();
					}
					return false;
				}.bind(this));
			}.bind(this))
		}
		
		if (this.dynamicLoad) this.loader.bind('click',this.abortLoading.bind(this));
	},
	
	nextSlide:function(){
		this.busy = true;
		this.previous = this.current;
		if (this.current < this.slides.length-1) this.current++
		else this.current = 0;
		this.direction = 1;
		if (typeof this.onChange === 'function') this.onChange(this.current);
		this.showSlide();
	},
	
	prevSlide:function(){
		this.busy = true;
		this.previous = this.current;
		if (this.current > 0) this.current--
		else this.current = this.slides.length-1;
		this.direction = -1;
		if (typeof this.onChange === 'function') this.onChange(this.current);
		this.showSlide();
	},
	
	showSlide:function(){
		var obj = this;
		var _current = this.current;
		clearTimeout(this.timer);
		
		if (typeof this.loadArray[_current] != 'undefined' || !this.dynamicLoad) {
			//slide already loaded
			if (this.previous != -1) this.switchSlide()
			else {
				obj.refreshStatus();
				if (obj.autoPlay) obj.startAutoPlay();
			}
		} else {
			//slide not loaded
			this.showLoading();
			
			var slide = this.slides.eq(this.current);
			var images = $(this.dynamicLoad,slide);
			var counter = 0;
			images.each(function(){
				var preloader = new Image;
				obj.preloader.push(preloader);
				var img = $(this);
				preloader.src = img.attr(obj.imgAttr);
				preloader.onload = function(){
					counter++;
					checkImages();
				}
				preloader.onerror = function(){
					//ignore errors
					counter++;
					checkImages();
				}
			});
			
			function checkImages(){
				if (counter == images.length) {
					images.each(function(){
						var img = $(this);
						img.attr('src',img.attr(obj.imgAttr));
					});
					obj.loadArray[_current] = 1;
					obj.hideLoading();
					if (obj.previous != -1) obj.switchSlide()
					else {
						obj.refreshStatus();
						if (obj.autoPlay) obj.startAutoPlay();
					} 
				}
			}
		}
	},
	
	switchSlide:function(){
		var obj = this;
		
		if (this.effect == 'fade') {
			this.slides.eq(this.previous).stop().animate({opacity:0},this.animSpeed,callback);
			this.slides.eq(this.current).stop().css({display:'block'}).animate({opacity:1},this.animSpeed);
		} else if (this.effect == 'slideX'){
			this.slides.eq(this.current).css({display:'block',left:this.slideW*this.direction}).animate({left:0},this.animSpeed);
			this.slides.eq(this.previous).animate({left:-this.slideW*this.direction},this.animSpeed,callback);
		} else if (this.effect == 'slideY'){
			this.slides.eq(this.current).css({display:'block',top:this.slideH*this.direction}).animate({top:0},this.animSpeed);
			this.slides.eq(this.previous).animate({top:-this.slideH*this.direction},this.animSpeed,callback);
		}
		
		function callback(){
			$(this).css({display:'none'});
			if (obj.autoPlay) obj.startAutoPlay();
			obj.busy = false;
		}
		
		this.refreshStatus();
	},
	
	refreshStatus:function(){
		for (var i = 0; i < this.pagingArray.length;i++) {
			this.pagingArray[i].eq(this.previous).removeClass('active');
			this.pagingArray[i].eq(this.current).addClass('active');
		}
	},
	
	showLoading:function(){
		var obj = this;
		this.loader.show();
		clearInterval(this.loadingTimer);
		obj.loadingTimer = setInterval(animateLoading, 66);
		
		function animateLoading(){
			if (!obj.loader.is(':visible')){
				clearInterval(obj.loadingTimer);
				return;
			}
			obj.loaderDiv.css('top', obj.loadingFrame * -40);
			obj.loadingFrame = (obj.loadingFrame + 1) % 12;
		}
	},
	
	hideLoading:function(){
		this.loader.hide();
	},
	
	abortLoading:function(){
		this.busy = false;
		this.loader.hide();
		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(){
		var obj = this;
		clearTimeout(obj.timer);
		obj.timer = setTimeout(function(){
			obj.nextSlide();
		},obj.switchTime);
	}
}

// bind scope function
Function.prototype.bind = function(scope) {
	var _function = this;
	return function() {
		return _function.apply(scope, arguments);
	}
}

//create jQuery plugin
$.fn.scrollGallery = function(options){return new scrollGallery(this,options)}

//constructor
function scrollGallery(obj,options){this.init(obj,options);}

//prototype
scrollGallery.prototype = {
	init:function(obj,options){
		this.options = $.extend({
			holder:'div.mask', 
			slider:'>ul',
			slides:'>li',
			prevBtn:'span.link-prev',
			nextBtn:'span.link-next',
			pagingHolder:'div.paging',
			pagingBtn:'li',
			createPaging:false,
			circleSlide:true,
			slideSpeed:500,
			startSlide:false,
			step:false
		},options);
		
		// elems
		this.mainHolder = $(obj);
		this.holder = $(this.options.holder, this.mainHolder);
		this.slider = $(this.options.slider, this.holder)
		this.slides = $(this.options.slides ,this.slider);
		this.prevBtn = $(this.options.prevBtn, this.mainHolder);
		this.nextBtn = $(this.options.nextBtn, this.mainHolder);
		
		//variables
		this.slideW = this.slides.eq(0).outerWidth(true);
		this.visibleStep = Math.round(this.holder.width()/this.slideW);
		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;
		
		//paging
		this.pagingHolder = $(this.options.pagingHolder, this.mainHolder);
		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(i,obj){
					var $this = $(obj);
					$this.empty();
					var list = $('<ul>');
					for (var i = 0; i < this.pagingLength; i++) $('<li><a href="#">' + (i + 1) + '</a></li>').appendTo(list);
					$this.append(list);
				}.bind(this));
			}
			
			this.pagingHolder.each(function(i,obj){
				this.pagingBtn[i] = $(this.options.pagingBtn, $(obj)); 
				var stepCount = 0;
				this.pagingBtn[i].each(function(j,obj){
					var index = stepCount;
					$(obj).click(function(){
						if (index != this.current) {
							this.showSlide(index);
						}
						return false;
					}.bind(this));
					stepCount += this.step;
				}.bind(this));
			}.bind(this));
		}
		
		//next & prev
		this.nextBtn.click(function(){
			this.nextSlide();
			return false;
		}.bind(this));
		this.prevBtn.click(function(){
			this.prevSlide();
			return false;
		}.bind(this));
	},
	
	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){
		var offset;
		if (this.step * this.current < this.max) offset = (this.step*this.current)*this.slideW;
		else offset = this.max * this.slideW
		if (instant) this.slider.css({marginLeft:-offset})
		else this.slider.animate({marginLeft:-offset},this.options.slideSpeed);
		
	},
	
	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();
		}
	}
}
