/**
 * Pagination class.
 */
function Pagination(container, url)
{
	/* save the container */
	this._container = $(container);
	this._url = url;

	/* get the next/previous buttons */
	this._buttonPrev = getElementsByTagAndClassName("A", "previous", this._container.parentNode.parentNode)[0];
	this._buttonNext = getElementsByTagAndClassName("A", "next", this._container.parentNode.parentNode)[0];

	/* get the width of the container, which is used for the scrolling */
	this._containerWidth = elementDimensions(this._container).w;
	this._containerHeight = elementDimensions(this._container).h;

	/* private properties */
	this._currentPage = 0;
	this._sliding = false;
	this._lastPageReached = false;

	/* pages */
	this._calculatePages();
	this._loadPage();

	setTimeout(bind(this._initButtons, this), 500);
	//this._initButtons();
} // class Pagination

Pagination.prototype = {

	/**
	 * Slides to the next page (if available)
	 */
	nextPage: function()
	{
		/* already sliding, do nothing */
		if (this._sliding)
		{
			return;
		}

		/* get current and next page */
		var currentPage = this._pages[this._currentPage];
		var nextPage = this._pages[this._currentPage+1];

		/* no next page? do nothing */
		if (!nextPage)
		{
			return;
		}

		/* prepare for a slide. this method prevents rendering issues */
		this._prepForSlide();

		/* page might be hidden, unhide */
		if (/(msie|MSIE) 6/.test(navigator.userAgent) === true)
		{
			nextPage.style.display = "";
		}

		/* scroll simultaneous */
		MochiKit.Visual.Parallel(
		[
			MochiKit.Visual.Move(currentPage, {"x": -this._containerWidth, "sync": true}),
			MochiKit.Visual.Move(nextPage, {"x": -this._containerWidth, "sync": true})
		], {"afterFinish": bind(this._finishNextPage, this)});
	}, // function nextPage

	/**
	 * Slides to the previous page (if available)
	 */
	previousPage: function()
	{
		/* do nothing when sliding or when the first page is visible */
		if (this._sliding || this._currentPage == 0)
		{
			return;
		}

		/* get current and previous page */
		var currentPage = this._pages[this._currentPage];
		var previousPage = this._pages[this._currentPage-1];

		/* prepare for a slide. this method prevents rendering issues */
		this._prepForSlide();

		/* scroll simultaneous */
		MochiKit.Visual.Parallel(
		[
			MochiKit.Visual.Move(previousPage, {"x": this._containerWidth, "sync": true}),
			MochiKit.Visual.Move(currentPage, {"x": this._containerWidth, "sync": true})
		], {"afterFinish": bind(this._finishPreviousPage, this)});
	}, // function previousPage

	/**
	 * Prepares for a slide.
	 */
	_prepForSlide: function()
	{
		/* We're sliding. Setting a flag so you can't slide simultaneously. */
		this._sliding = true;

		/* for reisverhalen; collapse before moving to the next page */
		if (hasElementClass(this._pages[this._currentPage], "overview-reisverhalen"))
		{
			collapseAllStories();
		}

		/* set current height as fixed minimal height to prevent the container from collapsing */
		if (/(msie|MSIE) 6/.test(navigator.userAgent) === true)
		{
			/* IE6 doesn't support min-height, so we're setting the fixed height.
			 * A CSS overflow-y rule will mimick the min-height.
			 */
			this._container.style.height = elementDimensions(this._container).h + "px";
		}
		else
		{
			this._container.style.minHeight = elementDimensions(this._container).h + "px";
		}

		/* make sure the current page has a fixed left position of zero */
		this._pages[this._currentPage].style.left = "0";

		/* now we van remove its current class name, making it scrollable */
		removeElementClass(this._pages[this._currentPage], "current");
	}, // function _prepForSlide

	/**
	 * Initialize buttons.
	 */
	_initButtons: function()
	{
		/* vertical-align the previous and next buttons */
		var offsetTop = Math.round((elementDimensions(this._container).h / 2) - 30) + 44;
		/* IE6/7 needs an additional 20px apparently */
		if (/(msie|MSIE) [67]/.test(navigator.userAgent) === true)
		{
			offsetTop += 20;
		}		
		this._buttonPrev.style.top = offsetTop + "px";
		this._buttonNext.style.top = offsetTop + "px";

		/* initially disable the previous button, since we're on page 1 */
		addElementClass(this._buttonPrev, "disabled");

		/* IE can't fade in PNG images (not even IE8!), so display instantly */
		if (/msie|MSIE/.test(navigator.userAgent) === true)
		{
			this._buttonPrev.style.display = "block";
			this._buttonNext.style.display = "block";
		}
		/* use a fancy appear affect for all other browsers */
		else
		{
			MochiKit.Visual.appear(this._buttonPrev);
			MochiKit.Visual.appear(this._buttonNext);
		}
	}, // function _initButtons

	/**
	 * Method to be called after we've slided to the next page.
	 */
	_updateButtons: function()
	{
		/* disable previous page when at the first page */
		if (this._currentPage == 0)
		{
			addElementClass(this._buttonPrev, "disabled");
		}
		else
		{
			removeElementClass(this._buttonPrev, "disabled");
		}

		/* if we know the last page, and the current page is the last page, disable next button */
		if (this._lastPageReached && (this._currentPage + 1) == this._pages.length)
		{
			addElementClass(this._buttonNext, "disabled");
		}
		else
		{
			removeElementClass(this._buttonNext, "disabled");
		}
	}, // function _updateButtons

	/**
	 * Method to be called after we've slided to the next page.
	 */
	_finishNextPage: function()
	{
		/* update current page */
		this._currentPage++;

		/* mark the current page as current */
		addElementClass(this._pages[this._currentPage], "current");

		/* update buttons */
		this._updateButtons();

		/* no longer sliding */
		this._sliding = false;

		/* load another page */
		if (this._lastPageReached === false)
		{
			this._loadPage();
		}
	}, // function _finishNextPage

	/**
	 * Method to be called after we've slided to the previous page.
	 */
	_finishPreviousPage: function()
	{
		/* update current page */
		this._currentPage--

		/* mark the current page as current */
		addElementClass(this._pages[this._currentPage], "current");

		/* update buttons */
		this._updateButtons();

		/* no longer sliding */
		this._sliding = false;
	}, // function _finishPreviousPage

	/**
	 * Calculate the number of available pages
	 */
	_calculatePages: function()
	{
		this._pages = getElementsByTagAndClassName("UL", "page", this._container);
	}, // function _calculatePages

	/**
	 * Load another page.
	 */
	_loadPage: function()
	{
		/* load the next page */
		var ajax = new Sitebox.Framework.Ajax();
		ajax.call(this._url.replace("{PAGE}", this._pages.length + 1), {"callbacks": {"success": bind(this._handlePageLoaded, this)}});
	}, // function _loadPage

	/**
	 * Callback for when a new page is loaded.
	 */
	_handlePageLoaded: function()
	{
		/* re-calculate pages */
		this._calculatePages();
		/* check if the last page was returned */
		if (Sitebox.Framework.Ajax.json[this._container.id + "LastPage"])
		{
			this._lastPageReached = true;
		}

		/* hide page (IE6 only) */
		if (/(msie|MSIE) 6/.test(navigator.userAgent) === true)
		{
			this._pages[this._pages.length-1].style.display = "none";
		}

		/* update buttons (since we might be on the last page) */
		this._updateButtons();
	} // function _handlePageLoaded

};
