var Ticker = Class.create();
Ticker.prototype = {
	initialize: function(id, options) {
		Object.extend(this.options, options);
		this.list = $(id);
		if (this.list) {
			this.items = this.list.getElementsByTagName(this.options.tagName);
			this._setup();
		}
	},
	
	options: {
		delay: 4, // Delay between slides, in seconds
		tagName: 'div', // The name of the tag for each element in the list
		haltOnHover: true, // Should the ticker stop running when a mouse moves over it?
		hideMethod: function(elem) {Element.hide(elem);}, // Effect used to hide an item
		showMethod: function(elem) {new Effect.BlindDown(elem);} // Effect used to show an item
	},
	
	play: function() {
		this._isPaused = false;
		if (!this._timer) this._timer = setInterval(this._run.bind(this), this.options.delay * 1000);
	},
	
	pause: function() {
		this._isPaused = true;
	},
	
	stop: function() {
		clearInterval(this._timer);
		this._isPaused = true;
	},

	/* Private functions */
	
	// sets up the ticker for display
	_setup: function() {
		this._currentIndex = 0;
		this._show();
		if (this.options.haltOnHover) {
			Event.observe(this.list, 'mouseover', this.pause.bind(this));
			Event.observe(this.list, 'mouseout', this.play.bind(this));
		}
		setTimeout(this.play.bind(this), this.options.delay * 1000);
	},
	
	// Hides all but the current item
	_show: function() {
		for (var i=0, item; item = this.items[i]; i++) {
			if (item && item.style) {
				if (i != this._currentIndex) {
					Element.hide(item);
				} else {
					Element.show(item);
				}
			}
		}
	},
	
	_increment: function() {
			this._currentIndex = (this._currentIndex + 1 >= this.items.length) ? 0 : this._currentIndex + 1;
			return this._currentIndex;
	},
	
	// Refreshes the display after the specified time
	_run: function() {
		if (!this._isPaused) {
			var last = this._currentIndex;
			var next = this._increment();

			if (this.items[last]) this.options.hideMethod(this.items[last]);
			if (this.items[next]) this.options.showMethod(this.items[next]);
		}
	}
}
