var NXC = NXC || {};
NXC.Paginator = NXC.Paginator || {};
NXC.Paginator.Base = new Class( {

	Implements: [Options, Events],

	options: {
		'navigationBlocks': [ 'paginator' ],
		'quantityBlocks': [ 'paginator-quantity-top', 'paginator-quantity-bottom' ],
		'possbileQuantities': [ 5, 10, 25, 50 ],
		'defaultQuantity': 10,
		'currentQuantityCSSClass': 'paginator-quantity-current',
		'otherQuantityCSSClass': 'paginator-quantity-other',
		'currentLinkCSSClass': 'paginator-current',
		'otherLinkCSSClass': 'paginator-other',
		'disabledLinkCSSClass': 'paginator-disabled',
		'prevLinkTitle': '&laquo;Previous',
		'nextLinkTitle': 'Next&raquo;',
		'prevLinkCSSClass': 'paginator-prev',
		'nextLinkCSSClass': 'paginator-next',
		'currentURL': true
	},

	itemsPerPage: 10,
	pagesCount: 0,
	currentPage: 1,
	quantityBlocks: [],
	navigationBlocks: [],

	initialize: function( options ) {
		this.setOptions( options );

		this.itemsPerPage = this.options.defaultQuantity;
	},

	build: function() {
		this.parseURL();

		this.pagesCount = this.getPagesCount();

		if ( this.pagesCount > 1 ) {
			this.installPagesNavigation();
			this.installQuantityNavigatoion();
		}

		this.showPage();
	},

	parseURL: function() {
		if( this.options.currentURL ) {
			var uri = new URI();
			if( uri.get( 'fragment' ) ) {
				var quantity = this.itemsPerPage;

				var parts = uri.get( 'fragment' ).split( '/' );
				parts.each( function( part ) {
					var partElements = part.split( '=' );
					if( partElements.length == 2 ) {
						switch( partElements[0] ) {
							case 'quatity':
								quantity = partElements[1].toInt();
								break;
							case 'page':
								this.currentPage = partElements[1].toInt();
								break;
						}
					}
				}.bind( this ) );

				if( this.options.possbileQuantities.contains( quantity ) ) {
					this.setItemsPerPage( quantity );
				}
			}
		}
	},

	installPagesNavigation: function() {
		this.options.navigationBlocks.each( function( el ) {
			var navigationBlock = document.id( el );
			if( $type( navigationBlock ) == 'element' ) {
				this.navigationBlocks.include( navigationBlock );
			}
		}.bind( this ) );

		this.navigationBlocks.each( function( navigationBlock ) {
			navigationBlock.empty();

			this.buildPagesNavigationLink( this.options.prevLinkTitle, this.options.prevLinkCSSClass )
			.inject( navigationBlock )
			.addEvent( 'click', function() {
				if( this.currentPage == 1 ) {
					return false;
				}

				this.currentPage--;
				this.showPage();
			}.bind( this ) );

			if( this.pagesCount > 1 ) {

				var pageNumber = 1;
				while ( pageNumber <= this.pagesCount ) {
					this.buildNavigationLink( pageNumber, navigationBlock );
					pageNumber++;
		        }
			}

			this.buildPagesNavigationLink( this.options.nextLinkTitle, this.options.nextLinkCSSClass )
			.inject( navigationBlock )
			.addEvent( 'click', function() {
				if( this.currentPage == this.pagesCount ) {
					return false;
				}

				this.currentPage++;
				this.showPage();
			}.bind( this ) );
		}.bind( this ) );
	},

	buildPagesNavigationLink: function( html, cssClass ) {
		return new Element( 'a', {
			'html': html,
			'href': '#',
			'class': cssClass,
		    'events': {
				'click': function( e ){ e.stop(); }
			}
		} );
	},

	buildNavigationLink: function( pageNumber, container ) {
		var el = this.buildPagesNavigationLink(
			pageNumber,
			( pageNumber == this.currentPage ) ? this.options.currentLinkCSSClass : this.options.otherLinkCSSClass
		).inject( container ).store( 'page', pageNumber );
		el.addEvent( 'click', function() {
			this.currentPage = el.retrieve( 'page' );
			this.showPage();
		}.bind( this ) );
	},

	installQuantityNavigatoion: function() {
		this.options.quantityBlocks.each( function( el ) {
			var quantityBlock = document.id( el );
			if( quantityBlock ) {
				this.quantityBlocks.include( quantityBlock );
			}
		}.bind( this ) );

		this.quantityBlocks.each( function( quantityBlock ) {
			quantityBlock.empty();
			this.options.possbileQuantities.each( function( quantity ) {
				if( $type( quantity ) == 'number' ) {
					new Element( 'a', {
						'href': '#',
						'html': quantity,
						'class': ( quantity == this.itemsPerPage ) ? this.options.currentQuantityCSSClass : this.options.otherQuantityCSSClass,
					    'events': {
							'click': function( e ){ e.stop(); }
						}
					} )
					.inject( quantityBlock )
					.store( 'quantity', quantity )
					.addEvent( 'click', this.setItemsPerPage.bind( this, quantity ) )
				}
			}.bind( this ) );
		}.bind( this ) );
	},

	setItemsPerPage: function( itemsCount ) {
		var otherClass   = this.options.otherQuantityCSSClass;
		var currentClass = this.options.currentQuantityCSSClass;

		this.quantityBlocks.each( function( quantityBlock ) {
			quantityBlock.getElements( 'a.' + otherClass ).extend(
				quantityBlock.getElements( 'a.' + currentClass )
			).each( function( el ) {
				el.removeClass( otherClass );
				el.removeClass( currentClass );

				if( el.retrieve( 'quantity' ) == itemsCount ) {
					el.addClass( currentClass );
				} else {
					el.addClass( otherClass );
				}
			} );
		}.bind( this ) );

		this.itemsPerPage = itemsCount;

		this.pagesCount = this.getPagesCount();
		if( this.currentPage > this.pagesCount ) {
			this.currentPage = this.pagesCount;
		}

		this.installPagesNavigation();
		this.showPage();
	},

	showPage: function() {
		var linkClassCurrent  = this.options.currentLinkCSSClass;
		var linkClassOther    = this.options.otherLinkCSSClass;
		var linkClassDisabled = this.options.disabledLinkCSSClass;

		this.navigationBlocks.each( function( navigationBlock ) {
			if( this.pagesCount > 1 ) {
				navigationBlock.getElements( 'a.' + linkClassOther ).extend(
					navigationBlock.getElements( 'a.' + linkClassCurrent )
				).each( function( el ) {
					el.removeClass( linkClassOther );
					el.removeClass( linkClassCurrent );
					if( el.retrieve( 'page' ) == this.currentPage ) {
						el.addClass( linkClassCurrent );
					} else {
						el.addClass( linkClassOther );
					}
	        	}.bind( this ) );
    		}

        	var prevLink = navigationBlock.getElement( 'a.' + this.options.prevLinkCSSClass );
			var nextLink = navigationBlock.getElement( 'a.' + this.options.nextLinkCSSClass );
			prevLink.removeClass( linkClassDisabled );
			nextLink.removeClass( linkClassDisabled );
			if( this.currentPage == 1 ) {
				prevLink.addClass( linkClassDisabled );
			}
			if( this.currentPage == this.pagesCount ) {
				nextLink.addClass( linkClassDisabled );
			}
		}.bind( this ) );

		this.showItems();

		this.updateCurrentURI();
	},

	updateCurrentURI: function() {
		if( this.options.currentURL != false ) {
			var uri = new URI();
			uri.set( 'fragment', 'page=' + this.currentPage + '/quatity=' + this.itemsPerPage );
			window.location = uri.toString();
		}
	},

	/* Should be implemented in child class */
	calculatePagesCount: function() {},
	showItems: function() {}
} );
