package com.tootsville.tootsbook.client.panel.wallobjects;

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.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HTML;
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.Panel;
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.panel.ErrorMessage;
import com.tootsville.tootsbook.client.util.DisplayText;
import com.tootsville.tootsbook.client.util.Message;
import com.tootsville.tootsbook.client.util.Post;

/**
 * WRITEME: Document this type. twheys@gmail.com Jan 18, 2010
 * 
 * @author <a href="mailto:twheys@gmail.com@resinteractive.com">Tim Heys</a>
 * 
 */
public class PostPanel extends WallObject {
	/**
	 * 
	 */
	private final CommentPanel commentContainer;

	/**
	 * 
	 */
	protected final Post post;

	/**
	 * <pre>
	 * twheys@gmail.com Jan 15, 2010
	 * </pre>
	 * 
	 * A PostPanel WRITEME...
	 * 
	 * @param newPost * WRITEME twheys@gmail.com
	 */
	public PostPanel (final Post newPost) {
		super (newPost);
		post = newPost;
		post.setContainingPanel (this);
		setStyleName ("wall-post");

		commentContainer = new CommentPanel (post);
		commentContainer.setStyleName ("comment");
		final FocusPanel buddyicon = post.getAuthor ().getIcon ();

		final DockPanel postDock = new DockPanel ();
		final HorizontalPanel postMessage = getPostMessagePanel ();

		postDock.add (buddyicon, DockPanel.WEST);
		postDock.add (commentContainer, DockPanel.SOUTH);
		postDock.setCellWidth (buddyicon, "65px");
		postDock.add (postMessage, DockPanel.CENTER);

		postDock.setCellHeight (postMessage, "75px");
		postDock.setCellWidth (postMessage, "345px");

		postDock.setWidth ("100%");

		add (postDock);
	}

	/**
	 * <pre>
	 * twheys@gmail.com Jan 19, 2010
	 * </pre>
	 * 
	 * TO addComment WRITEME...
	 * 
	 * @param comment WRITEME
	 */
	public void addComment (final Post comment) {
		commentContainer.addComment (comment, true);
	}

	/**
	 * 
	 * <pre>
	 * twheys@gmail.com Dec 18, 2009
	 * </pre>
	 * 
	 * TO buildDeleteAndReportButtons WRITEME...
	 * 
	 * @return WRITEME
	 */
	private VerticalPanel buildDeleteAndReportButtons () {
		final Image deletePost = new Image (
		"/tootbook-resource/images/ui/delete.png");
		deletePost.setTitle (DisplayText.DELETE_TITLE);
		deletePost.setStyleName ("comment-icons");
		deletePost.addClickHandler (new ClickHandler () {
			@Override
			public void onClick (final ClickEvent event) {
				deletePost ();
			}
		});
		final Image reportPost = new Image (
		"/tootbook-resource/images/ui/report.png");
		reportPost.setTitle (DisplayText.REPORT_TITLE);
		reportPost.setStyleName ("comment-icons");
		reportPost.addClickHandler (new ClickHandler () {
			@Override
			public void onClick (final ClickEvent event) {
				reportPost ();
			}
		});

		final VerticalPanel options = new VerticalPanel ();
		options.setSpacing (5);
		if (TootsBook.isLoggedIn ()) {
			if (post.getAuthor ().equals (TootsBook.getUser ())
					|| TootsBook.getUser ().getStaffLevel () > 0) {
				options.add (deletePost);
			}
			options.add (reportPost);
		}
		return options;
	}

	/**
	 * Perform an RPC call to the server to delete a post.
	 * 
	 */
	protected void deletePost () {
		final BookServiceAsync service = TootsBook.initService ();

		if (Window
				.confirm ("Are you sure you want to delete this comment?")) {
			// 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 successfulComment) {
					puffDestroy (post.getContainingPanel ());
				}
			};

			// Make the call to the search service.
			service.deletePost (TootsBook.getUser ().getUserID (),
					post, callback);
			TootsBook.displayLoadingBar ();
		}
	}

	/**
	 * <pre>
	 * twheys@gmail.com Dec 18, 2009
	 * </pre>
	 * 
	 * TO getPostMessagePanel WRITEME...
	 * 
	 * @return WRITEME
	 */
	private HorizontalPanel getPostMessagePanel () {
		final HorizontalPanel postMessagePanel = new HorizontalPanel ();
		final HTML message = new HTML ();
		final Element messageElement = message.getElement ();
		if (post.hasAttachment ()) {
			messageElement.setInnerHTML ("<img src=\""
					+ post.getAttachmentURL ()
					+ "\" class=\"system-event-icon\" />"
					+ post.getMessage ());
		} else {
			messageElement.setInnerText (post.getMessage ());
		}

		messageElement.setAttribute ("class", "post-text");
		final VerticalPanel options = buildDeleteAndReportButtons ();
		postMessagePanel.add (message);
		postMessagePanel
		.setVerticalAlignment (HasVerticalAlignment.ALIGN_MIDDLE);
		postMessagePanel.add (options);
		postMessagePanel.setCellWidth (options, "15px");
		postMessagePanel.setStyleName ("post-message primary-text");
		return postMessagePanel;
	}

	/**
	 * Destroy a post using the puff animation.
	 * 
	 * @param panelToDestroy The post you want to destroy.
	 */
	protected void puffDestroy (final Panel panelToDestroy) {
		final Callback callBack = new Callback () {
			@Override
			public void execute () {
				panelToDestroy.removeFromParent ();
			}
		};
		Effect.puff (panelToDestroy,
				new EffectOption [] { new EffectOption ("afterFinish",
						callBack) });
	}

	/**
	 * Perform an RPC call to the server to report a user and delete the
	 * post that was reported
	 * 
	 */
	protected void reportPost () {
		final BookServiceAsync service = TootsBook.initService ();

		if (Window.confirm (DisplayText.ARE_YOU_SURE_REPORT)) {
			// 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 deletedComment) {
					TootsBook.showPopup (new ErrorMessage (Message
							.getReportMessage (post.getAuthor ()
									.getUserName ())));
					puffDestroy (post.getContainingPanel ());
				}
			};

			// Make the call to the search service.
			service.reportPost (post, callback);
		}
	}
}
