var MooFlow = new Class({

	Implements: [Events, Options],
	
	options: {
		onStart: Class.empty,
		onComplete: Class.empty,
		onCancel: Class.empty,
		container: 'MooFlow',
		imgContainer: 'images',
		slider: false,
		caption: false,
		reflection: 0.5,
		startIndex: 2,
		buttons: false,
		interval: 3000,
		useWindowResize: true,
		useMouseWheel: true,
		useKeyInput: false
	},
	initialize: function(options){
		this.setOptions(options);
		this.foc = 150;
		this.cur = 0;
		this.tar = 0;
		this.curI = this.options.startIndex;
		this.isRun = false;
		this.sli = null;
		this.checker = null;
		this.images = $$(this.options.images);
		this.iL = $$(this.options.images).length;
		this.interval = this.options.interval;
		this.init();
		if(this.options.buttons){
			this.initButtons(this.options.buttons);
		}
		if(this.options.useWindowResize){
			window.addEvent('resize', this.update.bind(this));
		}
	},
	init: function(){
		$$(this.options.images).each(function(image, i){
			image.setStyle('display','block');
			image.addEvent('click', this.clickTo.bind(this,[i]));
		}, this);
		
		if(this.options.useMouseWheel && this.options.slider){
			$(this.options.container).addEvent('mousewheel', this.wheelTo.bind(this));
		}
		if(this.options.useKeyInput){
			document.addEvent('keydown', this.keyTo.bind(this));
		}
		this.update();
	},
	update: function(){
		this.oW = $(this.options.container).offsetWidth;
		this.oT = $(this.options.container).offsetTop;
		$(this.options.imgContainer).setStyle('height', this.oW*0.5);
		$(this.options.container).setStyle('height', this.oW*0.66);
		$(this.options.container).setStyle('visibility','visible');
		this.sz = this.oW * 0.5;
		if(this.options.slider){
			this.sli = new Slider($(this.options.slider.slider), $(this.options.slider.knob),{
				steps: this.iL-1
			}).set(this.curI);
			$(this.options.slider.knob).setStyles({'width':$(this.options.slider.slider).offsetWidth/this.iL,'opacity':0.5});
			this.sli.addEvent('onChange', this.glideTo.bind(this));
		}
		this.process(this.curI*-this.foc);
		this.glideTo(this.curI);
	},
	initButtons: function(btns){
		if($chk(btns.prev)){ $(btns.prev).addEvent('click', this.prev.bind(this)); };
		if($chk(btns.stop)){ $(btns.stop).addEvent('click', this.stop.bind(this)); };
		if($chk(btns.play)){ $(btns.play).addEvent('click', this.play.bind(this)); };
		if($chk(btns.next)){ $(btns.next).addEvent('click', this.next.bind(this)); };
	},
	prev: function(){
		if(this.curI > 0)
			this.curI--;this.clickTo(this.curI);
	},
	stop: function(){
		$clear(this.autoPlay);
	},
	play: function(){
		this.autoPlay = this.auto.periodical(this.interval, this);
	},
	auto: function(){
		if(this.curI < this.iL-1){
			this.curI++;this.clickTo(this.curI);
		} else if(this.curI == this.iL-1){
			this.curI=0;this.clickTo(this.curI);
		}
	},
	next: function(){
		if(this.curI < this.iL-1)
			this.curI++;this.clickTo(this.curI);
	},
	start: function(){
		this.isRun = true;
		this.checker = this.check.periodical(50, this);
	},
	end: function(){
		$clear(this.checker);
	},
	keyTo: function(e){
		switch (e.code){
			case 37:
				if(this.curI > 0)
					this.curI--;this.clickTo(this.curI);
				break;
			case 39:
				if(this.curI < this.iL-1)
					this.curI++;this.clickTo(this.curI);
				break;
		}
	},
	wheelTo: function(e){
		var d = e.wheel;
		if(d > 0 && this.curI > 0)
			this.curI--;this.clickTo(this.curI);
		
		if(d < 0 && this.curI < this.iL-1)
			this.curI++;this.clickTo(this.curI);
	},
	clickTo: function(i){
		if(this.options.slider){
			this.sli.set(i);
		} else {
			this.glideTo(i);
		}
	},
	glideTo: function(i){
		if(!this.isRun){this.start();}
		if(this.options.caption && this.images[i]){$(this.options.caption).set('html', this.images[i].alt);}
		this.curI = i;
		this.tar = i*-this.foc;
	},
	check: function(){
		switch(this.tar < this.cur-1 || this.tar > this.cur+1){
			case true:
				this.process(this.cur + (this.tar-this.cur)/3);
				break;
			default:
				this.isRun = false;
				this.end();
				break;
		}
	},
	process: function(x){
		x = Math.round(x);
		this.cur = x;
		var zI = this.iL;
		var z, xs, imgH, imgW, percent;
		$$(this.images).each(function(img){
			if(x<-this.foc*4||x>this.foc*4){img.setStyle('display','none');} else {img.setStyle('display','block');}
			z = Math.sqrt(10000 + x * x) + 100;
			xs = x / z * this.sz + this.sz;
			imgH = img.height;
			imgW = img.width;
			percent = 100;
			if ((imgW + 1) > (imgW / (this.options.reflection + 1))){
				percent = 115;
			}
			newL = xs - (percent / 2) / z * this.sz;
			newH = (imgH / imgW * percent) / z * this.sz;
			newT = (this.oW * 0.4 - newH) + ((newH / (this.options.reflection + 1)) * this.options.reflection);
				
			img.setStyle('left', newL);
			img.setStyle('height', newH);
			img.setStyle('margin-top', newT);
			img.setStyle('zIndex', x < 0 ? zI++ : zI--);		
			
			x += this.foc;
		}, this);
	}
});