Ticker = Class.create();  

Object.extend(Ticker.prototype, {
	initialize: function(id, nb, options) {
		//Default Options
		this._options = {
			tempo: 3,
			slideSpeed: 5,
			slideOpacity: 0.5,
			itemPadding: 3,
			height: 150,
			autofit: false
		}
		
		//Setting up ticker
		this._container = $(id);
		this._ul = this._container.down('ul');
		this._elts = this._container.select('li');
		this.nbDisplayed = typeof(nb) != 'object' ? nb : 2;
		
		//Setting up users options
		Object.extend(this._options, options || {});
		
		//Setting up default values
		this.offset = {id: 1, height: 0, top: 0};
		this.nextOffset = {id: 2, height: 0, top: 0};
		this.currentOffset = 1;		
		this._topOffset = 0;
		this._timeout = null;
		this.scrollInterval = null;
		this._heightOffset = 0;
		this.heightIsOk = true;
		this.margins = [];
		
		//Overiding css rules
		this._ul.style.position = 'absolute';
		this._ul.style.top = this._topOffset;
		this._container.style.height = this._options.height+'px';
		
		this.initScrolling();
		return this;
	},
	
	initScrolling: function() {
		if (this._options.autofit) this._container.style.height = this.offset.height+'px';
		else {
			var h, count, idOffset, margin;
			var h = count = idOffset = 0;
			this._elts.each(function(e){
				count++; h += e.getHeight();
				if (count%this.nbDisplayed == 0) {
					idOffset++;
					if (h < this._options.height) {
						margin = this._options.height - h - this._options.itemPadding;
						e.style.marginBottom = margin+'px';
						this.margins[idOffset] = 0;
					}
					else {
						margin = h - this._options.height  + this._options.itemPadding*this.nbDisplayed;
						this.margins[idOffset] = margin;
					}
					h=0;
				}
			}.bind(this));
		}
		this._getOffsetValues();
		this.doTempo();
	},
	
	scroll: function() {
		this.slideTime = -this._options.slideSpeed;
		if (this._elts.length / this.nbDisplayed < this.currentOffset) {
			this.offset = {id: 0, height: 0, top: 0};
			this.nextOffset = {id: 1, height: 0, top: 0};
			this.currentOffset = 0;		
			this._getOffsetValues();
			this.slideTime = this._options.slideSpeed;
		}
		this.scrollInterval = setInterval(this.doScroll.bind(this), 10);
	},
	
	doScroll: function() {
		this._container.setOpacity(this._options.slideOpacity);
		this._topOffset += this.slideTime;
		var v2 = this.offset.height < this.nextOffset.height ? this._options.slideSpeed : -this._options.slideSpeed;
		this._heightOffset += v2;
		if ((this._topOffset <= this.nextOffset.top || this._topOffset > 0) && this.heightIsOk == true) {
			clearInterval(this.scrollInterval);
			if (this._topOffset > 0) this._topOffset = 0;
			else if (this._topOffset <= this.nextOffset.top) this._topOffset = this.nextOffset.top;
			if (this._options.autofit) this._container.style.height = this.nextOffset.height+'px';
			this._ul.style.top = this._topOffset+'px';
			this.currentOffset++;this.offset.id++;this.nextOffset.id++;
			this._container.setOpacity(1);
			this._getOffsetValues();
			this.doTempo();
		}
		else {
			this._ul.style.top = this._topOffset+'px';
			if (this._options.autofit) {
				if (this._heightOffset >= this.nextOffset.height && v2 > 0) {
					this._container.style.height = this.nextOffset.height+'px';
					this.heightIsOk = true;
				}
				else if (this._heightOffset <= this.nextOffset.height && v2 < 0) {
					this._container.style.height = this.nextOffset.height+'px';
					this.heightIsOk = true;
				}
				else this._container.style.height = this._heightOffset+'px';
			}
		}
	}, 
	
	doTempo: function() {
		this._timeout = setTimeout(this.scroll.bind(this), this._options.tempo*1000);
	}, 
	
	_getOffsetValues: function(offset) {
		if (this._options.autofit) {
			var count =  0;
			var h, nh;
			h = nh = 0;
			this._elts.each(function(e){
				if (count < this.nbDisplayed*this.offset.id) {
					if (this.offset.id == 1) h += e.getHeight();
					else if(this.offset.id != 1 && count >= this.nbDisplayed*(this.offset.id-1)) h += e.getHeight();
				}
				else if (count >= (this.nbDisplayed)*this.offset.id && count < (this.nbDisplayed)*this.offset.id+this.nbDisplayed) nh += e.getHeight();
				count++;
			}.bind(this));
			h+=this._options.itemPadding*this.nbDisplayed;
			nh+=this._options.itemPadding*this.nbDisplayed;
			this.offset.height = h;
			this._heightOffset = h;
			this.nextOffset.height = nh;
			this.offset.top = this._topOffset;
			this.nextOffset.top = this.offset.top-h;
		}
		else {
			this.offset.height = this.nextOffset.height = this._heightOffset = this._options.height;
			this.offset.top = this._topOffset;
			this.nextOffset.top = this.offset.top-this._options.height - this.margins[this.currentOffset];
		}
	}
});

function debug(txt) {
	throw(txt);
}