/**
 * Object scrolls subcontainer of $container in desired direction using mootools
 *
 * @author Henning Künne
 * $Id: RemoteScroller.js 203 2009-08-06 08:04:42Z pn $
 */

/**
 * Constructor
 *
 * @param OBJECT settings
 *
 *
 {
	container:idOfcontainer	STRING	(mandatory)
	fps:framesPerSecond	INT	(optional, defaults to 25)
	step:pixelsToScrollBy	INT	(optional, defaults to 20)
 }
 */
var RemoteScroller = function (settings) {
	if (typeof settings == 'undefined') {
		throw('No settings given');
	}
	if (typeof settings.container == 'undefined') {
		throw('No id given. Specify id of container to be scrolled');
	}
	if (typeof settings.buttons == 'undefined') {
		throw('Specify buttons')
	}
	if (typeof settings.startEvent == 'undefined') {
		throw('Specify startevent')
	}
	if (typeof settings.stopEvent == 'undefined') {
		throw('Specify stopevent')
	}
	this.container = settings.container; // fetch container to scroll
	if (typeof settings.hideScrollBars != 'undefined' && settings.hideScrollBars === true) {
		this.container.style.overflow = 'hidden';
	}
	this.maxScrollLeft = this.container.getScrollWidth() - this.container.clientWidth;
	this.maxScrollTop = this.container.getScrollHeight() - this.container.clientHeight;
	this.startEvent = settings.startEvent || 'mousedown';
	this.stopEvent = settings.stopEvent || 'mouseup';
	this.fps = settings.fps || 25;
	this.step = settings.step || 20;

	var that = this;	// closure
	for (var i in settings.buttons) {
		settings.buttons[i].RemoteScrollButtonDir = i;
		settings.buttons[i].addEvent(this.startEvent, function () {
			that.startScroll(this);
		});
		settings.buttons[i].addEvent(this.stopEvent, function () {
			that.stopScroll(this);
		});
	}

	this.callbacks = {};
	this.callbacks.start = function (button) {
		if (typeof settings.onscrollstart == 'function') {
			settings.onscrollstart(button);
		} else return
	}
	this.callbacks.stop = function (button) {
		if (typeof settings.onscrollstop == 'function') {
			settings.onscrollstop(button);
		} else return
	}
	
	this.scrollable = this.getScrollable();
}

/**
 * Invoke the scrolling process by setting an interval
 *
 */
RemoteScroller.prototype.startScroll = function (button) {
	this.callbacks.start({button:button,scrollableButtons:this.getScrollable()});
	this.scrollInterval = window.setInterval(function (){
		this.scroll(button);
	}.bind(this), Math.round(1000/this.fps))
}

/**
 * scroll the container
 */
RemoteScroller.prototype.scroll = function (button) {
	switch (button.RemoteScrollButtonDir) {
		case 'left':
			if (this.scrollInterval && this.container.getScrollLeft() >= this.maxScrollLeft) {
				this.stopScroll(button, true);
			} else {
				this.container.scrollTo(this.container.getScrollLeft()+this.step, this.container.getScrollTop());
			}
			break;
		case 'right':
			if (this.scrollInterval && this.container.getScrollLeft() <= 0) {
				this.stopScroll(button, true);
			} else {
				this.container.scrollTo(this.container.getScrollLeft()-this.step, this.container.getScrollTop());
			}
			break;
		case 'up':
			if (this.scrollInterval && this.container.getScrollTop() <= 0) {
				this.stopScroll(button, true);
			} else {
				this.container.scrollTo(this.container.getScrollLeft(), this.container.getScrollTop()-this.step);
			}
			break;
		case 'down':
			if (this.scrollInterval && this.container.getScrollTop() >= this.maxScrollTop) {
				this.stopScroll(button, true);
			} else {
				this.container.scrollTo(this.container.getScrollLeft(), this.container.getScrollTop()+this.step);
			}
			break;
	}
}

/**
 * Stop scrolling by clearing the Interval
 */
RemoteScroller.prototype.stopScroll = function (button, stopPropagation) {
	if (!stopPropagation)
		this.callbacks.stop({button:button,scrollableButtons:this.getScrollable()});
	if (this.scrollInterval) window.clearInterval(this.scrollInterval);
}

/**
 * Get scrollable directions
 *
 * @return OBJECT
 */
RemoteScroller.prototype.getScrollable = function () {
	var that = this;	// closure
	return {
		left:function () {
			return that.container.getScrollLeft() < that.maxScrollLeft ? true : false;
		}(),
		right:function () {
			return that.container.getScrollLeft() > 0 ? true : false;
		}(),
		up:function () {
			return that.container.getScrollTop() > 0 ? true : false;
		}(),
		down:function () {
			return that.container.getScrollTop() < that.maxScrollTop ? true : false;
		}()
	}
}

