function HTScroller(element, descriptor) {
	var items = [];
	var y = 0;
	var y0 = 0;
	var bounds = jgtc.getBounds(element);
	var height;
	var over = false;
	var drag = false;
	var wasMove = false;
	var overTimer = 0;

	// init.
	(function() {
		descriptor = jgtc.validateObject(descriptor, [
			[ 'speed', 'number', 1 ],
			[ 'overSpeed', 'number', 12 ],
			[ 'autoMove', 'boolean', true ]
		], true);

		var y1 = 0;
		var idx = 0;
		for(var e = element.firstChild; e != null; e = e.nextSibling) {
			if(e.nodeType == 1) {
				var itemd;
				if((itemd = jgtc.safeGetAttribute(e, 'ht:scrollerItem')) != null) {
					try {
						eval("itemd = {" + itemd + "};");
					} catch(err) {
						console.warn("");
						continue;
					}

					var b = jgtc.getBounds(e);
					e.htScrollerItemIndex = idx;
					itemd.__index = idx++;
					items.push({ 'element': e, 'descriptor': itemd, 'x': 0, 'y': y1 });
					y1 += b.h;

//					console.log("e: %o, itemd: %o", e, itemd);
				}
			}
		}

		height = y1;
	})();

	function _pos() {
		if(y < 0) y += height;
		else if(y > height) y -= height;

		for(var i = 0; i < items.length; i++) {
			var y1 = items[i].y + y;
			if(y1 > bounds.h) y1 -= height;

			items[i].element.style.top = y1 + 'px';
		}
	}

	function _drag(e) {
		if(!e) e = event;
		jgtc.discardEvent(e)

		var y1 = e.clientY;
		var dy = y1 - y0;

		if(wasMove || Math.abs(dy) > 5) {
			y += dy;
			y0 = y1;
			wasMove = true;
			_pos();
		}
	}

	function _up(e) {
		if(!e) e = event;
		jgtc.discardEvent(e)

		jgtc.releaseEvent(document, 'mousemove', _drag, false);
		jgtc.releaseEvent(document, 'mouseup', _up, false);

		drag = false;
	}

	_pos();

	jgtc.captureEvent(element, 'mouseover', function() {
		over = true;
	}, true);

	jgtc.captureEvent(element, 'mouseout', function() {
		over = false;
	}, true);

	jgtc.captureEvent(element, 'mousedown', function(e) {
		if(!e) e = event;
		jgtc.discardEvent(e)

		jgtc.captureEvent(document, 'mousemove', _drag, false);
		jgtc.captureEvent(document, 'mouseup', _up, false);

		y0 = e.clientY;
		wasMove = false;
		drag = true;
		overTimer = descriptor.overSpeed;
	}, true);

	jgtc.captureEvent(element, 'click', function(e) {
		if(!e) e = event;
		if(wasMove) {
			jgtc.discardEvent(e);
		} else {
			for(var e1 = is.ie ? e.srcElement : e.target; e1 != null; e1 = e1.parentNode) {
				if('htScrollerItemIndex' in e1) {
					var e1d = items[e1.htScrollerItemIndex].descriptor;
					if('href' in e1d) {
						var target;
						if('target' in e1d) {
							target = e1d.target;
						} 
						if(!target) {
							target = '_self';
						}

						jgtc.discardEvent(e);
						window.open(e1d.href, target);
					}
				}
			}
		}
	}, true);

	if(descriptor.autoMove) {
		window.setInterval(function() {
			if(!drag) {
				if(over) {
					if(overTimer < descriptor.overSpeed) {
						overTimer++;
					}
				} else {
					if(overTimer > 0) {
						overTimer--;
					}
				}
				var sm = 0.5 - Math.cos((descriptor.overSpeed - overTimer) / descriptor.overSpeed * Math.PI) / 2;

				if(sm != 0) {
					y -= descriptor.speed * sm;
					_pos();
				}
			}
		}, 40);
	}
}

jgtc.captureEvent(window, 'load', function() {
	console.log("scroller.js");

	var tags = document.getElementsByTagName("*");
	for(var i = 0; i < tags.length; i++) {
		var scr = jgtc.safeGetAttribute(tags[i], "ht:scroller");
		if(scr != null) {
			var d;
			try {
				eval('d = {' + scr + '};');
			} catch(err) {
				console.warn("Hibás scroller descriptor: %s, %o", scr, err);
				continue;
			}
			new HTScroller(tags[i], d);
		}
	}
}, false);
