/*
 * scrollable.js (V.1.0.1)
 * Implements vertical scrolling on DIV layers.
 * @author : Jean Semere (Baggage Claim)
 *
 * You have no right to use or redistribute this code unless Baggage Claim SARL
 * authorizes you to do so.
 *
 */

Scrollable = Class.create();
Scrollable.prototype =
{
	initialize: function(name, options)
	{
		this.busy = false;
		this.name = name;
		this.element = $(this.name);
		options = options || {};
		this.upButton = options.up || false;
		this.downButton = options.down || false;
		if (this.element == null)
		{
			if (this.upButton)
				$(this.upButton).hide();
			if (this.downButton)
				$(this.downButton).hide();
			return;
		}
		this.realHeight = parseInt($(this.name).offsetHeight);
		this.visibleHeight = parseInt($(this.name).parentNode.offsetHeight);
		if (this.upButton)
		{
			$(this.upButton).style.cursor = "pointer";
			Event.observe(this.upButton, 'mousedown', this.upStart.bindAsEventListener(this), false);
		}
		if (this.downButton)
		{
			$(this.downButton).style.cursor = "pointer";
			Event.observe(this.downButton, 'mousedown', this.downStart.bindAsEventListener(this), false);
		}
		Event.observe(document, 'mouseup', this.unlock.bindAsEventListener(this), false);
		Event.observe(this.name, 'DOMMouseScroll', this.scrollWheel.bindAsEventListener(this), false);
		Event.observe(this.name, 'mousewheel', this.scrollWheel.bindAsEventListener(this), false);
		if (this.realHeight <= this.visibleHeight)
		{
			if (this.upButton)
				$(this.upButton).hide();
			if (this.downButton)
				$(this.downButton).hide();
		}
		this.update.bind(this).delay(1);
	},
	
	goToBottom: function()
	{
		if (this.visibleHeight < this.realHeight)
			new Effect.Move(this.element, {y: - (this.realHeight - this.visibleHeight), x: 0, mode:"absolute"});
	},
	
	reinit: function()
	{
		this.update();
		this.element.setStyle({top: "0px"});
	},
	
	goToElement: function(id)
	{
		if (this.element.select("#"+id).length != 0)
			new Effect.Move(this.element, {y: - $(id).offsetTop, x: 0, mode:"absolute"});
	},
	
	update: function()
	{
		this.realHeight = parseInt($(this.name).offsetHeight);
		this.visibleHeight = parseInt($(this.name).parentNode.offsetHeight);
		if (this.realHeight <= this.visibleHeight)
		{
			if (this.upButton)
				$(this.upButton).hide();
			if (this.downButton)
				$(this.downButton).hide();
		}
		else
		{
			if (this.upButton)
				$(this.upButton).show();
			if (this.downButton)
				$(this.downButton).show();
		}
	},
	
	downStart: function()
	{
		this.update();
		this.lock();
		this.downAction();
	},
	
	upStart: function()
	{
		this.update();
		this.lock();
		this.upAction();
	},
	
	downAction: function()
	{
		distance = parseInt($(this.name).offsetTop);
		if (distance - 10 >= this.visibleHeight - this.realHeight)
			$(this.name).setStyle({top: (distance - 10).toString() + "px"})
		else
			$(this.name).setStyle({top: (this.visibleHeight - this.realHeight).toString() + "px"})
		if (this.isLocked())
			this.downAction.bind(this).delay(0.05);
	},
	
	upAction: function()
	{
		this.update();
		distance = parseInt($(this.name).offsetTop);
		if (distance + 10 <= 0)
			$(this.name).setStyle({top: (distance + 10).toString() + "px"})
		else
			$(this.name).setStyle({top: "0px"})
		if (this.isLocked())
			this.upAction.bind(this).delay(0.05);
	},
	
	lock: function()
	{
		this.busy = true;
	},
	
	unlock: function()
	{
		this.busy = false;
	},
	
	isLocked: function()
	{
		return this.busy;
	},
	
	handleWheel: function(delta)
	{
		this.newPosition = this.element.offsetTop + delta*5;
		if (this.newPosition < this.visibleHeight - this.realHeight)
			this.newPosition = this.visibleHeight - this.realHeight;
		if (this.newPosition > 0)
			this.newPosition = 0
		this.element.style.top = this.newPosition.toString() + "px";
	},
	
	scrollWheel: 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;
		if (delta)
			this.handleWheel(delta);
		if (event.preventDefault)
			event.preventDefault();
		event.returnValue = false;
	}
};

