package com.tootsville.tootsbook.client.pages;

import org.gwtwidgets.client.style.Color;
import org.gwtwidgets.client.wrap.Callback;
import org.gwtwidgets.client.wrap.Effect;
import org.gwtwidgets.client.wrap.EffectOption;

import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.tootsville.tootsbook.client.BookServiceAsync;
import com.tootsville.tootsbook.client.TootsBook;
import com.tootsville.tootsbook.client.exception.PrivilegeRequiredException;
import com.tootsville.tootsbook.client.exception.SessionTimedOutException;
import com.tootsville.tootsbook.client.panel.AdPopupPanel;
import com.tootsville.tootsbook.client.panel.AvatarBox;
import com.tootsville.tootsbook.client.panel.Box;
import com.tootsville.tootsbook.client.panel.BuddyPanelPopup;
import com.tootsville.tootsbook.client.panel.ErrorMessage;
import com.tootsville.tootsbook.client.panel.wallobjects.PostPanel;
import com.tootsville.tootsbook.client.panel.wallobjects.WallObject;
import com.tootsville.tootsbook.client.util.Advertisement;
import com.tootsville.tootsbook.client.util.DisplayText;
import com.tootsville.tootsbook.client.util.Post;
import com.tootsville.tootsbook.client.util.ShadowUser;
import com.tootsville.tootsbook.client.util.UserProfile;
import com.tootsville.tootsbook.client.util.tasks.Task;

/**
 * @author twheys@gmail.com
 */
public class ProfilePage extends HorizontalPanel {

	/**
	 * WRITEME: Document this type.
	 *
	 * @author brpocock@star-hope.org
	 *
	 */
	static final class ShowAllClickHandler implements
	ClickHandler {
		@Override
		public void onClick (final ClickEvent event) {
			TootsBook.showPopup (new BuddyPanelPopup (
					ProfilePage.getUser ()));
		}
	}

	/**
	 * WRITEME
	 */
	private static String commentFieldDefaultText = "";

	/**
	 * WRITEME
	 */
	private static final int NUMBER_OF_BUDDIES = 9;

	/**
	 * WRITEME
	 */
	private static UserProfile user;

	/**
	 * @return the cOMMENT_FIELD_DEFAULT_TEXT
	 */
	public static String getCommentFieldDefaultText () {
		return ProfilePage.commentFieldDefaultText; /* TODO brpocock@star-hope.org */
	}

	/**
	 * @return The profile user
	 */
	public static UserProfile getUser () {
		return ProfilePage.user;
	}

	/**
	 * @param cOMMENT_FIELD_DEFAULT_TEXT the cOMMENT_FIELD_DEFAULT_TEXT to set
	 */
	public static void setCommendFieldDefaultText (
			final String cOMMENT_FIELD_DEFAULT_TEXT) {
		ProfilePage.commentFieldDefaultText = cOMMENT_FIELD_DEFAULT_TEXT; /* TODO brpocock@star-hope.org */
	}

	/**
	 * WRITEME
	 */
	private Box adBox;

	/**
	 * WRITEME
	 */
	protected TextArea addCommentField;

	/**
	 * WRITEME
	 */
	private Box avatarBox;

	/**
	 * WRITEME
	 */
	AvatarBox avatarPanel;

	/**
	 * WRITEME
	 */
	private Box buddyBox;

	/**
	 * WRITEME *
	 */
	private VerticalPanel centerContents;

	/**
	 * WRITEME *
	 */
	private Box collectionBox;

	/**
	 * WRITEME *
	 */
	private final BlurHandler comemntBlur = new BlurHandler () {
		/**
		 * @see com.google.gwt.event.dom.client.BlurHandler#onBlur(com.google.gwt.event.dom.client.BlurEvent)
		 */
		@Override
		public void onBlur (final BlurEvent event) {
			if ("".equals (addCommentField.getText ())) {
				addCommentField
				.setText (ProfilePage
						.getCommentFieldDefaultText ());
				addCommentField.addStyleName ("greyed-text");
			}
		}
	};

	/**
	 * WRITEME *
	 */
	private final FocusHandler commentFocus = new FocusHandler () {
		/**
		 * @see com.google.gwt.event.dom.client.FocusHandler#onFocus(com.google.gwt.event.dom.client.FocusEvent)
		 */
		@Override
		public void onFocus (final FocusEvent event) {
			if (ProfilePage.getCommentFieldDefaultText ()
					.equals (addCommentField.getText ())) {
				addCommentField.setText ("");
				addCommentField.removeStyleName ("greyed-text");
			}
		}
	};

	/**
	 * WRITEME twheys@gmail.com
	 */
	private VerticalPanel leftContents;

	/**
	 * WRITEME twheys@gmail.com
	 */
	private Label loadingPostsMessage;

	/**
	 * Highest ID of displayed posts. Used to retrieve updated posts on
	 * a timer.
	 */
	private int newestPostID;

	/**
	 * WRITEME twheys@gmail.com
	 */
	private int numberOfDisplayedPosts;

	/**
	 * WRITEME twheys@gmail.com
	 */
	private Box postBox;

	/**
	 * WRITEME twheys@gmail.com
	 */
	private FlexTable postContainer;

	/**
	 * WRITEME twheys@gmail.com
	 */
	private SimplePanel postDiv;

	/**
	 * WRITEME twheys@gmail.com
	 */
	private VerticalPanel rightContents;

	/**
	 * WRITEME twheys@gmail.com
	 */
	private Box tbLinkBox;

	/**
	 * WRITEME twheys@gmail.com
	 */
	private Box textBox;

	/**
	 * WRITEME twheys@gmail.com
	 */
	private Box titleBox;

	/**
	 * WRITEME twheys@gmail.com
	 */
	private HTML titlePanel;

	/**
	 * @param userInfo WRITEME twheys@gmail.com
	 */
	public ProfilePage (final UserProfile userInfo) {
		buildProfile (userInfo);
		listenForPosts ();
	}

	/**
	 * <pre>
	 * twheys@gmail.com Jan 19, 2010
	 * </pre>
	 *
	 * TO addComment WRITEME...
	 *
	 * @param post WRITEME twheys@gmail.com
	 */
	public void addComment (final Post post) {
		if (null != post.getParent ()) {
			((PostPanel) post.getParent ().getContainingPanel ())
			.addComment (post);
		}
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 18, 2009
	 * </pre>
	 *
	 * TO addCommentsToPosts WRITEME...
	 *
	 * @param posts WRITEME twheys@gmail.com
	 */
	private void addCommentsToPosts (final Post [] posts) {
		for (final Post post : posts) {
			final Post parent = post.getParent ();
			if (null != parent) {
				((PostPanel) parent.getContainingPanel ())
				.addComment (post);
			}
		}
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 31, 2009
	 * </pre>
	 *
	 * TO addMorePostsLink WRITEME...
	 */
	private void addMorePostsLink () {
		final Anchor getMorePostsLink = new Anchor (
				DisplayText.SHOW_MORE_POSTS, "javascript:;");
		getMorePostsLink.setStyleName ("primary-text");
		getMorePostsLink.addClickHandler (new ClickHandler () {
			@Override
			public void onClick (final ClickEvent event) {
				getOlderPosts ();
				final EffectOption [] opts = new EffectOption [] { new EffectOption (
						"onCompletion", new Callback () {

							@Override
							public void execute () {
								getPostContainer ().remove (
										getMorePostsLink);
							}
						}) };
				Effect.puff (getMorePostsLink, opts);
			}
		});
		getPostContainer ()
		.setWidget (getPostContainer ().getRowCount (), 0,
				getMorePostsLink);
	}

	/**
	 * <pre>
	 * twheys@gmail.com Feb 17, 2010
	 * </pre>
	 *
	 * TO addNewPostsToWall WRITEME...
	 *
	 * @param posts WRITEME twheys@gmail.com
	 */
	private void addNewPostsToWall (final Post [] posts) {
		numberOfDisplayedPosts += posts.length - 1;
		for (final Post post : posts) {
			if (null == post.getParent ()) {
				final WallObject wallObject = post.getPanel ();
				wallObject.setVisible (false);
				getPostContainer ().insertRow (0);
				newestPostID = post.getId () > newestPostID ? post
						.getId () : newestPostID;
						postContainer.setWidget (0, 0, wallObject);
						Effect.blindDown (wallObject,
								new EffectOption [] { new EffectOption (
										"duration", "0.5") });
			}
		}
	}

	/**
	 * <pre>
	 * twheys@gmail.com Jan 19, 2010
	 * </pre>
	 *
	 * TO addPost WRITEME...
	 *
	 * @param post WRITEME twheys@gmail.com
	 */
	protected void addPost (final Post post) {
		updateStatus (post);
		if (null != loadingPostsMessage) {
			loadingPostsMessage.removeFromParent ();
		}
		addCommentField
		.setText (ProfilePage
				.getCommentFieldDefaultText ());
		addCommentField.addStyleName ("greyed-text");
		final PostPanel postPanel = new PostPanel (post);
		final int rowBefore = 0;
		postPanel.getElement ()
		.setAttribute ("style", "display: none;");
		getPostContainer ().insertRow (rowBefore);
		getPostContainer ().setWidget (rowBefore, 0, postPanel);
		Effect.blindDown (postPanel,
				new EffectOption [] { new EffectOption ("direction",
				"top-left") });
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 18, 2009
	 * </pre>
	 *
	 * TO addPostsToWall WRITEME...
	 *
	 * @param posts WRITEME twheys@gmail.com
	 */
	private void addPostsToWall (final Post [] posts) {
		numberOfDisplayedPosts += posts.length - 1;
		for (final Post post : posts) {
			if (null == post.getParent ()) {
				final WallObject wallObject = post.getPanel ();
				getPostContainer ().setWidget (
						getPostContainer ().getRowCount (),
						0, wallObject);
				newestPostID = post.getId () > newestPostID ? post
						.getId () : newestPostID;
			}
		}
		// If there might be more posts add a link to retrieve them.
		if (posts.length >= TootsBook.NUMBER_OF_POSTS) {
			addMorePostsLink ();
		}
	}

	/**
	 * <pre>
	 * twheys@gmail.com Mar 9, 2010
	 * </pre>
	 *
	 * TO addScrollListener WRITEME...
	 */
	private void addScrollListener () {
		// TODO Auto-generated method stub WRITEME twheys@gmail.com

	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 31, 2009
	 * </pre>
	 *
	 * TO buildAdPanel WRITEME...
	 */
	private void buildAdPanel () {
		final Advertisement adPanel = new Advertisement ();
		adBox = new Box (adPanel, "Advertisment", "<br />", "");
		adBox.pack ();
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 31, 2009
	 * </pre>
	 *
	 * TO buildAvatarPanel WRITEME...
	 */
	private void buildAvatarPanel () {
		avatarPanel = new AvatarBox (String.valueOf (ProfilePage.user
				.getUserID ()), ProfilePage.user.getAvatarBgURL ());
		avatarPanel.setStyleName ("avatar-portrait");

		// put this panel in the UI container
		avatarBox = new Box (avatarPanel, "Player Card", "", "");

		// build the container.
		avatarBox.pack ();
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 31, 2009
	 * </pre>
	 *
	 * TO buildBuddyListPanel WRITEME...
	 */
	private void buildBuddyListPanel () {
		final FlowPanel buddyPanel = new FlowPanel ();
		buddyPanel.setStyleName ("buddy-panel");

		if (0 != ProfilePage.user.getBuddies ().length) {
			buddyBox = new Box (buddyPanel, "My Friends",
					"&middot; See All", new ClickHandler () {
				@Override
				public void onClick (final ClickEvent event) {
					TootsBook.showPopup (new BuddyPanelPopup (
							ProfilePage.getUser ()));
				}
			});
		} else {
			buddyBox = new Box (buddyPanel, "My Friends", "<br />", "");
		}

		buddyBox.addRelImage (
				new Image (ProfilePage.user.getIconBaseURL ()
						+ "icon2.png"), 10, -70);

		buddyBox.pack ();

		int i = 1;
		for (final ShadowUser buddy : ProfilePage.user.getBuddies ()) {
			if (null == buddy) {
				// do nothing
			} else {
				buddyPanel.add (buddy.getIcon ());
				if (ProfilePage.NUMBER_OF_BUDDIES == i++ ) {
					break;
				}
			}
		}
	}

	/**
	 * Adds a panel for showing collections. Currently this is
	 * unsupported because the backend has not been developed for most
	 * of its components (TODO)
	 */
	private void buildCollectionPanel () {
		final VerticalPanel collectionPanel = new VerticalPanel ();
		collectionPanel.setStyleName ("collection-panel");

		final String [][] collectionsList = new String [] [] {
				{ "Pivitz",
					"#pivitz?id=" + ProfilePage.user.getUserID () },
					{
						"PivitPals",
						"#pivitpals?id="
						+ ProfilePage.user.getUserID () },
						{
							"Katootels",
							"#katootels?id="
							+ ProfilePage.user.getUserID () },
							{ "Posters",
								"#posters?id=" + ProfilePage.user.getUserID () },
								{ "Tootfinds",
									"#finds?id=" + ProfilePage.user.getUserID () } };

		for (final String [] collectionItem : collectionsList) {
			final HorizontalPanel item = new HorizontalPanel ();
			final Anchor link = new Anchor (collectionItem [0],
					collectionItem [1]);
			link.setStyleName ("primary-text collection-link");

			item.add (new Image (ProfilePage.user.getIconBaseURL ()
					+ "bullet.png"));
			item.add (link);
			collectionPanel.add (item);
		}

		collectionBox = new Box (collectionPanel, "Collections",
				"<br />", "");

		collectionBox.addRelImage (
				new Image (ProfilePage.user.getIconBaseURL ()
						+ "icon3.png"), 128, -315);
		collectionBox.addRelImage (
				new Image (ProfilePage.user.getIconBaseURL ()
						+ "icon4.png"), 80, -70);

		collectionBox.pack ();
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 31, 2009
	 * </pre>
	 *
	 * TO buildPostPanel WRITEME...
	 */
	private void buildPostPanel () {
		setPostContainer (new FlexTable ());
		getPostContainer ().getElement ()
		.setAttribute ("width", "100%");

		postDiv = new SimplePanel ();
		postDiv.setStyleName ("wall-panel");
		postDiv.setWidget (getPostContainer ());

		postBox = new Box (postDiv, "Comments");
		postBox.pack ();

		loadingPostsMessage = new Label (
				ProfilePage.user.getUserName ()
				+ "'s comments are loading.");

		getPostContainer ().setWidget (
				getPostContainer ().getRowCount (), 0,
				loadingPostsMessage);

		final BookServiceAsync service = TootsBook.initService ();

		// Set up the callback object.
		final AsyncCallback <Post []> callback = new AsyncCallback <Post []> () {
			@Override
			public void onFailure (final Throwable caught) {
				TootsBook.showError (caught);
			}

			@Override
			public void onSuccess (final Post [] result) {
				ProfilePage.this.loadPosts (result);
			}
		};

		// Make the call to the search service.
		service.getPosts (ProfilePage.user.getUserID (), callback);
		TootsBook.displayLoadingBar ();
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 31, 2009
	 * </pre>
	 *
	 * TO buildProfile WRITEME...
	 *
	 * @param userInfo WRITEME twheys@gmail.com
	 */
	private void buildProfile (final UserProfile userInfo) {
		System.out.println ("Loading profile for: "
				+ userInfo.getUserName () + " ("
				+ userInfo.getUserID () + ")");
		Window.setTitle (userInfo.getUserName ()
				+ "'s Profile - TootsBook® www.Tootsville.com");
		ProfilePage.user = userInfo;
		ProfilePage
		.setCommendFieldDefaultText (ProfilePage.user
				.equals (TootsBook.getUser ()) ? DisplayText.WRITE_ON_MY_WALL
						: DisplayText.WRITE_ON_YOUR_WALL);

		TootsBook.loadBoxStylesStyleSheet (ProfilePage.user
				.getBoxStyleURL ());
		TootsBook.loadPageBGStyleSheet (ProfilePage.user
				.getPageStyleURL ());
		TootsBook.loadTitleBGStyleSheet (ProfilePage.user
				.getTitleStyleURL ());

		leftContents = new VerticalPanel ();
		centerContents = new VerticalPanel ();
		rightContents = new VerticalPanel ();
		leftContents
		.setHorizontalAlignment (HasHorizontalAlignment.ALIGN_CENTER);
		centerContents
		.setHorizontalAlignment (HasHorizontalAlignment.ALIGN_CENTER);
		rightContents
		.setHorizontalAlignment (HasHorizontalAlignment.ALIGN_CENTER);

		buildAvatarPanel ();
		avatarBox.addStyleName ("left-panel");
		leftContents.add (avatarBox);

		buildBuddyListPanel ();
		buddyBox.addStyleName ("left-panel");
		leftContents.add (buddyBox);

		// buildCollectionPanel ();
		// collectionBox.addStyleName ("left-panel");
		// leftContents.add (collectionBox);

		buildTitlePanel ();
		titleBox.addStyleName ("center-panel");
		centerContents.add (titleBox);

		buildTBLinkPanel ();
		tbLinkBox.addStyleName ("center-panel");
		centerContents.add (tbLinkBox);

		buildTextPanel ();
		textBox.addStyleName ("center-panel");
		centerContents.add (textBox);

		buildPostPanel ();
		postBox.addStyleName ("center-panel");
		centerContents.add (postBox);

		buildAdPanel ();
		adBox.addStyleName ("right-panel");
		rightContents.add (adBox);

		leftContents.setStyleName ("leftContent");
		centerContents.setStyleName ("centerContent");
		rightContents.setStyleName ("rightContent");

		add (leftContents);
		add (centerContents);
		add (rightContents);

		setStyleName ("main-panel");

		addScrollListener ();

		if (TootsBook.isLoggedIn () && !TootsBook.getUser ().isPaid ()
				&& !TootsBook.isAdShown ()) {
			TootsBook.showPopup (new AdPopupPanel ());
			TootsBook.setAdShown (true);
		}

		TootsBook.hideLoadingBar ();
	}

	/**
	 * <pre>
	 * twheys@gmail.com Feb 3, 2010
	 * </pre>
	 *
	 * TO buildTBLinkPanel WRITEME...
	 */
	private void buildTBLinkPanel () {
		final HTML tbLinkLabel = new HTML (
				"<div class=\"tb-link-container\"><span class=\"secondary-text\" style=\"font-weight:"
				+ " bold !important\">My TootsBook Link: </span><span "
				+ "class=\"primary-text\" style=\"font-weight: bold "
				+ "!important\"> "
				+ ProfilePage.getUser ()
				.getPublicProfileLink ()
				+ "</span></div>");
		tbLinkBox = new Box (tbLinkLabel);
		tbLinkBox.pack ();
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 31, 2009
	 * </pre>
	 *
	 * TO buildTextPanel WRITEME...
	 */
	private void buildTextPanel () {
		final VerticalPanel textPanel = new VerticalPanel ();
		textPanel.getElement ()
		.setAttribute ("style", "padding: 10px;");
		final HorizontalPanel addPostPanel = new HorizontalPanel ();
		addPostPanel.setStyleName ("text-panel");

		textPanel.add (addPostPanel);
		textPanel.add (new HTMLPanel ("<br />"));

		final String textBoxHeader = ProfilePage.user.equals (TootsBook
				.getUser ()) ? DisplayText.MAKE_A_POST
						: DisplayText.LEAVE_A_MESSAGE;

		textBox = new Box (textPanel, textBoxHeader);
		textBox.pack ();

		final Button submit = new Button (" ", new ClickHandler () {
			/**
			 * (non-Javadoc)
			 *
			 * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
			 */
			@Override
			public void onClick (final ClickEvent event) {
				try {
					submitText ();
				} catch (final PrivilegeRequiredException caught) {
					TootsBook.showError (caught);
				}
			}
		});
		final Button cancel = new Button ("  ", new ClickHandler () {
			/**
			 * (non-Javadoc)
			 *
			 * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
			 */
			@Override
			public void onClick (final ClickEvent event) {
				addCommentField
				.setText (ProfilePage
						.getCommentFieldDefaultText ());
				addCommentField.addStyleName ("greyed-text");
			}
		});

		final VerticalPanel submitBox = new VerticalPanel ();
		submit.setStyleName ("confirm-button-small");
		submit.getElement ().setId ("submit-button-small");
		cancel.setStyleName ("confirm-button-small");
		cancel.getElement ().setId ("cancel-button-small");
		submit.setTitle ("SUBMIT");
		cancel.setTitle ("CANCEL");
		submitBox.add (cancel);
		submitBox.add (submit);
		submitBox.setSpacing (2);

		addCommentField = new TextArea ();
		addCommentField.setStyleName ("text-area");
		if (TootsBook.isLoggedIn ()) {
			addCommentField
			.setText (ProfilePage
					.getCommentFieldDefaultText ());
			addCommentField.addStyleName ("greyed-text");
			addCommentField.setVisibleLines (1);
		} else {
			addCommentField
			.setText (DisplayText.LOGGED_IN_FOR_COMMENTS);
			addCommentField.getElement ().setAttribute ("disabled",
			"disabled");
			addCommentField.setVisibleLines (2);
		}
		addCommentField.getElement ().setAttribute ("cols", "25");
		addCommentField.getElement ().setAttribute ("wrap", "hard");
		addCommentField.getElement ().setAttribute ("maxlength",
				String.valueOf (TootsBook.MAX_CHAR_LENGTH));
		addCommentField.addFocusHandler (commentFocus);
		addCommentField.addBlurHandler (comemntBlur);
		addCommentField.getSelectionLength ();
		addCommentField.addKeyPressHandler (new KeyPressHandler () {
			/**
			 * @see com.google.gwt.event.dom.client.KeyPressHandler#onKeyPress(com.google.gwt.event.dom.client.KeyPressEvent)
			 */
			@Override
			public void onKeyPress (final KeyPressEvent event) {
				if ( !TootsBook.filterKeys (
						event.getCharCode (),
						(addCommentField.getText ().length () >= TootsBook.MAX_CHAR_LENGTH))) {
					addCommentField.cancelKey ();
					return;
				}
				if (15 > addCommentField.getVisibleLines ()
						&& addCommentField.getText ().length () / 48 >= addCommentField
						.getVisibleLines ()) {
					addCommentField.setVisibleLines (addCommentField
							.getVisibleLines () + 1);
				}
			}
		});

		addPostPanel
		.setVerticalAlignment (HasVerticalAlignment.ALIGN_MIDDLE);
		addPostPanel.add (addCommentField);
		addPostPanel.add (submitBox);
		addPostPanel.setCellWidth (addCommentField, "415px");
		addPostPanel.setBorderWidth (0);

	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 31, 2009
	 * </pre>
	 *
	 * TO buildTitlePanel WRITEME...
	 */
	private void buildTitlePanel () {
		titlePanel = new HTML ("<div class=\"header-text-container\">"
				+ "<div class=\"header-box\">"
				+ "<span class=\"header-name\">"
				+ ProfilePage.user.getUserName ()
				+ " </span><span class=\"header-text\">"
				+ ProfilePage.user.getStatus () + "</span></div></div>");
		titlePanel.setStyleName ("title-panel");
		titleBox = new Box (titlePanel);
		titleBox.addRelImage (
				new Image (ProfilePage.user.getIconBaseURL ()
						+ "icon0.png"), 340, -132);
		titleBox.useBackground ();
		titleBox.pack ();
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 18, 2009
	 * </pre>
	 *
	 * TO getMostPosts WRITEME...
	 */
	protected void getNewPosts () {
		final BookServiceAsync service = TootsBook.initService ();

		final AsyncCallback <Post []> callback = new AsyncCallback <Post []> () {

			@Override
			public void onFailure (final Throwable caught) {
				if (caught instanceof SessionTimedOutException) {
					TootsBook.showError (caught);
				}
				listenForPosts ();
			}

			@Override
			public void onSuccess (final Post [] result) {
				if (0 == result.length) {
					// no op
				} else {
					ProfilePage.this.loadNewPosts (result);
				}
				listenForPosts ();
			}
		};

		final int profileID = ProfilePage.getUser ().getUserID ();
		service.getNewProfilePosts (profileID, newestPostID, callback);
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 18, 2009
	 * </pre>
	 *
	 * TO getMostPosts WRITEME...
	 */
	protected void getOlderPosts () {
		final BookServiceAsync service = TootsBook.initService ();

		final AsyncCallback <Post []> callback = new AsyncCallback <Post []> () {

			@Override
			public void onFailure (final Throwable caught) {
				TootsBook.showError (caught);
			}

			@Override
			public void onSuccess (final Post [] result) {
				if (0 == result.length) {
					TootsBook
					.showPopup (new ErrorMessage (
							ProfilePage.getUser ()
							.getUserName ()
							+ " does not have any more posts to view!"));
				} else {
					ProfilePage.this.loadPosts (result);
				}
			}
		};

		service.getMorePosts (ProfilePage.user.getUserID (),
				numberOfDisplayedPosts, callback);
	}

	/**
	 * @return the postContainer
	 */
	public FlexTable getPostContainer () {
		return postContainer; /* TODO brpocock@star-hope.org */
	}

	/**
	 * <pre>
	 * twheys@gmail.com Feb 18, 2010
	 * </pre>
	 *
	 * TO listenForPosts WRITEME...
	 */
	protected void listenForPosts () {
		TootsBook.clientMetronome.addOneTimeTask (new Task () {
			@Override
			public void execute () {
				getNewPosts ();
			}
		});
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 18, 2009
	 * </pre>
	 *
	 * TO loadPosts WRITEME...
	 *
	 * @param posts WRITEME twheys@gmail.com
	 */
	protected void loadNewPosts (final Post [] posts) {
		addNewPostsToWall (posts);
		addCommentsToPosts (posts);
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 18, 2009
	 * </pre>
	 *
	 * TO loadPosts WRITEME... WRITEME twheys@gmail.com
	 *
	 * @param posts WRITEME twheys@gmail.com
	 */
	protected void loadPosts (final Post [] posts) {
		if (0 == posts.length) {
			showNoCommentsToDisplayMessage ();
			return;
		}
		loadingPostsMessage.removeFromParent ();
		addPostsToWall (posts);
		addCommentsToPosts (posts);
	}
	
	/**
	 * @param newPostContainer the postContainer to set
	 */
	public void setPostContainer (final FlexTable newPostContainer) {
		postContainer = newPostContainer;
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 18, 2009
	 * </pre>
	 *
	 * TO showNoCommentsToDisplayMessage WRITEME...
	 */
	private void showNoCommentsToDisplayMessage () {
		final String profileUsersName = ProfilePage.user.getUserName ();
		loadingPostsMessage.setText (profileUsersName
				+ " has no comments.  Be the first to leave "
				+ profileUsersName + " a comment!");
	}

	/**
	 * <pre>
	 * twheys@gmail.com Jan 15, 2010
	 * </pre>
	 *
	 * TO submitText WRITEME...
	 *
	 * @throws PrivilegeRequiredException WRITEME twheys@gmail.com
	 */
	protected void submitText () throws PrivilegeRequiredException {
		if ( !TootsBook.isLoggedIn ()) throw new PrivilegeRequiredException (
				DisplayText.LOGGED_IN_FOR_COMMENTS);
		final String newMessage = addCommentField.getText ().trim ();
		if (ProfilePage.getCommentFieldDefaultText ().equals (
				newMessage)
				|| "".equals (newMessage)) {
			Effect.highlight (addCommentField, Color.RED, Color.WHITE,
					0.5);
			return;
		}

		final Post newComment = new Post (TootsBook.getUser (),
				newMessage);

		final BookServiceAsync service = TootsBook.initService ();

		// Set up the callbacUserInfo.k object.
		final AsyncCallback <Post> callback = new AsyncCallback <Post> () {
			@Override
			public void onFailure (final Throwable caught) {
				TootsBook.hideLoadingBar ();
				TootsBook.showError (caught);
			}

			@Override
			public void onSuccess (final Post successfulComment) {
				TootsBook.hideLoadingBar ();
				ProfilePage.this.addPost (successfulComment);
				addCommentField.setText ("");
			}
		};

		// Make the call to the search service.
		service.addPost (ProfilePage.user.getUserID (), newComment,
				callback);
		TootsBook.displayLoadingBar ();
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 18, 2009
	 * </pre>
	 *
	 * TO updateStatus WRITEME...
	 *
	 * @param post WRITEME twheys@gmail.com
	 */
	private void updateStatus (final Post post) {
		if (ProfilePage.user.getUserID () == post.getAuthor ()
				.getUserID ()) {
			ProfilePage.user.setStatus (post.getMessage ());
			titlePanel.setHTML ("<div class=\"header-text-container\">"
					+ "<span class=\"header-name\">"
					+ ProfilePage.user.getUserName ()
					+ " </span><span class=\"header-text\">"
					+ ProfilePage.user.getStatus () + "</span></div>");
		}
	}
}
