function scroller(name, divid, delay, incr, pause)
{
	this.name        = name;
	this.div         = document.getElementById(divid);
	this.size        = Math.abs(parseInt(this.div.style.height));
	this.pos         = 0;
	this.nextPos     = 0;
	this.delay       = delay;
	this.pause       = pause;
	this.incr        = incr;
	this.timer       = 0;
	this.pauseTimer  = 0;
	this.relativeY   = false;
	this.mouseIsDown = false;
	this.fixedMode   = false;
	this.cursor      = "move";

	this.run = function()
	{
		if (this.pos <= this.nextPos) {
			var incr;
			// calcul le déplacement
			if (this.nextPos - this.pos <= this.incr) {
				incr = Math.ceil((this.nextPos - this.pos)/2);
				if (incr > this.incr){
					incr = this.incr;
				} else if (incr == 0) {
					incr = 1;
				}
			} else {
				incr = this.incr;
			}
			// effectue le déplacement
			this.pos += incr;
			this.div.scrollTop = this.pos;

			if (this.div.scrollTop != this.pos) {
				// On arrive au bout du slide
				this.stop();
				setTimeout((function()
				{
					// On repart au début
					var bck = this.pause;
					this.pause = 0;
					this.start();
					this.pause = bck;
				}).bind(this), this.pause);
			}
		} else {
			this.stop();
			this.pauseTimer = window.setTimeout(this.name+'.next()', this.pause);
		}
	}

	this.start = function()
	{
		this.stop();
		this.pos     = 0;
		this.nextPos = 0;
		this.pauseTimer = window.setTimeout(this.name+'.next()', this.pause);
	}

	this.next = function()
	{
		this.pos     = this.nextPos;
		this.nextPos += this.size;
		this.stop();
		this.timer = window.setInterval(this.name+'.run()', this.delay);
	}

	this.stop = function()
	{
		window.clearInterval(this.timer);
		window.clearInterval(this.pauseTimer);
	}

	this.restart = function()
	{
		this.pos = Math.abs(this.div.scrollTop);
		this.nextPos = 0;
		while(this.nextPos < this.pos) {
			this.nextPos += this.size;
		}
		this.stop();
		this.timer = window.setInterval(this.name+'.run()', this.delay);
	}

	this.mouseover = function(e)
	{
		if (!this.fixedMode){
			var relatedElmt;
			if (!e) {
				relatedElmt = window.event.fromElement;
			} else {
				relatedElmt = e.relatedTarget;
			}
			if (!this.relatedIsIn(relatedElmt)) {
				this.div.style.cursor = this.cursor;
				this.stop();
			}
		}
	}

	this.mouseout = function(e)
	{
		if (!this.fixedMode) {
			var relatedElmt;
			if (!e) {
				relatedElmt = window.event.toElement;
			} else {
				relatedElmt = e.relatedTarget;
			}
			if (!this.relatedIsIn(relatedElmt)) {
				this.div.style.cursor = "default";
				this.restart();
			}
		}
	}

	this.mousedown = function(e)
	{
		if (!e) var e = window.event;
		this.relativeY = e.clientY;
		this.mouseIsDown = true;
		return false;
	}

	this.mouseup = function(e)
	{
		this.relativeY = false;
		this.mouseIsDown = false;
		return false;
	}

	this.mousemove = function(e)
	{
		if (this.mouseIsDown && !this.fixedMode) {
			if (!e) var e = window.event;
			this.scroll(this.relativeY - e.clientY);
			this.relativeY = e.clientY;
		}
	}

	this.mouseWheel = function(e, ref)
	{
		if (e) {
			this.scroll(10*e.detail);
			e.preventDefault();
		} else {
			if (ref == this.div) {
				this.scroll(-window.event.wheelDelta);
			}
			return false;
		}
	}

	this.scroll = function(l)
	{
		var newPos = this.div.scrollTop + l;
		this.div.scrollTop += l;
		if (newPos > this.div.scrollTop) {
			this.div.scrollTop = newPos - this.div.scrollTop;
		} else if (newPos < this.div.scrollTop) {
			this.div.scrollTop = this.div.scrollHeight - (this.div.scrollTop - newPos);
		}
	}

	this.dblclick = function(e)
	{
		if (this.fixedMode) {
			this.cursor = "move";
			this.fixedMode = false;
			this.div.style.MozUserSelect = "none";
			this.div.onselectstart = function(){return false;};
			this.restart();
		} else {
			this.cursor = "text";
			this.fixedMode = true;
			this.div.style.MozUserSelect = "";
			this.div.onselectstart = function(){return true;};
			this.stop();
		}
		this.div.style.cursor = this.cursor;
	}

	/* Cherche si l'objet relatif à l'évènement est un sous-élement */
	this.relatedIsIn = function(reltg)
	{
		while (reltg && reltg != this.div && reltg.nodeName != 'BODY')
			reltg= reltg.parentNode;
		if (reltg && reltg == this.div)
			return true;
		return false;
	}

	// Clone le premier élément à la fin
	var firstItem = null;
	var lastItem = null;
	for (var i = 0; i < this.div.children.length; i++) {
		if (this.div.children[i].nodeName == 'NOSCRIPT' || this.div.children[i].nodeName == 'SCRIPT') {
			continue;
		}
		if (firstItem === null) {
			firstItem = this.div.children[i];
		}
		lastItem = this.div.children[i];
	}
	this.div.insertBefore(firstItem.cloneNode(true), lastItem.nextSibling); // tricky insert l’élément après le dernier
	this.size = Math.abs(parseInt(this.div.style.height));
	this.incr++;


	/* Désactive la sélection */
	this.div.style.MozUserSelect = "none";
	this.div.onselectstart = function()
	{
		return false;
	};

	if (document.addEventListener) eval("this.div.addEventListener('DOMMouseScroll', function(e){"+this.name+".mouseWheel(e);}, false)");
	else eval("this.div.onmousewheel = function(){return "+this.name+".mouseWheel(0, this);};");

	var events = ['mouseover', 'mouseout', 'mousedown', 'mouseup', 'mousemove', 'dblclick'];
	for(ev in events) {
		try{eval("this.div.on"+events[ev]+" = function(e){"+this.name+"."+events[ev]+"(e);}");}
		catch(e){}
	}

	this.start();
}
