var Panels = Fx.Elements.extend({
	options: {
		onStopRotation: Class.empty,
		onStartRotation: Class.empty,
		offsetX: 25,
		offsetY: 25,
		velocity: 10000,
		wait: true,
		duration: 300
	},
	
	initialize: function(elements, options) {
		var fx = this, elements = $$(elements),  map = {};
		
		this.elements = elements;
		
		this.current = 0;
		
		this.setOptions(options);
		
		elements.each(function(element, index) {
			map[index] = element;
			
			element.setStyles({
				'position': 'absolute',
				'left':     index * fx.options.offsetX,
				'top':      ((elements.length - 1) * fx.options.offsetY) - (index * fx.options.offsetY),
				'z-index':  elements.length - index,
				"cursor":   (index != 0) ? "pointer" : "default"
			});
			
			element.addEvent("click", function (event) {
				fx.display(index);
			});
		});
		
		this.map = map;
		
		this.rotating = false;
		
		this.parent(elements);
	},
	
	display: function(index) {
		while (this.current != index) {
			this.fast();
		}
		this.stopRotation();
	},
	
	_startRotation: function(once) {
		if (!this.rotating) {
			this.rotating = true;
			this.rotateTimer = (function() {
				this.next();
				if (once && this.current == 0) {
					this.stopRotation();
				}
			}).periodical(this.options.velocity, this);
		}
	},
	
	_stopRotation: function() {
		if (this.rotating) {
			this.rotating = false;
			$clear(this.rotateTimer);
		}
	},
	
	startRotation: function(once) {
		this._startRotation(once);
		this.fireEvent('onStartRotation');
	},
	
	stopRotation: function() {
		this._stopRotation();
		this.fireEvent('onStopRotation');
	},
	
	resetRotation: function() {
		$clear(this.rotateTimer);
		this.rotateTimer = (function() {
			this.next();
		}).periodical(this.options.velocity, this);
	},
	
	toggleRotation: function() {
		if (this.rotating) {
			this.stopRotation();
		}
		else {
			this.startRotation();
		}
	},
	
	next: function() {
		var current = this.current, element = this.map[current], fx = this;
		var len = this.elements.length;
		
		this.current = this.current + 1;
		
		if (this.current >= len) {
			this.current = 0;
		}
		
		
		return fx.start().chain(function() {
			var effects = {};
			effects[current] = { "opacity": [1, 0] };
			return fx.start(effects);
		}).chain(function() {
			var effects = {};
			this.elements.each(function(el, index) {
				effects[index] = { 
					"left":   [el.getStyle("left").toInt(), el.getStyle("left").toInt() - fx.options.offsetX],
					"top":    [el.getStyle("top").toInt(),  el.getStyle("top").toInt()  + fx.options.offsetY]
				};
				
				el.setStyles({
					"z-index": el.getStyle("z-index").toInt() + 1,
					"cursor":  (index != fx.current) ? "pointer" : "default"
				});
			});
			return fx.start(effects);
		}).chain(function() {
			// send to back
			element.setStyles({
				"top":     0,
				"left":    (len - 1) * fx.options.offsetX,
				"z-index": 1
			});
			
			// show
			var effects = {};
			effects[current] = { "opacity": [0, 1] };
			return fx.start(effects);
		});
	},
	
	fast: function() {
		var current = this.current, element = this.map[current], fx = this;
		var len = this.elements.length;
		
		this.current = this.current + 1;
		
		if (this.current >= len) {
			this.current = 0;
		}
				
		this.elements.each(function(el, index) {
			el.setStyles({
				"left":   el.getStyle("left").toInt() - fx.options.offsetX,
				"top":    el.getStyle("top").toInt()  + fx.options.offsetY,
				"z-index": el.getStyle("z-index").toInt() + 1,
				"cursor":  (index != fx.current) ? "pointer" : "default"
			});
		});
		
		element.setStyles({
			"top":     0,
			"left":    (len - 1) * fx.options.offsetX,
			"z-index": 1
		});
	}
})