var REPEAT_DELAY = 500;
var SCROLLING_SPEED = 10;

var CustomScrollBar = Class.create();

CustomScrollBar.prototype =
{
	// ScrollBar Constructor
	initialize: function(container, direction, content, scrollBar, track, cursor, keepOffset, evolvingContent)
	{
		this.direction = direction;
		this.scrollContent = content;
		this.scrollBar = scrollBar;
		this.scrollTrack = track;
		this.scrollCursor = cursor;
		this.keepOffset = keepOffset;
		this.evolvingContent = evolvingContent;

		// Initialize state variables
		this.isScrolling = false;
		this.isDragging = false;

		// Get the Container size
		this.h = $(container).getHeight();
		this.w = $(container).getWidth();

		// Load ScrollBar
		this.loadScrollBar(false);
	},

	// ScrollBar reInit
	loadScrollBar: function(reload)
	{
		// Get the Content size and compute ScrollBar Properties
		this.setScrollBarProperties();

		// ScrollBar size
		this.setScrollBarSize();

		// Content and cursor positions
		if (this.keepOffset && reload)
			this.setPositions();
		else
			this.initPositions(0, 0, 0);

		// Display ScrollBar depending on the Content size
		this.displayScrollBar();
	},



	// ScrollBar Settings
	setScrollBarProperties: function()
	{
		this.ch = $(this.scrollContent).getHeight();
		this.cw = $(this.scrollContent).getWidth();
		this.vseek = this.h-30 == 0 ? 0 : (this.ch-this.h)/(this.h-30);
		this.hseek = this.w-30 == 0 ? 0 : (this.cw-this.w)/(this.w-30);
		this.vspeed = this.ch-this.h == 0 ? 0 : this.h/(this.ch-this.h) * 10;
		this.hspeed = this.cw-this.w == 0 ? 0 : this.w/(this.cw-this.w) * 10;
	},
	
	setScrollBarSize: function()
	{
		if (this.direction == 'HORIZONTAL')
		{
			$(this.scrollBar).style.width = (this.w+10) + "px";
			$(this.scrollBar).style.height = "10px";
			$(this.scrollTrack).style.width = (this.w-20) + "px";
			$(this.scrollTrack).style.height = "10px";
		}
		if (this.direction == 'VERTICAL')
		{
			$(this.scrollBar).style.width = "10px";
			$(this.scrollBar).style.height = this.h + "px";
			$(this.scrollTrack).style.width = "10px";
			$(this.scrollTrack).style.height = (this.h > 30 ? this.h-20 : 10) + "px";
		}
	},

	setPositions: function()
	{
		if (this.direction == 'VERTICAL')
		{
			// Set offset new position
			this.offset = -this.top / this.vseek;

			// If offset is unbounded, place it at the end
			if (this.offset > this.h-30 || this.evolvingContent)
			{
				this.offset = this.h-30;
				this.top = -this.offset*this.vseek;
			}

			// When SrollBar has to disappear
			if (this.ch-this.h <= 0)
				this.top = 0;
		}

		if (this.direction == 'HORIZONTAL')
		{
			// Set offset new position
			this.offset = -this.left / this.hseek;

			// If offset is unbounded, place it at the end
			if (this.offset > this.w-30 || this.evolvingContent)
			{
				this.offset = this.w-30;
				this.left = -this.offset*this.hseek;
			}

			// When SrollBar has to disappear
			if (this.cw-this.w <= 0)
				this.left = 0
		}

		this.initPositions(this.top, this.left, this.offset);
	},
	
	initPositions: function(top, left, offset)
	{
		this.top = top;
		this.left = left;
		this.offset = offset;

		if (this.direction == 'VERTICAL')
		{
			$(this.scrollContent).style.top = top + "px";
			$(this.scrollCursor).style.top = offset + "px";
		}

		if (this.direction == 'HORIZONTAL')
		{
			$(this.scrollContent).style.left = left + "px";
			$(this.scrollCursor).style.left = offset + "px";
		}
	},

	displayScrollBar: function()
	{
		$(this.scrollBar).style.display = (this.direction == 'VERTICAL' && this.ch-this.h > 0 ||
										   this.direction == 'HORIZONTAL' && this.cw-this.w > 0) ? "inline" : "none";
	},



	// ScrollBar Moving
	scroll_up: function()
	{
		if (this.isScrolling)
		{
			this.setOffsetPosition(this.offset - this.vspeed);
			if (this.offset >= 0)
			{
				var self = this;
				setTimeout(function() {self.scroll_up();}, delay);
			}
		} 
	},

	scroll_down: function()
	{
		if (this.isScrolling)
		{
			this.setOffsetPosition(this.offset + this.vspeed);
			if (this.offset <= this.h-30)
			{
				var self = this;
				setTimeout(function() {self.scroll_down();}, delay);
			}
		}
	},

	scroll_left: function()
	{
		if (this.isScrolling)
		{
			this.setOffsetPosition(this.offset - this.hspeed);
			if (this.offset >= 0)
			{
				var self = this;
				setTimeout(function() {self.scroll_left();}, delay);
			}
		}
	},

	scroll_right: function()
	{
		if (this.isScrolling)
		{
			this.setOffsetPosition(this.offset + this.hspeed);
			if (this.offset <= this.w-30)
			{
				var self = this;
				setTimeout(function() {self.scroll_right();}, delay);
			}
		} 
	},

	handleClickSpeed: function()
	{
		if (!first_click)
			delay = SCROLLING_SPEED;
		if (first_click)
			first_click = false;
	},

	setOffsetPosition: function(value)
	{
		this.handleClickSpeed();

		this.offset = value;
		if (this.offset < 0)
			this.offset = 0;

		if (this.direction == 'VERTICAL')
		{
			if (this.offset > this.h-30)
				this.offset = this.h-30;
			
			this.top = -this.offset*this.vseek;
			
			$(this.scrollContent).style.top = this.top+"px";
			$(this.scrollCursor).style.top = this.offset+"px";
		}

		if (this.direction == 'HORIZONTAL')
		{
			if (this.offset > this.w-30)
				this.offset = this.w-30;
			
			this.left = -this.offset*this.hseek;
			
			$(this.scrollContent).style.left = this.left+"px";
			$(this.scrollCursor).style.left = this.offset+"px";
		}
	}
};

var sb = new Array();
var current_scrolling = 0;
var mouse_x = -1;
var mouse_y = -1;
var current_offset = 0;
var delay = REPEAT_DELAY;
var first_click = true;

function initScrollBar(instance, direction, container, content, scrollBar, track, cursor, keepOffset, evolvingContent)
{
	if (sb[instance])
		sb[instance].loadScrollBar(true);
	else
		sb[instance] = new CustomScrollBar(container, direction, content, scrollBar, track, cursor, keepOffset, evolvingContent);
}

function scrollingUp(i)
{
	sb[i].isScrolling = true;
	sb[i].scroll_up();
}

function scrollingDown(i)
{
	delay = REPEAT_DELAY;
	first_click = true;
	sb[i].isScrolling = true;
	sb[i].scroll_down();
}

function scrollingLeft(i)
{
	sb[i].isScrolling = true;
	sb[i].scroll_left();
}

function scrollingRight(i)
{
	sb[i].isScrolling = true;
	sb[i].scroll_right();
}

function stopScroll(i)
{
	sb[i].isScrolling = false;
	delay = REPEAT_DELAY;
	first_click = true;
}

function startDrag(i)
{
	current_scrolling = i;
	
	document.onmousemove = drag;
	document.onmouseup = stopDrag;
	
	return false;
}

function drag(e)
{
	/*var ie=document.all;
	var nn6=document.getElementById && !document.all;*/

	if (!e)
		e = window.event

	if (mouse_x == -1 && mouse_y == -1)
	{
		/*mouse_x = nn6 ? e.clientX : event.clientX;
		mouse_y = nn6 ? e.clientY : event.clientY;*/
		mouse_x = e.clientX;
		mouse_y = e.clientY;
		current_offset = sb[current_scrolling].offset;
	}

	/*if (sb[current_scrolling].direction == 'HORIZONTAL')
		sb[current_scrolling].setOffsetPosition((nn6 ? e.clientX : event.clientX) - mouse_x + current_offset);
	if (sb[current_scrolling].direction == 'VERTICAL')
		sb[current_scrolling].setOffsetPosition((nn6 ? e.clientY : event.clientY) - mouse_y + current_offset);*/
	if (sb[current_scrolling].direction == 'HORIZONTAL')
		sb[current_scrolling].setOffsetPosition(e.clientX - mouse_x + current_offset);
	if (sb[current_scrolling].direction == 'VERTICAL')
		sb[current_scrolling].setOffsetPosition(e.clientY - mouse_y + current_offset);
		
	return false;
}

function stopDrag()
{
	current_scrolling = 0;
	mouse_x = -1;
	mouse_y = -1;
	document.onmousemove = null;
	document.onmouseup = null;
}


