newsScroller = new Class({
	Implements: [Chain, Events, Options],

	options: {
		current:    0,
		delay:      2000,
		direction:  "up",
		itemHeight: 100,
		speed:      300,
		total:      0
	},

	initialize: function(el, options) {
		this.setOptions(options);
		this.newsScrollerContainer = $(el);
		this.newsScroller = 'ul' === this.newsScrollerContainer.get('tag') ? this.newsScrollerContainer : this.newsScrollerContainer.getElements('ul')[0];

		this.items = this.newsScroller.getChildren('li');
		this.options.total = this.items.length;
		this.newsScrollerContainer.addClass('newsScroller');
		this.newsScrollerContainer.setStyle('height', this.options.itemHeight);
		this.items.setStyle('height', this.options.itemHeight);

		this.newsScrollerContainer.addEvents({
			'mouseenter': this._stop.bind(this),
			'mouseleave': this._run.bind(this)
		});

		if ( 1 < this.options.total ) {
			this.newsScrollerInfo = new Element('div', {
				'class': "info",
				'html': "<span>" + this._getInfo() + "</span>"
			}).inject(this.newsScroller, 'after');
			var rw = new Element('a', {'html': "&laquo; ", 'href': "javascript:void(0);", 'events': {'click': this.goTo.bind(this, '-1')}}).inject(this.newsScrollerInfo, 'top');
			var ff = new Element('a', {'html': " &raquo;", 'href': "javascript:void(0);", 'events': {'click': this.goTo.bind(this, '+1')}}).inject(this.newsScrollerInfo);

			this._run();
		}; // endif
	},

	goTo: function(item) {
		if ( 'string' === $type(item) ) {
			if ( "-1" === item ) {
				this.options.direction = "down";
			}; // endif
		}; // endif

		this._run();
		this._switch();
	},

	_run: function() {
		this._stop();
		this.autorun = this._switch.periodical(this.options.delay, this);
	},

	_stop: function() {
		$clear(this.autorun);
	},

	_getInfo: function() {
		return (this.options.current +1) + " von " + this.options.total;
	},

	_switch: function(item) {
		if ( this.newsScrollerInfo == undefined )
			return false;

		if ( 'down' === this.options.direction ) {
			var last = this.newsScroller.getLast('li');
			last.setStyles({
				'margin-top': '-' + this.options.itemHeight,
				'opacity': 0
			});
			this.newsScroller.grab(last, 'top');
		}; // endif

		var current = $defined(last) ? last : this.items[this.options.current];

		if ( 'down' === this.options.direction )
			this.options.current = 0 < this.options.current ? this.options.current -1 : (this.options.total-1);
		else
			this.options.current = this.options.current >= ( this.options.total - 1 ) ? 0 : this.options.current +1;

		var slideOut = new Fx.Morph(current, {
			duration: this.options.speed,
			transition: Fx.Transitions.Linear,
			wait: false
		});

		var marginTop = 'down' === this.options.direction ? 0 : ( "-" + this.options.itemHeight );
		var opacity = 'down' === this.options.direction ? 1 : 0;

		this.newsScrollerInfo && this.newsScrollerInfo.getFirst('span').set('text', this._getInfo());

		slideOut.start({
			'margin-top': marginTop,
			'opacity': opacity
		}).chain(function() {
			if ( 'up' === this.options.direction )
				this.newsScroller.grab(current);

			current.setStyles({
				'margin-top': 0,
				'opacity': 1
			});
			this.options.direction = "up";
		}.bind(this));
	}
});