/* ******************************************************************************
		Coded by GS on 16.03.2008, True Vision
****************************************************************************** */
  
(function($) {
	
    $.fn.scroller = function(options) {
		
		settings = $.extend($.fn.scroller.constructor, options);
		
		var c = 0;
        
        this.filter('div.scrollable').each(function() {
			var $this = $(this);
			
			$('#' + this.id + '_scrlr').remove();
			
			$this.css({ overflow:'hidden' });
			$this.scrollTop(0);
			$this.scrollLeft(0);
			
			if (this.scrollHeight - this.offsetHeight == 0) return;
			if (!this.id){
				this.id = 'rnd_' + c;
				c++;
			}
			
			var scroller	=	$('<div></div>')
									.attr('id', this.id + '_scrlr')
									.addClass('scroller')
									.css({ position:'absolute', marginTop:'11px', marginLeft:this.offsetWidth - 10 + 'px', height:this.offsetHeight - 22 + 'px' });
			var slider		=	$('<div></div>')
									.attr('id', this.id + '_scrlr_sldr')
									.addClass('scroller-slider')
									.css({ position:'absolute', top:'11px', left:0, marginTop:'-11px' });
			var up			=	$('<div></div>')
									.attr('id', this.id + '_scrlr_top')
									.addClass('scroller-top')
									.css({ position:'absolute', bottom:'100%', left:0 });
			var down		=	$('<div></div>')
									.attr('id', this.id + '_scrlr_bot')
									.addClass('scroller-bot')
									.css({ position:'absolute', top:'100%', left:0 });
			
			$this.before(scroller);
				
			scroller.append(slider)
					.append(up)
					.append(down);
			
			settings.init(this, scroller, slider, up, down);
        });
		
        return this;
    };
	
	$.fn.scroller.constructor = {
		scrollers: {},
			
		current: null,
		
		timer: null,
		
		init: function(_this, scroller, slider, up, down) {
			var self = this;
			var offset = scroller.offset();
			
			up.addClass('scroller-arrow-deactive');

			this.scrollers[_this.id] = {
				id: _this.id,
				object: _this,
				scroller: scroller,
				slider: slider,
				up: up,
				down: down,
				offset: {
					top: offset.top,
					left: offset.left,
					width: _this.offsetWidth,
					height: _this.offsetHeight - 22
				}
			};
			
			self.current = _this.id;
			
			$(_this).bind('mousewheel', function(e, delta) {
				self.arrow(delta * -1);
				return false;
			});
			
			slider.mousedown(function(e) {
				self.current = _this.id;
				self.mouse_down(e);
				return false;
			}).click(function() {
				return false;
			});
				
			scroller.click(function(e) {
				self.current = _this.id;
				self.mouse_click(e);
				return false;
			});
			
			down.click(function(e) {				
				e.stopPropagation();
				clearInterval(self.timer);
				self.current = _this.id;
				self.arrow(1);
				return false;
			}).mousedown(function(e) {
				clearInterval(self.timer);
				down.addClass('scroller-arrow-down');
				self.current = _this.id;
				self.timer = setInterval(
					function(){ self.arrow(1) },
					100
				);
			}).mouseup(function() {
				clearInterval(self.timer);
				down.removeClass('scroller-arrow-down');
			});
			
			up.click(function(e) {				
				e.stopPropagation();
				clearInterval(self.timer);
				self.current = _this.id;
				self.arrow(-1);
				return false;
			}).mousedown(function(e) {
				clearInterval(self.timer);
				up.addClass('scroller-arrow-down');
				self.current = _this.id;
				self.timer = setInterval(
					function(){ self.arrow(-1) },
					100
				);
			}).mouseup(function() {
				clearInterval(self.timer);
				up.removeClass('scroller-arrow-down');
			});
		},
		
		mouse_down: function(e) {
			var self = this;
			var id = this.current;
			var slider = this.scrollers[id].slider;
			
			slider.addClass('scroller-slider-down');

			this.mouseMoveFunction = function(e) {
				self.mouse_move(e);
				return false;
			}
			this.mouseUpFunction = function(e) {
				self.mouse_up(e);
				return false;
			}
			
			$(document).bind('mousemove', self.mouseMoveFunction );
			$(document).bind('mouseup', self.mouseUpFunction );
		},
		
		mouse_click: function(e) {
			var id = this.current;
			var offset = this.scrollers[id].offset;
			var x = e.clientX - offset.left;
			var y = e.clientY - offset.top;
			this.scroll(x, y);
		},
		
		mouse_up : function(e) {
			var self = this;
			var id = this.current;
			var slider = this.scrollers[id].slider;
			
			slider.removeClass('scroller-slider-down');
			
			$(document).unbind('mousemove', self.mouseMoveFunction );
			$(document).unbind('mouseup', self.mouseUpFunction );
		},
		
		mouse_move : function(e) {
			var id = this.current;
			var offset = this.scrollers[id].offset;
			var x = e.clientX - offset.left;
			var y = e.clientY - offset.top;
			this.scroll(x, y);
		},
			
		arrow: function(d){
			var id = this.current;
			var slider = this.scrollers[id].slider;
			var pos = slider.position();
			var y = pos.top + (10 * d);

			this.scroll(0, y);
		},
			
		scroll: function(x, y){
			var id = this.current;
			var object = this.scrollers[id].object;
			var scroller = this.scrollers[id].scroller;
			var slider = this.scrollers[id].slider;
			var up = this.scrollers[id].up;
			var down = this.scrollers[id].down;
			var offset = this.scrollers[id].offset;
			var posy = y;
			
			if (y >= offset.height - 11) {
				y = offset.height;
				posy = y - 11;
				down.addClass('scroller-arrow-deactive');
			} else {
				down.removeClass('scroller-arrow-deactive');
			}
			if (y <= 10) {
				y = 0;
				posy = y + 10;
				up.addClass('scroller-arrow-deactive');
			} else {
				up.removeClass('scroller-arrow-deactive');
			}
			
			slider.css({ position:'absolute', top:posy + 'px' });
			
			y = Math.round((object.scrollHeight - object.offsetHeight) / (offset.height - 22) * y);
			
			object.scrollTop = y;
		}
	};
    
})(jQuery);