/**
 * Object jacIDScroller
 * 
 * @super Object
 * @constructor
 * @memberOf {jacIDScroller}
 * @param scrolling_id The id of the element which will be scrolled.
 * @param scroll_point_ids_array Array of IDs of elements at which the scrolling will stop.
 * @param max_scroll_pixels Maximum amount of pixels the scroller can move at one time, if the scroll_points
 * 		are longer, it will stop in between.
 * @param orientation Ether "vertical" or "horizontal".  Not yet implemented.
 */
function jacIDScroller(scrolling_id, scroll_point_ids_array, max_scroll_pixels, orientation)
{
	this._scroll_elem_id = scrolling_id;
	this._scroll_elem = $(scrolling_id);
	this._scroll_points = $A(scroll_point_ids_array);

	this._top_scroll = 0;
	this._scroll_amounts = new Array();
	// use a manual loop as scroll_points array might be large.  Initial scroll amount is three pixels because of descenders
	// on characters in the previous line being in view.
	var point_elem = null, offset = 0, prev_offset = 0;
	for(var i = 0, len = this._scroll_points.length; i < len; ++i)
	{
		point_elem = $(this._scroll_points[i]);
		if(point_elem == null)
			continue;
		offset = point_elem.offsetTop;
		prev_offset = i > 0 ? this._scroll_amounts[i-1].get('offset') : 0;
		this._scroll_amounts.push(new Hash({valid: true, scroll_amount: offset - prev_offset, offset: offset}));
	}
//	this._scroll_amounts[0].set('scroll_amount', this._top_scroll);
//	this._scroll_amounts[0].set('offset', this._top_scroll);
//	this._scroll_amounts[0].set('valid', true);

	this._cur_scroll = 0;
	this._max_scroll = this._scroll_points.length > 0 ? this._scroll_points.length - 1 : 0;

	this._cur_offset = this._top_scroll;

	this._max_pixels = max_scroll_pixels;

	//TODO:  Implement the orientation
	this._orient = (orientation == 'vertical' || orientation == 'horizontal') ? orientation.charAt(0) : 'v';

	this._allow_scroll = true;
}
jacIDScroller.prototype = new Object();
jacIDScroller.prototype._scroll_elem_id;
jacIDScroller.prototype._scroll_elem;
jacIDScroller.prototype._scroll_points;
jacIDScroller.prototype._scroll_amounts;
jacIDScroller.prototype._cur_scroll;
jacIDScroller.prototype._max_scroll;
jacIDScroller.prototype._max_scroll_pixels;
jacIDScroller.prototype._orient;
jacIDScroller.prototype._allow_scroll;

jacIDScroller.prototype._check_id =
	function()
	{
		return this._scroll_elem != null;
	};

jacIDScroller.prototype._scroll_starting =
	function()
	{
		this._allow_scroll = false;
	};
jacIDScroller.prototype._scroll_finished =
	function()
	{
		this._allow_scroll = true;
	};

jacIDScroller.prototype.scroll_forward =
	function(e)
	{
		if(!this._allow_scroll)
			return;
		if(!this._check_id())
			return;
		if(this._cur_scroll >= this._max_scroll)
			return;
		var index = ++this._cur_scroll, scroll_amount = 0;
		var scroll_amounts_elem = this._scroll_amounts[index], prev_scroll_amounts_elem = this._scroll_amounts[index-1];
		if(!scroll_amounts_elem.get('valid')) // || scroll_amounts_elem.get('scroll_amount') > this._max_pixels)
		{
//			alert(prev_scroll_amounts_elem.get('offset'));
			var point_elem = $(this._scroll_points[index]);//, prev_point_elem = $(this._scroll_points[index - 1]);
			if(point_elem == null)// || prev_point_elem == null)
				return;
			alert(point_elem.offsetTop);
			alert(prev_scroll_amounts_elem.get('offset'));
			scroll_amount = point_elem.offsetTop - prev_scroll_amounts_elem.get('offset');
			alert(scroll_amount);
			scroll_amounts_elem.set('scroll_amount', scroll_amount);
			scroll_amounts_elem.set('offset', point_elem.offsetTop);
			scroll_amounts_elem.set('valid', true);
		}
		else
			scroll_amount = scroll_amounts_elem.get('scroll_amount');
		

		if(scroll_amount > this._max_pixels)
		{
			scroll_amounts_elem.set('scroll_amount', scroll_amounts_elem.get('scroll_amount') - this._max_pixels);
			this._scroll_amounts.splice(index, 0, new Hash({valid: true, scroll_amount: this._max_pixels,
					offset: prev_scroll_amounts_elem.get('offset') + this._max_pixels}));
			this._scroll_points.splice(index, 0, '');
			scroll_amount = this._max_pixels;
			++this._max_scroll;
		}
		
		this._cur_offset += scroll_amount;
		new Effect.Move(this._scroll_elem_id, {y: -scroll_amount, mode: 'relative', beforeStart: this._scroll_starting.bind(this),
				afterFinish: this._scroll_finished.bind(this)});

		Event.stop(e);
	};

jacIDScroller.prototype.scroll_backward =
	function(e)
	{
		if(!this._allow_scroll)
			return;
		if(!this._check_id())
			return;
		if(this._cur_scroll <= 0)
			return;

		var index = this._cur_scroll--, scroll_amount = 0;
		var scroll_amounts_elem = this._scroll_amounts[index];
		if(!scroll_amounts_elem.get('valid'))
		{
			var point_elem = $(this._scroll_points[index-1]);
			if(point_elem == null)
				return;
			scroll_amount = this._cur_offset - point_elem.offsetTop;
			scroll_amounts_elem.set('scroll_amount', scroll_amount);
			scroll_amounts_elem.set('offset', point_elem.offsetTop);
			scroll_amounts_elem.set('valid', true);
		}
		else
			scroll_amount = scroll_amounts_elem.get('scroll_amount');
		this._cur_offset -= scroll_amount;
		new Effect.Move(this._scroll_elem_id, {y: scroll_amount, mode: 'relative', beforeStart: this._scroll_starting.bind(this),
				afterFinish: this._scroll_finished.bind(this)});

		Event.stop(e);
	};


jacIDScroller.prototype.scroll_top =
	function(e)
	{
		if(!this._allow_scroll)
			return;
		if(!this._check_id())
			return;
		if(this._cur_scroll <= 0)
			return;

		this._cur_scroll = 0;
		new Effect.Move(this._scroll_elem_id, {y: this._cur_offset - this._top_scroll, mode: 'relative',
			beforeStart: this._scroll_starting.bind(this), afterFinish: this._scroll_finished.bind(this)});
		this._cur_offset = this._top_scroll;
	
		Event.stop(e);
	};

jacIDScroller.prototype.scroll_bottom =
	function(e)
	{
		if(!this._allow_scroll)
			return;
		if(!this._check_id())
			return;
		if(this._cur_scroll >= this._max_scroll)
			return;
	
		this._cur_scroll = this._max_scroll;
		var point_elem = $(this._scroll_points[this._cur_scroll]);
		if(point_elem == null)
			return;
		var scroll_amount = point_elem.offsetTop - this._cur_offset;
		new Effect.Move(this._scroll_elem_id, {y: -scroll_amount, mode: 'relative',
			beforeStart: this._scroll_starting.bind(this), afterFinish: this._scroll_finished.bind(this)});
		this._cur_offset += scroll_amount;
	
		Event.stop(e);
	};
