/**
 * The Page object controls all functionallity on the site
 * which relates to the navigation/transition between pages,
 * the storing of user/cache data and the displaying of notifications.
 *
 * @module FrancesTwiddy
 * @class Page
 * @author Dan Whitfield
 */
 
var Page = 
{
	/**
	 * Store the requested page ID.
	 *
	 * @property _selectedPageId
	 * @type String
	 * @private
	 */
	_selectedPageId: "index",
	
	
	/**
	 * Store the currently displayed page ID.
	 *
	 * @property _currentPageId
	 * @type Bool
	 * @private
	 */
	_currentPageId: "",
	
	
	/**
	 * Store a reference to all page content elements.
	 *
	 * @property _allPageElements
	 * @type Array
	 * @private
	 */
	_allPageElements: null,
	
	
	/**
	 * Store the total number of page content elements.
	 *
	 * @property _totalPages
	 * @type Int
	 * @private
	 */
	_totalPages: null,
	
	
	/**
	 * Store the page content element positions.
	 *
	 * @property _pagePositions
	 * @type Object
	 * @private
	 */
	_pagePositions: {},
	
	
	/**
	 * For functionallity that only needs to run on initial page load.
	 *
	 * @property _initialPageLoad
	 * @type Bool
	 * @private
	 */
	_initialPageLoad: false,
	
	
	/**
	 * Lock for window scroll functionallity called by jQuery callbacks.
	 *
	 * @property _scrollWindowLock
	 * @type Bool
	 * @private
	 */
	_scrollWindowLock: false,
	
	
	/**
	 * Lock for content fade functionallity called by jQuery callbacks.
	 *
	 * @property _contentFadeInLock
	 * @type Bool
	 * @private
	 */
	_contentFadeInLock: false,
	
	
	/**
	 * Lock for navigation move functionallity called by jQuery callbacks.
	 *
	 * @property _navigationLock
	 * @type Bool
	 * @private
	 */
	_navigationLock: false,
	
	
	/**
	 * Store the main nav for use on all content elements.
	 *
	 * @property _mainNavObject
	 * @type Object
	 * @private
	 */
	_mainNavObject: null,
	
	
	/**
	 * Status of the main nav.
	 *
	 * @property _mainNavStatus
	 * @type Bool
	 * @private
	 */
	_mainNavStatus: false,
	
	
	/**
	 * Get the page ready for navigation, this includes
	 * storing IDs and positions of the content.
	 *
	 * @method initialise
	 * @public
	 */
	initialise: function()
	{
		// Store the main nav object for nav movement.
		this._mainNavObject = $("#mainnav");
		
		// Get all the positions of the page content elements.
		this._allPageElements = $(".page");
		this._totalPages = this._allPageElements.length;
		
		for(var i = 0; i < this._totalPages; i++)
		{
			var id = $(this._allPageElements[i]).attr("id");
			this._pagePositions[id] = new Array();
			this._pagePositions[id] = $(this._allPageElements[i]).position();
		}
		
		// Launch the index page only on initial page load.
		if(this._initialPageLoad === false)
		{
			this._initialPageLoad = true;
			
			// Show image captions for the current page.
			Utils.captionSpecifiedImages();
			
			// Load the index page.
			this.switchPage();
			
			// Display any notifications.
			Utils.displayNotifications();
		}
	
		// Register control events.
		Control.initialise();
		Contact.prepareContactForm();
		
		Twitter.initialise($("#twitterFeed ul"), "li");
	},
	
	
	/**
	 * This handles the actual switching of pages, it will
	 * trigger the correct functions to make it all work.
	 *
	 * @method switchPage
	 * @public
	 * @param {String} newPage
	 */
	switchPage: function(newPage)
	{
		var that = this;
		
		// You can pass in a page name and switch the page by calling this function.
		if(typeof newPage != "undefined")
		{
			this._selectedPageId = newPage;
		}		
	
		// Unlock the ability to fade in content.
		this._contentFadeInLock = false;
		
		this._currentPageId = this._selectedPageId;
	
		Utils.debugConsole("Initialising switchPage [" + this._selectedPageId + "]");

		this._scrollWindow();
	},
	
	
	/**
	 * Final stage of page switch is to
	 * fade the content in and reset a few locks.
	 *
	 * @method _scrollFinished
	 * @private
	 */
	_scrollFinished: function()
	{
		Utils.debugConsole("Fading content back in");
		
		if(Page._contentFadeInLock == false)
		{
			Page._contentFadeInLock = true;
			
			// Reset all locks.
			Page._scrollWindowLock = false;
			Page._navigationLock = false;
			
			Page._moveMainNav(Page._selectedPageId);
		
			// Reshow the main nav.
			Page._toggleMainNav();
			
			// Hide activity indicator if shown.
			if(Utils._activityIndicatorStatus.body)
			{
				Utils.toggleActivityIndicator();
			}
		}
	},
	
	
	/**
	 * This handles the actual page movement.
	 *
	 * @method _scrollWindow
	 * @private
	 */
	_scrollWindow: function()
	{
		if(this._scrollWindowLock === false)
		{
			var that = this;

			Utils.debugConsole("pagePositions: ", this._pagePositions);
			Utils.debugConsole("selectedPageId: ", this._selectedPageId);
			Utils.debugConsole("pagePositions[selectedPageId]: ", this._pagePositions[this._selectedPageId]);
			
			var scrollTo = this._pagePositions[this._selectedPageId];
			
			Utils.debugConsole("scrollTo: ", scrollTo.left);
			
			$("#window").scrollTo(scrollTo, 1500,
			{
				easing: "easeInOutExpo",
				onAfter: function()
				{
					that._scrollFinished();
				}
			});
		
			this._scrollWindowLock = true;
		}
	},
	
	
	/**
	 * Show and hide the main nav.
	 *
	 * @method _toggleMainNav
	 * @private
	 */
	_toggleMainNav: function()
	{
		if(this._mainNavStatus)
		{
			$("#mainnav").fadeOut();
			this._mainNavStatus = false;
			Utils.debugConsole("Faded main nav out");
		}
		else
		{
			$("#mainnav").fadeIn("slow");
			this._mainNavStatus = true;
			Utils.debugConsole("Faded main nav in");
		}
	},
	
	
	/**
	 * Move the main nav to the next pagecontent element to be displayed.
	 *
	 * @method _moveMainNav
	 * @private
	 * @param {String} newParentElement
	 */
	_moveMainNav: function(newParentElement)
	{
		Utils.debugConsole("moving nav to [#" + newParentElement + " .pagecontent]");
		$("#" + newParentElement + " .pagecontent").prepend(this._mainNavObject);
	}
};
