package com.tootsville.tootsbook.client;

import org.gwtwidgets.client.wrap.Effect;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.tootsville.tootsbook.client.exception.NotFoundException;
import com.tootsville.tootsbook.client.exception.PrivilegeRequiredException;
import com.tootsville.tootsbook.client.pages.CollectionsPage;
import com.tootsville.tootsbook.client.pages.CollectionsPage.Page;
import com.tootsville.tootsbook.client.pages.HomePage;
import com.tootsville.tootsbook.client.pages.LoginPage;
import com.tootsville.tootsbook.client.pages.ProfilePage;
import com.tootsville.tootsbook.client.pages.SettingsPage;
import com.tootsville.tootsbook.client.pages.StorePage;
import com.tootsville.tootsbook.client.panel.AdPopupPanel;
import com.tootsville.tootsbook.client.panel.ErrorMessage;
import com.tootsville.tootsbook.client.panel.ToolPanel;
import com.tootsville.tootsbook.client.util.AvailableItems;
import com.tootsville.tootsbook.client.util.DisplayText;
import com.tootsville.tootsbook.client.util.Message;
import com.tootsville.tootsbook.client.util.TimeStampLabel;
import com.tootsville.tootsbook.client.util.UserProfile;
import com.tootsville.tootsbook.client.util.tasks.Task;

/**
 * MainPanel is the primary content of the TootsBook application. All
 * user interface elements are controlled through MainPanel. Also,
 * history support is enabled and managed through here as well.
 * 
 * @author <a href="mailto:twheys@gmail.com@resinteractive.com">Tim
 *         Heys</a>
 */
public class MainPanel extends HorizontalPanel {

	/**
	 * Constant width of {@link #contentPanel}
	 */
	private static final String CONTENTS_WIDTH = "900px";

	/**
	 * Contains all the content of the application. {@link MainPanel} is
	 * a HorizontalPanel so it can add a left and right margin to this
	 * panel.
	 */
	static VerticalPanel mainPanelContainer = new VerticalPanel ();

	/**
	 * Tool Panel contains everything in the header of each page. This
	 * content is static and only loaded once when the application is
	 * loaded.
	 */
	static ToolPanel toolPanel = new ToolPanel ();

	/**
	 * <pre>
	 * twheys@gmail.com Jan 19, 2010
	 * </pre>
	 * 
	 * TO reloadToolPanelLinks WRITEME...
	 */
	public static void reloadToolPanelLinks () {
		MainPanel.toolPanel.reloadLinks ();
	}

	/**
	 * Content Panel is used to display the page contents for every
	 * page.
	 */
	protected final SimplePanel contentPanel;

	/**
	 * Keep a reference to the home page so it doesn't have to be
	 * rebuilt every time the user hits it. This is the heaviest page in
	 * the entire application and also the most heavily used.
	 */
	protected Panel home;

	/**
	 * Content Panel is used to display the page contents for every
	 * page.
	 */
	protected SimplePanel messagePanel;

	/**
	 * Vertical space used when toolbar is not visible
	 */
	private final HTMLPanel vertSpace;

	/**
	 * MainPanel is the controlling panel of the TootsBook application.
	 * All pages are loaded and displayed through this.
	 */
	public MainPanel () {

		MainPanel.toolPanel.setStyleName ("header");
		MainPanel.toolPanel.setWidth (MainPanel.CONTENTS_WIDTH);
		MainPanel.toolPanel.setVisible (false);

		vertSpace = new HTMLPanel ("");
		vertSpace.setStyleName ("space");
		vertSpace.setHeight ("50px");

		messagePanel = new SimplePanel ();
		messagePanel.setStyleName ("message");
		messagePanel.setVisible (false);

		contentPanel = new SimplePanel ();
		contentPanel.setStyleName ("main");

		MainPanel.mainPanelContainer.add (MainPanel.toolPanel);
		MainPanel.mainPanelContainer.add (vertSpace);
		MainPanel.mainPanelContainer.add (messagePanel);
		MainPanel.mainPanelContainer.add (contentPanel);
		MainPanel.mainPanelContainer.add (TootsBook.loadingTab);
		MainPanel.mainPanelContainer
		.setWidth (MainPanel.CONTENTS_WIDTH);

		final HTMLPanel space = new HTMLPanel ("");
		space.setStyleName ("space");
		space.setWidth ("5px");
		final HTMLPanel space2 = new HTMLPanel ("");
		space2.setStyleName ("space");
		space2.setWidth ("6px");

		setSize ("100%", "100%");
		this.add (space);
		this.add (MainPanel.mainPanelContainer);
		setCellWidth (MainPanel.mainPanelContainer,
				MainPanel.CONTENTS_WIDTH);
		this.add (space2);

		setBorderWidth (0);

	}

	/**
	 * {@link #changeState(Panel, boolean)} with Toolbar set to true.
	 * 
	 * @param newPanel WRITEME twheys@gmail.com
	 */
	protected void changeState (final Panel newPanel) {
		changeState (newPanel, true);
	}

	/**
	 * Change the state of this application. ANY METHOD THAT CHANGES
	 * WHICH PAGE IS BEING VIEWED SHALL USE THIS METHOD TO CHANGE IT.
	 * 
	 * @param newPanel A panel object containing the new page that will
	 *            be displayed.
	 * @param withToolBar Boolean flag whether to display the toolbar or
	 *            not
	 */
	protected void changeState (final Panel newPanel,
			final boolean withToolBar) {
		if (null == newPanel) return;
		MainPanel.reloadToolPanelLinks ();
		MainPanel.toolPanel.setVisible (withToolBar);
		vertSpace.setVisible ( !withToolBar);

		if (TootsBook.hasMessage ()) {
			messagePanel.setVisible (true);
			messagePanel.clear ();
			final Message message = TootsBook.getMessage ();
			messagePanel.setWidget (new Label (message.getMessage ()));
			messagePanel.setStyleName ("message");
			messagePanel.getElement ().setAttribute ("style",
					"background-color: " + message.getMessageColor ());
			TootsBook.clientMetronome.addOneTimeTask (new Task () {
				@Override
				public void execute () {
					Effect.fold (messagePanel);
				}
			});

		}
		contentPanel.clear ();
		newPanel.setStyleName ("main-panel");
		contentPanel.setWidget (newPanel);
		MainPanel.mainPanelContainer
		.setWidth (MainPanel.CONTENTS_WIDTH);
	}

	/**
	 * Initialize history support for application and prepare handler
	 */
	public void initHistorySupport () {
		/* add history listener */
		History.addValueChangeHandler (new ValueChangeHandler <String> () {
			/**
			 * <pre>
			 * twheys@gmail.com Dec 17, 2009
			 * </pre>
			 * 
			 * TO cleanUpPage WRITEME...
			 */
			private void cleanUpPage () {
				TootsBook.removeBoxStylesStyleSheets ();
				TootsBook.removePageBGStyleSheets ();
				TootsBook.removetitleBGStyleSheets ();
				MainPanel.toolPanel.removeHighlights ();
				contentPanel.clear ();
				messagePanel.setVisible (false);
				TimeStampLabel.cleanup ();
				TootsBook.clientMetronome.clearLocalTasks ();
				TootsBook.hideCurrentPopup ();
			}

			@Override
			public void onValueChange (
					final ValueChangeEvent <String> event) {
				TootsBook.displayLoadingBar ();
				/* Clear components on screen. */
				cleanUpPage ();
				/*
				 * Check tokens and handle them appropriately for each
				 * page
				 */
				if (tryEachPage (event.getValue ())) return;
				/*
				 * if the history changed and we cannot recognize it,
				 * send to the home page
				 */
				MainPanel.this.loadLoginPage ();
			}

			private boolean tryAdminConsole (final String historyToken) {
				// TODO brpocock@star-hope.org Auto-generated method stub (Aug 7,
				// 2010)
				return false;
			}

			/**
			 * <pre>
			 * twheys@gmail.com Dec 17, 2009
			 * </pre>
			 * 
			 * TO tryEachPage WRITEME...
			 * 
			 * @param historyToken WRITEME twheys@gmail.com
			 */
			private boolean tryEachPage (final String historyToken) {
				if (null == historyToken)
					return false;
				else if (tryHome (historyToken))
					return true;
				else if (tryProfile (historyToken))
					return true;
				else if (tryLogin (historyToken))
					return true;
				else if (tryStore (historyToken))
					return true;
				else if (trySettings (historyToken))
					return true;
				else if (tryPivitz (historyToken))
					return true;
				else if (tryPivitPals (historyToken))
					return true;
				else if (tryKatootel (historyToken))
					return true;
				else if (tryPosters (historyToken))
					return true;
				else if (tryTootFinds (historyToken))
					return true;
				else if (tryAdminConsole (historyToken)) return true;
				return false;
			}
		});
	}

	/**
	 * Retrieve a ShadowUser object from the servlet then display their
	 * collections page via {@link #loadCollections(UserProfile, Page)}
	 * 
	 * @param userID The ShadowUser's ID whom you wish to display
	 * @param page Which collections page is being loaded. See
	 *            {@link CollectionsPage.Page}
	 */
	protected void loadCollections (final int userID,
			final CollectionsPage.Page page) {
		if ( -1 == userID) {
			if (TootsBook.isLoggedIn ()) {
				loadCollections (TootsBook.getUser (), page);
				return;
			}
			loadLoggedInUsersProfile ();
		} else {
			System.out
			.println ("Attempting to call the servlet for user information on User ID#"
					+ userID);
			final BookServiceAsync service = TootsBook.initService ();

			// Set up the callback object.
			final AsyncCallback <UserProfile> callback = new AsyncCallback <UserProfile> () {
				@Override
				public void onFailure (final Throwable caught) {
					GWT.log (
							"Exception on RPC call for loadCollections",
							caught);
					if (caught instanceof NotFoundException) {
						TootsBook.showPopup (new ErrorMessage (
								DisplayText.ERROR_404));
						changeState (home);
					} else {
						TootsBook.showError (caught);
					}
				}

				@Override
				public void onSuccess (final UserProfile result) {
					if (null == result) {
						changeState (home);
					} else {
						loadCollections (result, page);
					}
				}
			};

			// Make the call to the search service.
			service.getUser (userID, callback);
			TootsBook.displayLoadingBar ();
		}
	}

	/**
	 * Load a collections page for a user. Use
	 * {@link #loadCollections(int, Page)} to retrieve the user object
	 * first.
	 * 
	 * @param user Which user's collections are being viewed.
	 * @param page Which collections page is being loaded. See
	 *            {@link CollectionsPage.Page}
	 */
	protected void loadCollections (final UserProfile user,
			final CollectionsPage.Page page) {
		System.out.println ("Received info for ShadowUser ID#"
				+ user.getUserID ());
		TootsBook.trackPage ("/collections/" + user.getUserName ());
		changeState (new CollectionsPage (user, page));
	}

	/**
	 * <pre>
	 * twheys@gmail.com Jan 15, 2010
	 * </pre>
	 * 
	 * TO loadHome WRITEME...
	 */
	private void loadHome () {
		loadLoggedInUsersHomePage ();
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 17, 2009
	 * </pre>
	 * 
	 * TO loadLoggedInUsersProfile WRITEME...
	 */
	protected void loadLoggedInUsersHomePage () {
		System.out.println ("Displaying profile for user");
		if (TootsBook.isLoggedIn ()) {
			MainPanel.toolPanel.highlightHome ();
			TootsBook.trackPage ("/home/");
			changeState (new HomePage ());
		} else {
			History.newItem (TootsBook.PAGE_URL_LOGIN, false);
			changeState (new LoginPage (), false);
		}
		return;
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 17, 2009
	 * </pre>
	 * 
	 * TO loadLoggedInUsersProfile WRITEME...
	 */
	protected void loadLoggedInUsersProfile () {
		System.out.println ("Displaying profile for user");
		if (TootsBook.isLoggedIn ()) {
			MainPanel.toolPanel.highlightProfile ();
			TootsBook.trackPage ("/profile/");
			changeState (new ProfilePage (TootsBook.getUser ()));
		} else {
			History.newItem (TootsBook.PAGE_URL_LOGIN, false);
			changeState (new LoginPage (), false);
		}
		return;
	}

	/**
	 * Use this method to attempt to direct to the login screen. If the
	 * user had a cookie detected on loading the website, then they will
	 * be automatically logged in and directed to their profile. If they
	 * are already logged in they will also be directed to their
	 * profile.
	 */
	protected void loadLoginPage () {
		/*
		 * Actually the logic is the same with loading the login page as
		 * it is for loading the logged in user's profile. If the user
		 * is logged in, load the profile page, otherwise load the login
		 * page.
		 */
		loadLoggedInUsersHomePage ();
	}

	/**
	 * Retrieve a user from the servlet then display their profile via
	 * {@link #loadProfile(UserProfile)}
	 * 
	 * @param userID The user ID for whom you wish to display
	 */
	protected void loadProfile (final int userID) {
		if ( -1 == userID) {
			loadLoggedInUsersProfile ();
			return;
		}

		System.out
		.println ("Attemtping to call the servelt for user information on User ID#"
				+ userID);
		final BookServiceAsync service = TootsBook.initService ();

		// Set up the callback object.
		final AsyncCallback <UserProfile> callback = new AsyncCallback <UserProfile> () {
			@Override
			public void onFailure (final Throwable caught) {
				TootsBook.showError (caught);
			}

			@Override
			public void onSuccess (final UserProfile result) {
				loadProfile (result);
			}
		};

		// Make the call to the search service.
		service.getUser (userID, callback);
		TootsBook.displayLoadingBar ();
	}

	/**
	 * Load the profile page for a user.
	 * 
	 * @param user The user whose profile page we're loading.
	 * @see #loadProfile(int) If you need to retrieve another user to
	 *      load thier profile
	 */
	protected void loadProfile (final UserProfile user) {
		System.out.println ("Received info for ShadowUser ID#"
				+ user.getUserID ());
		TootsBook.trackPage ("/" + user.getUserName ());
		changeState (new ProfilePage (user));
	}

	/**
	 * <pre>
	 * twheys@gmail.com Jan 19, 2010
	 * </pre>
	 * 
	 * TO loadSettings WRITEME...
	 */
	protected void loadSettings () {
		if ( !TootsBook.isLoggedIn ()) {
			loadLoginPage ();
			return;
		}
		if ( !TootsBook.getUser ().isPaid ()) {
			TootsBook.showPopup (new AdPopupPanel ());
		}
		final BookServiceAsync service = TootsBook.initService ();

		// Set up the callback object.
		final AsyncCallback <AvailableItems> callback = new AsyncCallback <AvailableItems> () {
			/**
			 * @see com.google.gwt.user.client.rpc.AsyncCallback#onFailure(java.lang.Throwable)
			 */
			@Override
			public void onFailure (final Throwable caught) {
				History.newItem (TootsBook.PAGE_URL_HOME);
				if (caught instanceof PrivilegeRequiredException) {
					TootsBook.showPopup (new AdPopupPanel ());
					return;
				}
				TootsBook.showError (caught);
			}

			/**
			 * @see com.google.gwt.user.client.rpc.AsyncCallback#onSuccess(java.lang.Object)
			 */
			@Override
			public void onSuccess (final AvailableItems items) {
				loadSettings (items);
			}
		};

		// Make the call to the search service.
		service.getAvailableThemeItems (callback);
		TootsBook.displayLoadingBar ();
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 17, 2009
	 * </pre>
	 * 
	 * TO loadSettings change the state to a new {@link SettingsPage}
	 * page with the retrieved {@link AvailableItems} data.
	 * 
	 * @param items data of available items retrieved from the server.
	 */
	protected void loadSettings (final AvailableItems items) {
		MainPanel.toolPanel.highlightSettings ();
		TootsBook.trackPage ("/settings/");
		changeState (new SettingsPage (items));
	}

	/**
	 * <pre>
	 * twheys@gmail.com Feb 23, 2010
	 * </pre>
	 * 
	 * TO loadStore WRITEME...
	 */
	protected void loadStore () {
		loadStore (0);
	}

	/**
	 * <pre>
	 * twheys@gmail.com Feb 23, 2010
	 * </pre>
	 * 
	 * TO loadStore WRITEME...
	 * 
	 * @param tabIndex WRITEME twheys@gmail.com
	 */
	private void loadStore (final int tabIndex) {
		System.out.println ("Displaying profile for user");
		if (TootsBook.isLoggedIn ()) {
			TootsBook.trackPage ("/store/");
			changeState (new StorePage (tabIndex));
		} else {
			History.newItem (TootsBook.PAGE_URL_LOGIN, false);
			changeState (new LoginPage (), false);
		}
		return;
	}

	/**
	 * Check the history token to see if the user is trying to hit the
	 * Pivit pals page.
	 * 
	 * @param historyToken History token from the browser. It is
	 *            compared against {@link TootsBook#PAGE_URL_PROFILE}
	 * @return boolean true: token matches false: token does not match
	 */
	protected boolean tryHome (final String historyToken) {
		String page;
		try {
			page = TootsBook.PAGE_URL_HOME;
			if (page.equals (historyToken.substring (0, page.length ()))) {
				System.out.println ("Directing to " + page + " page");
				// Action
				MainPanel.this.loadHome ();
				// Return so the state doesn't change
				// further
				return true;
			}
		} catch (final IndexOutOfBoundsException e) {
			// do nothing
		}
		return false;
	}

	/**
	 * Check the history token to see if the user is trying to hit the
	 * Katootel page.
	 * 
	 * @param historyToken History token from the browser. It is
	 *            compared against {@link TootsBook#PAGE_URL_KATOOTEL}
	 * @return boolean true: token matches false: token does not match
	 */
	protected boolean tryKatootel (final String historyToken) {
		String page;
		try {
			// https://members.tootsville.com/#profile?id=123456
			page = TootsBook.PAGE_URL_KATOOTEL;
			if (page.equals (historyToken.substring (0, page.length ()))) {
				System.out.println ("Directing to " + page + " page");
				// Action
				final String userID = TootsBook.parseURL ("id",
						historyToken);
				try {
					MainPanel.this.loadCollections (
							Integer.parseInt (userID),
							CollectionsPage.Page.KATOOTELS);
				} catch (final NumberFormatException e) {
					GWT.log ("Failed to check id on katootel", e);
					MainPanel.this.loadCollections ( -1,
							CollectionsPage.Page.KATOOTELS);
				}

				// Return so the state doesn't change
				// further
				return true;
			}
		} catch (final IndexOutOfBoundsException e) {
			// do nothing
		}
		return false;
	}

	/**
	 * Check the history token to see if the user is trying to hit the
	 * Login page.
	 * 
	 * @param historyToken History token from the browser. It is
	 *            compared against {@link TootsBook#PAGE_URL_LOGIN}
	 * @return boolean true: token matches false: token does not match
	 */
	protected boolean tryLogin (final String historyToken) {
		String page;
		try {
			// https://members.tootsville.com/#home
			page = TootsBook.PAGE_URL_LOGIN;
			if (page.equals (historyToken.substring (0, page.length ()))) {
				System.out.println ("Directing to login");
				// Action
				MainPanel.this.loadLoginPage ();

				// Return so the state doesn't change
				// further
				return true;
			}
		} catch (final IndexOutOfBoundsException e) {
			// do nothing
		}
		return false;
	}

	/**
	 * <pre>
	 * twheys@gmail.com Jan 19, 2010
	 * </pre>
	 * 
	 * TO tryLogout WRITEME...
	 * 
	 * @param historyToken WRITEME twheys@gmail.com
	 * @return true: token matches false: token does not match
	 */
	protected boolean tryLogout (final String historyToken) {
		String page;
		try {
			// https://members.tootsville.com/#home
			page = TootsBook.PAGE_URL_LOGOUT;
			if (page.equals (historyToken.substring (0, page.length ()))) {
				System.out.println ("Directing to login");
				// Action
				TootsBook.logout (Boolean.TRUE);
				MainPanel.this.loadLoginPage ();

				// Return so the state doesn't change
				// further
				return true;
			}
		} catch (final IndexOutOfBoundsException e) {
			// do nothing
		}
		return false;
	}

	/**
	 * Check the history token to see if the user is trying to hit the
	 * Pivit pals page.
	 * 
	 * @param historyToken History token from the browser. It is
	 *            compared against {@link TootsBook#PAGE_URL_PIVIT_PALS}
	 * @return boolean true: token matches false: token does not match
	 */
	protected boolean tryPivitPals (final String historyToken) {
		String page;
		try {
			// https://members.tootsville.com/#profile?id=123456
			page = TootsBook.PAGE_URL_PIVIT_PALS;
			if (page.equals (historyToken.substring (0, page.length ()))) {
				System.out.println ("Directing to " + page + " page");
				// Action
				final String userID = TootsBook.parseURL ("id",
						historyToken);
				try {
					MainPanel.this.loadCollections (
							Integer.parseInt (userID),
							CollectionsPage.Page.PIVITPALS);
				} catch (final NumberFormatException e) {
					GWT.log ("Failed to check id on pivitpals", e);
					MainPanel.this.loadCollections ( -1,
							CollectionsPage.Page.PIVITPALS);
				}

				// Return so the state doesn't change
				// further
				return true;
			}
		} catch (final IndexOutOfBoundsException e) {
			// do nothing
		}
		return false;
	}

	/**
	 * Check the history token to see if the user is trying to hit the
	 * Pivitz page.
	 * 
	 * @param historyToken History token from the browser. It is
	 *            compared against {@link TootsBook#PAGE_URL_PIVITZ}
	 * @return boolean true: token matches false: token does not match
	 */
	protected boolean tryPivitz (final String historyToken) {
		String page;
		try {
			// https://members.tootsville.com/#profile?id=123456
			page = TootsBook.PAGE_URL_PIVITZ;
			if (page.equals (historyToken.substring (0, page.length ()))) {
				System.out.println ("Directing to " + page + " page");
				// Action
				final String userID = TootsBook.parseURL ("id",
						historyToken);
				try {
					MainPanel.this.loadCollections (
							Integer.parseInt (userID),
							CollectionsPage.Page.PIVITZ);
				} catch (final NumberFormatException e) {
					GWT.log ("Failed to check id on pivitz", e);
					MainPanel.this.loadCollections ( -1,
							CollectionsPage.Page.PIVITZ);
				}

				// Return so the state doesn't change
				// further
				return true;
			}
		} catch (final IndexOutOfBoundsException e) {
			// do nothing
		}
		return false;
	}

	/**
	 * Check the history token to see if the user is trying to hit the
	 * Posters page.
	 * 
	 * @param historyToken History token from the browser. It is
	 *            compared against {@link TootsBook#PAGE_URL_POSTERS}
	 * @return boolean true: token matches false: token does not match
	 */
	protected boolean tryPosters (final String historyToken) {
		String page;
		try {
			// https://members.tootsville.com/#profile?id=123456
			page = TootsBook.PAGE_URL_POSTERS;
			if (page.equals (historyToken.substring (0, page.length ()))) {
				System.out.println ("Directing to " + page + " page");
				// Action
				final String userID = TootsBook.parseURL ("id",
						historyToken);
				try {
					MainPanel.this.loadCollections (
							Integer.parseInt (userID),
							CollectionsPage.Page.POSTERS);
				} catch (final NumberFormatException e) {
					GWT.log ("Failed to check id on posters", e);
					MainPanel.this.loadCollections ( -1,
							CollectionsPage.Page.POSTERS);
				}

				// Return so the state doesn't change
				// further
				return true;
			}
		} catch (final IndexOutOfBoundsException e) {
			// do nothing
		}
		return false;
	}

	/**
	 * Check the history token to see if the user is trying to hit the
	 * Pivit pals page.
	 * 
	 * @param historyToken History token from the browser. It is
	 *            compared against {@link TootsBook#PAGE_URL_PROFILE}
	 * @return boolean true: token matches false: token does not match
	 */
	protected boolean tryProfile (final String historyToken) {
		String page;
		try {
			// https://members.tootsville.com/#profile?id=123456
			page = TootsBook.PAGE_URL_PROFILE;
			if (page.equals (historyToken.substring (0, page.length ()))) {
				System.out.println ("Directing to " + page + " page");
				// Action
				final String userID = TootsBook.parseURL ("id",
						historyToken);
				System.out
				.println ("Unit profile loading: ShadowUser ID#"
						+ userID);
				try {
					MainPanel.this.loadProfile (Integer
							.parseInt (userID));
				} catch (final NumberFormatException e) {
					GWT.log ("Failed to check id on profile", e);
					MainPanel.this.loadProfile ( -1);
				}

				// Return so the state doesn't change
				// further
				return true;
			}
		} catch (final IndexOutOfBoundsException e) {
			// do nothing
		}
		return false;
	}

	/**
	 * Check the history token to see if the user is trying to hit the
	 * Pivit pals page.
	 * 
	 * @param historyToken History token from the browser. It is
	 *            compared against {@link TootsBook#PAGE_URL_PIVIT_PALS}
	 * @return boolean true: token matches false: token does not match
	 */
	protected boolean trySettings (final String historyToken) {
		String page;
		try {
			// https://members.tootsville.com/#profile?id=123456
			page = TootsBook.PAGE_URL_SETTINGS;
			if (page.equals (historyToken.substring (0, page.length ()))) {
				System.out.println ("Directing to " + page + " page");
				// Action
				MainPanel.this.loadSettings ();

				// Return so the state doesn't change
				// further
				return true;
			}
		} catch (final IndexOutOfBoundsException e) {
			// do nothing
		}
		return false;
	}

	/**
	 * Check the history token to see if the user is trying to hit the
	 * Pivit pals page.
	 * 
	 * @param historyToken History token from the browser. It is
	 *            compared against {@link TootsBook#PAGE_URL_PROFILE}
	 * @return boolean true: token matches false: token does not match
	 */
	protected boolean tryStore (final String historyToken) {
		String page;
		try {
			page = TootsBook.PAGE_URL_STORE;
			if (page.equals (historyToken.substring (0, page.length ()))) {
				System.out.println ("Directing to " + page + " page");
				// Action
				final String tab = TootsBook.parseURL ("id",
						historyToken);
				if (null == tab) {
					MainPanel.this.loadStore ();
					return true;
				}
				try {
					MainPanel.this.loadStore (Integer.parseInt (tab));
				} catch (final NumberFormatException e) {
					MainPanel.this.loadStore ();
				}
				return true;
			}
		} catch (final IndexOutOfBoundsException e) {
			// do nothing
		}
		return false;
	}

	/**
	 * Check the history token to see if the user is trying to hit the
	 * Toot Finds page.
	 * 
	 * @param historyToken History token from the browser. It is
	 *            compared against {@link TootsBook#PAGE_URL_TOOT_FINDS}
	 * @return boolean true: token matches false: token does not match
	 */
	protected boolean tryTootFinds (final String historyToken) {
		String page;
		try {
			// https://members.tootsville.com/#profile?id=123456
			page = TootsBook.PAGE_URL_TOOT_FINDS;
			if (page.equals (historyToken.substring (0, page.length ()))) {
				System.out.println ("Directing to " + page + " page");
				// Action
				final String userID = TootsBook.parseURL ("id",
						historyToken);
				try {
					MainPanel.this.loadCollections (
							Integer.parseInt (userID),
							CollectionsPage.Page.TOOTFINDS);
				} catch (final NumberFormatException e) {
					GWT.log ("Failed to check id on tootfinds", e);
					MainPanel.this.loadCollections ( -1,
							CollectionsPage.Page.TOOTFINDS);
				}

				// Return so the state doesn't change
				// further
				return true;
			}
		} catch (final IndexOutOfBoundsException e) {
			// do nothing
		}
		return false;
	}
}
