var ProtoFlow = Class.create({
    
    initialize: function(elem, opt){
        opt = opt || {};
        this.options = {
            startIndex: 2,
            interval: 60,
            slider: true,
            flex: 110,
            captions: false,
            autoplay: false,
            autoplayInterval: 5,
            useReflection: false,
            enableOnClickScroll: false,
			enableKeyboard: true,
			enableMouse: true
        };
		Object.extend(this.options, opt);
		
        this.useCaptions = this.options.captions; //initially we don't wanna use captions unless turned on?
        this.elem = $(elem);
        if (!this.elem) 
            return;
        
        //console.log(this.elem.select('img'));
        this.elem.setStyle({
            overflow: "hidden",
            position: "relative"
        });
        this.imageStack = this.elem.select('img'); //this.elem.childElements();
        if (this.options.captions != false) {
            this.captions = this.imageStack.pluck("alt");
            //this.captions = this.captionsHolder.childElements();		
            //this.captions.each( ( function(elem, i){this.captions[i] = elem.innerHTML;} ).bind(this));
            this.captionsCount = this.captions.size();
        }
        
        if (this.options.useReflection) {
            this.imageStack.each(function(elem){
                Reflection.add(elem, {
                    opacity: 2 / 3
                });
            }.bind(this));
            this.stack = this.elem.childElements();
        }
        else {
            this.stack = this.imageStack;
        }
        this.stackCount = (this.stack).size();
        
        
        
        if (this.useCaptions) {
            this.captionHolder = new Element('div');
            this.captionHolder.className = "captionHolder";
            this.captionHolder.setStyle({
                width: "100%",
                textAlign: "center",
                position: 'absolute',
                left: "0px",
                top: (Element.getHeight(this.elem) - 80) + "px"
            });
            this.elem.appendChild(this.captionHolder);
        }
        
        
        
        this.currPos = this.options.startIndex - 1;
        this.currIndex = this.currPos;
        /* slider */
        if (this.options.slider) {
            this.sliderContainer = new Element('div');
            this.sliderContainer.setStyle({
                width: '200px',
                height: '10px',
                position: 'absolute',
                top: (Element.getHeight(this.elem) - 30) + "px",
                left: (Element.getWidth(this.elem) / 2 - (137 / 2)) + "px",
                zIndex: 99999999
            });
            
            this.sliderTrack = new Element('div');
            this.sliderTrack.className = "sliderTrack";
            
            this.sliderHandle = new Element('div');
            this.sliderHandle.className = "sliderHandle";
            
            this.sliderTrack.appendChild(this.sliderHandle);
            this.sliderContainer.appendChild(this.sliderTrack);
            
            this.elem.appendChild(this.sliderContainer);
            
            this.slider = new Control.Slider(this.sliderHandle, this.sliderTrack, {
                range: $R(0, this.getStackCount() - 1),
                sliderValue: this.getCurrentPos(), 
                onSlide: this.handleSlider.bind(this),
                onChange: this.handleSlider.bind(this)
            });
        }
        
        
        
        this.timer = 0;
        
        
       
        this.stack.each(function(elem){
            elem.identify();
            //console.log(elem);
            //elem.observe("mouseover", function(){this.setStyle({"border": "2px solid yellow;"});});
            if (this.options.enableOnClickScroll) 
                elem.observe('click', this.handleClick.bind(this));
        }.bind(this));
        
        if (this.options.enableOnClickScroll) //lets go through all the <a> tags and disable them..
        {
            this.disableLinks();
        }
        
        this.goTo(this.currPos);
        
        this.autoplayer = null;
        if (this.options.autoplay) {
            this.autoplayer = new PeriodicalExecuter(this.autoPlay.bind(this), this.options.autoplayInterval);
        }

		
		
		if(this.options.enableKeyboard) {
		 document.observe('keyup', (function(e) {
		   var code = e.keyCode;
		   if(37 == code) this.previous();
		   if(39 == code) this.next();
		 }).bind(this));
		}

		if(this.options.enableMouse) {
		 var eventType = Prototype.Browser.Gecko ? "DOMMouseScroll" : "mousewheel";

		 Event.observe(this.elem, eventType, (function(e) {
		   this.enableMouse(e);
		 }).bind(this), false);

		 if (this.useCaptions) {
		   Event.observe(this.captionHolder, eventType, (function(e) {
			 this.enableMouse(e);
		   }).bind(this), false);
		 }
		}
		/***/
        Event.observe(window, 'resize', this.handleWindowResize.bind(this));
    },
	
	 disableLinks: function(){
		this.elem.select("a").each(function(a){
			a.observe('click', function(e) {
				e.preventDefault();
			});
		});
	},
	
    autoPlay: function(){
        if ((this.currIndex + 2) > this.stackCount) {
            this.currIndex = 0;
        }
        this.currIndex = this.currIndex + 1
        this.goTo(this.currIndex);
    },
	
    handleWindowResize: function(event){
    },
	
    handleWheel: function(event){
        v = Event.wheel(event);
        this.goTo(this.currIndex + v);
        this.slider.setValue(this.currIndex + v);
    },
	
    handleSliderChange: function(index){
        this.goTo(index);
    },
	
    handleSlider: function(index){
        if (index) 
            this.goTo(index);
    },
	
    handleClick: function(e){
        var elem = Event.element(e);
        
        var v = elem.getAttribute("index");
        
        if (!v && this.options.useReflection) {
            elem = elem.up('a');
            v = elem.getAttribute("index");
        }
        
        this.currIndex = v;
        this.goTo(v);
        this.updateSlider(v);
    },
	
    getCurrentPos: function(){
        return this.currPos;
    },
	
    goTo: function(index){
        this.slideTo(index * this.options.flex * -1);
        //this.currPos = Math.round(index);
        if (this.useCaptions) {
            this.captionHolder.innerHTML = this.captions[Math.round(index)];
        }
    },
	
    updateSlider: function(index){
        if (this.options.slider) 
            this.slider.setValue(index);
    },
	
    step: function(){
        if (this.target < this.currPos - 1 || this.target > this.currPos + 1) {
            this.moveTo(this.currPos + (this.target - this.currPos) / 5);
            window.setTimeout(this.step.bind(this), this.options.interval);
            this.timer = 1;
        }
        else {
            this.timer = 0;
            
        }
    },
	
    slideTo: function(x){
        this.target = x;
        
        if (this.timer == 0) {
            window.setTimeout(this.step.bind(this), this.options.interval);
            this.timer = 1;
        }
        
        
    },
   
    moveTo: function(currentPos){
        var x = currentPos;
        this.currPos = currentPos;
        var width = Element.getWidth(this.elem);
        var height = Element.getHeight(this.elem);
        
        var top = this.elem.offsetTop;
        var zIndex = this.stackCount;
		var flex = this.options.flex;
        this.stack.each(function(elem, index){

            Element.absolutize(elem);
            elem.setAttribute("index", index);

			var wsize=300;
        	var hsize=300;

            if (this.options.useReflection) {
				wsize=elem.select('img')[0].width;
				hsize=elem.select('img')[0].height;
			} else {
				wsize=elem.width;
				hsize=elem.height;
			}
            
            if (this.options.useReflection) {
                elem.down(1).setAttribute('index', index);
            }

			var sign=1;
			if(x < 0)
				sign=-1;

			var mvt=Math.abs(x/flex/this.stackCount);

			if(mvt > 0.2) {
				mvt=Math.min(1, Math.pow(mvt, 0.1));
			} else if(mvt > 0.01) {
				mvt=mvt*4;
			}

			var nx=(width  - wsize)/2 + sign * (width - wsize - 20) * mvt / 2;
			var ny=(20 + height - hsize)/2 - (height - hsize - 10) * mvt / 2;

            elem.setStyle({
                left: nx+'px',
                top: ny+'px',
                textAlign: "center"
            });
            //console.log(elem);
            elem.style.zIndex = zIndex;
            
            if (x < - (flex/2)) 
                zIndex++;
            else 
                zIndex--;

            x += this.options.flex;
            
        }.bind(this));
    },
    
    getStackCount: function(){
        return this.stackCount;
    },
	decreaseIndex: function(e) {
		if(this.currIndex > 0)
			this.currIndex--;
	},

	increaseIndex: function(e) {
		if (this.currIndex < this.getStackCount() - 1)
			this.currIndex++;
	},

	previous: function(e) {
		this.decreaseIndex();
		this.toCurrentIndex();
	},

	next: function(e) {
		this.increaseIndex();
		this.toCurrentIndex();
	},

	enableMouse: function(e) {
		Event.wheel(e)< 0 ? this.next() : this.previous();
		Event.stop(e);
	},

	toCurrentIndex: function(e) {
		this.goTo(this.currIndex);
		this.updateSlider(this.currIndex);
	}	
});

/**
* sifra
*/
Object.extend(Event, {
	wheel: function(event){
		var delta = 0;
		if (!event) event = window.event;

		if (event.wheelDelta) {
			delta = event.wheelDelta/120;
			if (window.opera) delta = -delta;
		} 
		else if (event.detail) {
			delta = -event.detail/3;
		}
		return Math.round(delta); //Safari Round
	}
});

