/*
	Class: Impressions
*/
var Impressions = new Class({
	Implements: Options,
							
	options: {
		'positions': 0,
		'rows': 1,
		'transition': Fx.Transitions.Quad.easeInOut,
		'duration': 3000,
		'interval': 5000,
		'autoStart': true,
		'randomPosition': false
	},

	elements: [],

	current: [],
	
	_currentPosition: 0,

	_timer: null,
	
	_currentIndex: 0,
	
	_zIndex: 1,

	/*
		Constructor: initialize
		Speichert die Bilder anhand des Selektors und bereitet sie für die Effekte vor.
	*/
	initialize: function(selector, options){
		this.setOptions(options);
		
		$$(selector).each(function(element, index){
			this.elements.include(element);
			
			if(this.options.positions == 0 && element.get('style').display != 'none') {
				this.options.positions += 1;
			}
			
			element.store('animation', new Fx.Tween(element, {property: 'opacity', duration: this.options.duration, transition: this.options.transition}));
			
			element.set('styles', {
				'display': 'none'
			});
			
			if(index < this.options.positions) {
				this.current[index] = element;	
			}
		}.bind(this));
		
		this.elemWidth  = $$(selector)[0].getStyle('width').toInt();
		this.elemHeight = $$(selector)[0].getStyle('height').toInt();

		for(i=0; i < this.options.positions; i++) {
			this.display(i);
		}
		
		if(this.options.autoStart) {
			this.play();
		}
	},
	
	/*
		Function: play
		Führt die Funktion <next> in einem definierten Interval aus.
	*/
	play: function() {
		this._timer = this.next.periodical(this.options.interval, this);
	},
	
	/*
		Function: pause
		Unterbricht das von <play> gesetzte Interval.
	*/
	pause: function() {
		$clear(this._timer);
	},
	
	/*
		Function: next
		Blendet das nächste Bild ein.
	*/
	next: function() {
		this.display(this._getNextPosition(this.options.randomPosition), true);
	},

	/*
		Function: display
		Zeigt ein neues Bild an.
		
		Parameters:
			position - (integer) Index der Position, an der das Bild dargestellt werden soll.
			animation - (boolean, optional) Bild mit einer Animation einblenden oder nicht.
	*/
	display: function(position, animate) {
		var element = this._getElement();
		var row = Math.ceil((position+1) / (this.options.positions / this.options.rows));

		element.setStyle('display', 'none');

		element.setStyles({
			   'position': 'absolute',
			   'left': position * this.elemWidth - ((row-1) * (this.options.positions / row) * this.elemWidth),
			   'top': (row-1) * this.elemHeight,
			   'z-index': this._zIndex
		});
		
		this._zIndex += 1;
		
		//element.getParent().grab(element, 'top');
		
		if(animate) {
			var fx = element.retrieve('animation');
			fx.set(0);
			
			element.setStyle('display', 'block');
			
			fx.start(0, 1);
		} else {
			element.setStyle('display', 'block');
		}
		
		this.currentPosition = position;
		this.current[position] = element;
	},

	/*
		Function: _getPosition
		Gibt eine Position zurück.
		
		Parameters:
			getRandom - (boolean, optional: defaults to true) Zufällige position oder nächste Position.
	*/	
	_getNextPosition: function(getRandom) {
		if(getRandom) {
			var newPos = $random(0, (this.options.positions-1));
			if(this.options.positions > 1 && newPos == this.lastPosition) {
				return this._getNextPosition(true);
			} else {
				this._currentPosition = newPos;
				return newPos;
			}
		} else {
			if(this._currentPosition == this.options.positions) {
				this._currentPosition = 0;
			}
			
			var newPosition = this._currentPosition;
			
			this._currentPosition++;
			return newPosition;
		}
	},
	
	_getElement: function() {
		if(this._currentIndex == this.elements.length) {
			this._currentIndex = 0;
		}
		
		var element = this.elements[this._currentIndex];
		
		this._currentIndex++;
		return element;
	}
});