var DEBUG_SCROLL = false

setupScrollable = function (scrollable) {
	if (scrollable.setup) return
	if (DEBUG_SCROLL) {
		log('clientHeight', scrollable.clientHeight)
		log('scrollHeight', scrollable.scrollHeight)
	}
	setStyle(scrollable, {'overflow':'hidden'})
	scrollable.scroll = bind(function(amount, delay) {
		if (DEBUG_SCROLL) log("scroll",amount,delay)
		if (!this.isVerticalBounded()) return
		try {
			if (this.scrollTimer) clearTimeout(this.scrollTimer)	//	stop timers if there are some
			new_pos = parseInt(this.scrollTop) + parseInt(amount)
			this.scrollTop = parseInt(new_pos)
			this.scrollTimer = setTimeout(partial(this.scroll, amount, delay), delay)
		} catch(e) {
			alert(e.description)
		}
	}, scrollable)
	scrollable.stopScroll = bind(function() {
		if (this.scrollTimer) clearTimeout(this.scrollTimer)
	}, scrollable)
	scrollable.scrollDown = bind(function(delay) {
		this.scroll(delay)
	}, scrollable)
	scrollable.scrollUp = bind(function(delay) {
		this.scroll(delay, true)
	}, scrollable)
	scrollable.scrollTo = bind(function(new_pos) {
		if (this.scrollTimer) clearTimeout(this.scrollTimer)	//	stop timers if there are some
		this.scrollTop = parseInt(new_pos)
	}, scrollable)
	scrollable.isVerticalBounded = bind(function(){
		return this.clientHeight < this.scrollHeight
	}, scrollable)
	scrollable.autoStop = bind(function(delay) {
		this.autoStopTimer = setTimeout(bind(function() {
			this.stopScroll()
			clearTimeout(this.autoStopTimer)
		}, scrollable), delay)
	}, scrollable)

	scrollable.setup = true
}

/**
 * boot the scrollers
 * we trigger controll over the title attribute of the scroller
 * parameters are seperated by ";" and values are applied by "="
 * @param target:<the id of the target element to be scrolled>
 * @param amount:+/-number of units
 * @param delay:ms of time between next scroll
 * @param title:"the title after successful setup"
 */
addLoadEvent(function() {
	forEach(getElementsByTagAndClassName(null, 'scrollable'), function(target){
		setupScrollable(target)
		var values = {
			delay: 1,
			amount: 20,
			title: "",
			autoStop: 150
		}
		var title = getNodeAttribute(target, "title")
		if (title) {
			params = title.split(';')
			for (i in params) {
				var param = params[i].split('=')
				values[param[0]] = param[1]
			}
		}
		setNodeAttribute(target, 'title', 'use your mouse wheel to scroll')

		connect(target, 'onmousewheel', bind(partial(function(amount, delay, autoStop, ev){
			this.scroll((ev.mouse().wheel.y / 3) * amount, delay)
			this.autoStop(autoStop)
			ev.stop()
			ev.stopPropagation()
		}, values.amount, values.delay, values.autoStop), target))
	})

	forEach(getElementsByTagAndClassName(null, 'scroller'), function (scroller) {
		var values = {
			delay: 20,
			title: ""
		}
		var title = getNodeAttribute(scroller, "title")
		if (title) {
			params = title.split(';')
			for (i in params) {
				var param = params[i].split('=')
				values[param[0]] = param[1]
			}
		}
		if (values.target != 'undefined') {
			//	setup target
			var target = $(values.target)
			setupScrollable(target)
			//	connect handler
			connect(scroller, 'onmousedown', bind(partial(function(amount, delay, ev){
				this.scroll(amount, delay)
			}, values.amount, values.delay), target))
			connect(scroller, 'onmouseup', bind(function(ev){
				this.stopScroll()
			}, target))
			connect(scroller, 'onmouseout', bind(function(ev){
				this.stopScroll()
			}, target))
			setNodeAttribute(scroller, 'title', values.title)
		}
	})
})
