var PageFader = new Class({	
	
	options: {
			bookClass: 'book',
			pageClass: 'page',
			hideClass: 'noshow',
			fadeInDuration: 550,
			fadeOutDuration: 400,
			rotateOnStart: false,
			rotateSpeed: 4500,
			onPageChange: Class.empty,
			wrap: true
	},
	
	initialize: function( id, options ) {
		this.setOptions( options );
		this.stage = $(id);
		this.pages = this.stage.getElements('.' + this.options.pageClass);
		this.currentPage = 0;
		this.fadeInFX = [];
		this.fadeOutFX = [];
		this.rotateIntervalId = null;
		
		this.pages.each(function(el, i){
			this.fadeInFX[i] = new Fx.Styles(el, {duration: this.options.fadeInDuration, transition: Fx.Transitions.linear});
			this.fadeOutFX[i] = new Fx.Styles(el, {duration: this.options.fadeOutDuration, transition: Fx.Transitions.linear});
			if(i != 0){
				el.setStyle('opacity', 0);
				el.removeClass(this.options.hideClass);
			}
		}, this);
		
		if(this.options.rotateOnStart)
			this.startRotation();
	},
	
	/**
	 * Jump to any of the "pages" contained in this object
	 * @private
 	 * @param {integer} [num] The page number to jump to
 	 */
	_gotoPage: function(num){
		if( this.pages.length <= num || num < 0){
			return false;
		}
		if(num == this.currentPage)
			return false;
		var prev = this.currentPage;
		this.currentPage = num;
		this.fadeInFX[this.currentPage].start({
			opacity : 1
		});
		this.fadeOutFX[prev].start({
			opacity : 0
		}).chain(function(){
			for(var i = 1; i < this.pages.length; i++){
				this.pages[(this.currentPage + i) % this.pages.length].setStyle('opacity', 0);
			}
		}.bind(this));
		this.fireEvent('onPageChange', [this]);
		return true;
	},

	_gotoNext: function(){
		if( ! this.hasNext() ){
			this.stopRotation();
			return false;
		}
		return this._gotoPage( (this.currentPage + 1) % this.pages.length);
	},
	
	_gotoPrevious : function(){
		if( ! this.hasPrevious() ){
			return false;
		}
		return this._gotoPage( this.currentPage == 0? this.pages.length-1 : this.currentPage-1 );
	},
	
	startRotation : function(speed){
		if(this.rotateIntervalId !== null)
			this.stopRotation();
		
		var rotateSpeed = this.options.rotateSpeed;
		if(speed)
			rotateSpeed = speed;
		this.rotateIntervalId = setInterval(function(){this._gotoNext();}.bind(this), rotateSpeed);
	},
	
	stopRotation : function(){
		if(this.rotateIntervalId === null)
			return;
		clearInterval(this.rotateIntervalId);
		this.rotateIntervalId = null;
	},
	
	gotoPage : function(num){
		this.stopRotation();
		return this._gotoPage(num);
	},
	
	gotoNext: function(){
		this.stopRotation();
		return this._gotoNext();
	},
	
	gotoPrevious : function(){
		this.stopRotation();
		return this._gotoPrevious();	
	},
	
	hasNext: function(){
		return this.options.wrap || this.currentPage + 1 < this.pages.length;
	},
	
	hasPrevious : function(){
		return this.options.wrap || this.currentPage > 0;
	},
	
	getNumPages : function(){
		return this.pages.length;
	},
	
	getCurrentPage : function(){
		return this.currentPage + 1;
	}
	
});
PageFader.implement(new Events, new Options);
