/*
 * Scroller class
 * (c) 2008 Przemysław Sitek
 */

function Scroller ()
{
	var outer;					// outer element
	var inner;					// inner element
	var stepWidth = 64;			// step size
	var steps = 3;				// number of steps
	var currentStep = 0;		// current step
	var currentPos = 0;			// current position
	var direction = 0;			// scrolling direction
	var delay = 10;				// delay between animation frames
	var timerId = undefined		// id of the timer
	var stopAt = 0;				// stop marker
	var LEFT = -1;
	var RIGHT = 1;
	var signals = {
		"stopped": [],
		"foo": ['a','b','c']
	};
	
	this.status = function ()
	{
		alert ('currentStep: '+currentStep+'\nsteps: '+steps);
	}
	
	/*
	 * Attach scroller to html element
	 */
	this.attach = function (outerId, innerId)
	{
		outer = document.getElementById (outerId);
		outer.style.overflow = 'hidden';
		
		inner = document.getElementById (innerId);
		inner.style.marginLeft = '0px';
	}
	
	
	/* Accessors */
	
	
	this.setStepSize = function (size)
	{
		stepWidth = size;
	}
	
	this.getStepSize = function ()
	{
		return stepWidth;
	}
	
	this.setSteps = function (n)
	{
		steps = n;
	}
	
	this.getSteps = function ()
	{
		return steps;
	}
	
	
	/* Signals */
	

	/*
	 * Connect handler to signal
	 *
	 * signal - signal name
	 * arg    - callback, may be function or string
	 */
	this.signalConnect = function (signal, arg)
	{
		signals[signal].push (arg);
	}
	
	
	/*
	 * Emit given signal
	 *
	 * signal - signal name
	 * args   - arguments
	 */
	var signalEmit = function (signal, args)
	{
		var sigs = signals[signal];
		for (i = 0; i < sigs.length; i++) {
			var sig = sigs[i];
			if (isString (sig))
				eval (sig);
			else
				sig (this, args);
		}
	}
	
	
	/* Control */
	
	
	this.scrollLeft = function ()
	{
		beginScroll (LEFT);
	}
	
	
	this.scrollRight = function ()
	{
		beginScroll (RIGHT);
	}
	
	
	this.canLeft = function ()
	{
		return currentStep > 0;
	}
	
	this.canRight = function ()
	{
		return currentStep <= steps-2;
	}
	
	/* Private methods */
	
	
	var beginScroll = function (dir)
	{
		if (direction == 0) {
			direction = dir;
			stopAt = (currentStep += direction) * stepWidth;
			window.status = 'Stopping at ' + stopAt;
			timerId = setInterval (timer, delay);
		}
	}
	
	
	var timer = function ()
	{
		currentPos += direction;
		scroll (currentPos);
		if (currentPos ==  stopAt) {
			timerId = clearInterval (timerId);
			direction = 0;
			
			signalEmit ('stopped');
		}
	}
	
	/*
	 * Scroll content to offset px
	 */
	var scroll = function (offset)
	{
		inner.style.marginLeft = -offset+'px';
	}
}



function isString()
{
	if (typeof arguments[0] == 'string') return true;
	if (typeof arguments[0] == 'object') {
		var criterion = arguments[0].constructor.toString().match(/string/i);
		return (criterion != null);
	}
	return false;
}
