/*
 *
 * Author: sandi.winter@gmail.com
 * http://www.alls-soft.com
 *
 */

function Scroller(){
	var scrollDiv;
	var scrollDHeight;
	var scrollCHeight;
	var scrollYPos = 0;
	var scrollTimer;
	
	var scrollThumb;
	var scrollTracky;
	var scrollTrackheight = 323;
	var scrollThumbheight = 10;
	var scrollTrack;
	var scrollHolder;
	
	var txtval;
	
	var tempX = 0;
	var tempY = 0;
	
	//public
	this.load = load;
	this.scrollUp = scrollUp;
	this.scrollDown = scrollDown;
	this.setPosition = setPosition;
	this.initmouwhell = initmouwhell;
	this.refresh = refresh;
	
	this.setTrackElem = setTrackElem;
	this.setThumbElem = setThumbElem;
	this.setTxtElem = setTxtElem;
	this.setTrackHeight = setTrackHeight;
	this.setScrollHolder = setScrollHolder;
	this.setJumpPosition = setJumpPosition;
	
	//private
	this.getAbsolutePosition = getAbsolutePosition;
	this.getRelativeCoordinates = getRelativeCoordinates;
	this.findPos = findPos;
	this.doScrollUp = doScrollUp;
	this.doScrollDown = doScrollDown;
	this.scrollStop = scrollStop;
	
	function getAbsolutePosition(element) {
	  var r = { x: element.offsetLeft, y: element.offsetTop };
	  if (element.offsetParent) {
	    var tmp = getAbsolutePosition(element.offsetParent);
	    r.x += tmp.x;
	    r.y += tmp.y;
	  }
	  return r;
	};
	
	function getRelativeCoordinates(event, reference) {
	  var x, y;
	  event = event || window.event;
	  var el = event.target || event.srcElement;
	
	  if (!window.opera && typeof event.offsetX != 'undefined') {
	    // Use offset coordinates and find common offsetParent
	    var pos = { x: event.offsetX, y: event.offsetY };
	
	    // Send the coordinates upwards through the offsetParent chain.
	    var e = el;
	    while (e) {
	      e.mouseX = pos.x;
	      e.mouseY = pos.y;
	      pos.x += e.offsetLeft;
	      pos.y += e.offsetTop;
	      e = e.offsetParent;
	    }
	
	    // Look for the coordinates starting from the reference element.
	    var e = reference;
	    var offset = { x: 0, y: 0 }
	    while (e) {
	      if (typeof e.mouseX != 'undefined') {
	        x = e.mouseX - offset.x;
	        y = e.mouseY - offset.y;
	        break;
	      }
	      offset.x += e.offsetLeft;
	      offset.y += e.offsetTop;
	      e = e.offsetParent;
	    }
	
	    // Reset stored coordinates
	    e = el;
	    while (e) {
	      e.mouseX = undefined;
	      e.mouseY = undefined;
	      e = e.offsetParent;
	    }
	  }
	  else {
	    // Use absolute coordinates
	    var pos = getAbsolutePosition(reference);
	    x = event.pageX  - pos.x;
	    y = event.pageY - pos.y;
	  }
	  // Subtract distance to middle
	  return { x: x, y: y };
	}
	
	function findPos(obj)
	{
		var curleft = curtop = 0;
		if (obj.offsetParent) {
			curleft = obj.offsetLeft
			curtop = obj.offsetTop
			while (obj = obj.offsetParent) {
				curleft += obj.offsetLeft
				curtop += obj.offsetTop
			}
		}
		return curtop;
	}
	
	function setTxtElem(elem){
		scrollDiv = elem;
	}
	
	function setThumbElem(elem){
		scrollThumb = elem;
	}
	
	function setTrackElem(elem){
		scrollTrack = elem;
	}
	
	function setTrackHeight(len){
		scrollTrackheight = len;
	}
	
	function setScrollHolder(elem){
		scrollHolder = elem;
	}
	
	function load(height){
		scrollCHeight = scrollDiv.offsetHeight;
		scrollDHeight = height;
	}
	
	function refresh(){
		scrollCHeight = scrollDiv.offsetHeight;
	    scrollThumb.style.top = '0px';
	    scrollYPos = 0;
	    scrollDiv.style.top = '0px';  	
	}
	
	function scrollUp(){
		scrollStop();
		scrollTimer = setInterval(function(){doScrollUp(10);}, 6);
	}
	
	function scrollDown(){
		scrollStop();
		if(scrollDHeight < scrollCHeight){
		scrollTimer = setInterval(function(){doScrollDown(10);}, 6);
		}
	}
	
	function doScrollUp(koliko){
	  if(scrollDHeight < scrollCHeight)
		if(scrollYPos+1 >= 0){
			scrollDiv.style.top = '0px';
			scrollYPos = 0;
			scrollStop();
		}else{
			scrollYPos += koliko;
			scrollDiv.style.top = scrollYPos+'px';
			if(((scrollYPos/(scrollDHeight-scrollCHeight))*(scrollTrackheight-scrollThumbheight))>0){
			  scrollThumb.style.top = ((scrollYPos/(scrollDHeight-scrollCHeight))*(scrollTrackheight-scrollThumbheight))+'px';
	    }
	    else{
			  scrollThumb.style.top = '0px';
	    }
		}
	}
	
	function doScrollDown(koliko){
	  if(scrollDHeight < scrollCHeight)
		if(scrollDHeight-scrollYPos+1 >= scrollCHeight){
			scrollDiv.style.top = (-(scrollCHeight-scrollDHeight))+'px';
			scrollYPos = -(scrollCHeight-scrollDHeight);
			scrollStop();
		}else{
			scrollYPos -= koliko;
			scrollDiv.style.top = scrollYPos+'px';
			if(((scrollYPos/(scrollDHeight-scrollCHeight))*(scrollTrackheight-scrollThumbheight))<scrollTrackheight){
			  scrollThumb.style.top = ((scrollYPos/(scrollDHeight-scrollCHeight))*(scrollTrackheight-scrollThumbheight))+'px';
	    }
	    else{
			  scrollThumb.style.top = scrollTrackheight-scrollThumbheight+'px';
	    }
		}
	}
	
	function scrollStop(){
		clearInterval(scrollTimer);
	}
	
	function setPosition(event){
	  if(scrollCHeight > scrollDHeight){
	    var pos = getRelativeCoordinates(event, scrollTrack);
	    if(pos.y<scrollTrackheight-scrollThumbheight){
		    scrollThumb.style.top = pos.y + 'px';
		    scrollYPos = (pos.y/scrollTrackheight * (scrollDHeight-scrollCHeight));
		    scrollDiv.style.top = scrollYPos + 'px';  	
		}
	  }
	}

	function setJumpPosition(top){
	  top = -top;
	  if(scrollCHeight > scrollDHeight){
	  	//alert(-(top*scrollTrackheight/scrollCHeight));
		scrollThumb.style.top = (-top*scrollTrackheight/scrollCHeight) + 'px';
		scrollYPos = top;
		scrollDiv.style.top = scrollYPos + 'px';  
	  }
	}

	/*
	 * This is high-level function.
	 * It must react to delta being more/less than zero.
	 */
	function handle(delta) {
        if (delta < 0)
			doScrollDown(20);
        else
			doScrollUp(20);
	}

	/*
	 * Event handler for mouse wheel event.
	 */
	function wheel(event){
	    var delta = 0;
	    if (!event) /* For IE. */
	            event = window.event;
	    if (event.wheelDelta) { /* IE/Opera. */
	            delta = event.wheelDelta/120;
	            /** In Opera 9, delta differs in sign as compared to IE.
	             */
	            if (window.opera)
	                    delta = -delta;
	    } else if (event.detail) { /** Mozilla case. */
	            /** In Mozilla, sign of delta is different than in IE.
	             * Also, delta is multiple of 3.
	             */
	            delta = -event.detail/3;
	    }
	    /** If delta is nonzero, handle it.
	     * Basically, delta is now positive if wheel was scrolled up,
	     * and negative, if wheel was scrolled down.
	     */
	    if (delta)
	            handle(delta);
	    /** Prevent default actions caused by mouse wheel.
	     * That might be ugly, but we handle scrolls somehow
	     * anyway, so don't bother here..
	     */
	    if (event.preventDefault)
	            event.preventDefault();
		event.returnValue = false;
	}

	function initmouwhell(){
		/** Initialization code. 
		* If you use your own event management code, change it as required.
		*/		
		if (scrollHolder.addEventListener)
			/** DOMMouseScroll is for mozilla. */
			scrollHolder.addEventListener('DOMMouseScroll', wheel, false);
		/** IE/Opera. */
		scrollHolder.onmousewheel = scrollHolder.onmousewheel = wheel;
		
	}

}
