//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Text;
using System.Web;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

using CommunityServer.Components;
using CommunityServer.Controls;
using CommunityServer.Discussions.Components;

namespace CommunityServer.Discussions.Controls 
{
	// *********************************************************************
	//  SinglePostView
	//
	/// <summary>
	/// This server control is used to display a single post.
	/// </summary>
	/// 
	// ********************************************************************/
	public class SinglePostView : TemplatedWebControl
	{
		CSContext csContext;
		ForumPost post;
		ForumPost topPost;
		Thread thread;
		Forum forum;
		ForumPermission permission;
		Forum reportForum;
		User currentUser;
		bool siteEnableUserPostingAsAnonymous = false;
		bool forumEnableUserPostingAsAnonymous = false;

		protected override void OnInit(EventArgs e)
		{
			if (SkinName == null)                
				ExternalSkinFileName = "View-SinglePostView.ascx";
			else 
				ExternalSkinFileName = SkinName;

			this.csContext = CSContext.Current;
			this.currentUser = csContext.User;

			if (csContext.ThreadID > 0)
			{
				// if we're in the threaded view, find the post within the PostSet (it's already cached)
				thread = Threads.GetThread(csContext.ThreadID);
				PostSet postSet = Posts.GetPosts(thread.PostID, 0, PostThreadedView.MaxPosts, 0, (int) SortOrder.Ascending, true);
				foreach (ForumPost p in postSet.Posts)
				{
					if (p.PostID == thread.PostID)
						this.topPost = p;

					if (p.PostID == csContext.PostID)
						this.post = p;

					if (this.post != null && this.topPost != null)
						break;	
				}
			}
			
			if (this.post == null)
				this.post = Posts.GetPost( csContext.PostID, currentUser.UserID, true, true, true );

			if (this.post == null || !this.post.IsApproved)
				throw new CSException(CSExceptionType.PostNotFound, "The post is not approved for public viewing");

			// Are we looking up the forum by forum id or post id
			//
			if (csContext.SectionID > 0) 
			{
				forum = Forums.GetForum(csContext.SectionID, true, true);
			} 
			else if (csContext.PostID > 0) 
			{
				forum = Forums.GetForumByPostID(csContext.PostID, csContext.User.UserID, true );
			}

			if (forum == null) 
			{
				PermissionBase.RedirectOrExcpetion(CSExceptionType.SectionNotFound, csContext.SectionID.ToString());
			}

			if (forum.SectionID == 0) 
			{
				UserMessages.InvalidateMessageCount(currentUser.UserID);
			}

			//Get the report forum
			reportForum = Forums.GetReportedForum();

			// Get site and forum settings if users may post as anonymous.
			//
			siteEnableUserPostingAsAnonymous = ForumConfiguration.Instance().EnableUserPostingAsAnonymous;
			forumEnableUserPostingAsAnonymous = forum.EnableAnonymousPostingForUsers;

			permission = forum.ResolvePermission( currentUser ) as ForumPermission;

			if( !permission.Read )
				PermissionBase.RedirectOrExcpetion(CSExceptionType.AccessDenied);

			base.OnInit(e);
		}

		protected override void OnLoad(EventArgs e) 
		{
			if ( !Page.IsPostBack || !EnableViewState ) 
			{
				DataBind();
			}
			JavaScript.RegisterRefresh(this.Page);
			JavaScript.RegisterToolTips(this.Page);
			Page.RegisterClientScriptBlock("QuickReply", BuildQuickReplyScript());
			base.OnLoad(e);
		}


		#region Child Controls

		RequiredFieldValidator postBodyValidator;
		Label forumName;
		HyperLink threadLink;
		Literal postDate;
		RatePost ratePost;
		ForumImageButton replyButton;
		ForumImageButton quoteButton;
		ForumImageButton deleteButton;
		ForumImageButton editButton;
		ModerationPopupMenu modPopupMenu;
		UserOnlineStatus onlineStatus;
		UserAvatar avatar;
		Literal username;
		PostIcons postIcon;
		RoleIcons roleIcon;
		UserAttribute joinedAttribute;
		UserAttribute locationAttribute;
		UserAttribute postsAttribute;
		UserAttribute pointsAttribute;
		Literal emoticon;
		Literal subject;
		PostAttachment postAttachment;
		PostView postView;
		HtmlAnchor postAnchor;
		PostImageButtons buttonsForPoster;
		Literal postPoints;
		Literal postIPAddress;
		HyperLink reportLink;
		StatusDropDownList threadStatus;
		ResourceControl threadStatusLabel;
		HtmlGenericControl PostViewWrapper;
		FavoritePopupMenu favoritePopupMenu;
		ContactPopupMenu contactPopupMenu;
		ITrackedThread trackingButton;
		RatePost rateThread;
		HyperLink quickReply;
		InlineTagEditorPanel tagEditorPanel;

		#endregion

		#region Skin

		protected override void AttachChildControls() 
		{

			postBodyValidator = (RequiredFieldValidator)FindControl("PostBodyValidator");
			forumName = (Label)FindControl("ForumName");
			threadLink = (HyperLink)FindControl("ThreadLink");

			postDate = (Literal)FindControl("PostDate");
			ratePost = (RatePost)FindControl("RatePost");
			replyButton = (ForumImageButton)FindControl("ReplyButton");
			quoteButton = (ForumImageButton)FindControl("QuoteButton");
			deleteButton = (ForumImageButton)FindControl("DeleteButton");
			editButton = (ForumImageButton)FindControl("EditButton");
			modPopupMenu = (ModerationPopupMenu)FindControl("ModerationPopupMenu");
			onlineStatus = (UserOnlineStatus)FindControl("OnlineStatus");
			avatar = (UserAvatar)FindControl("Avatar");
			username = (Literal)FindControl("Username");
			postIcon = (PostIcons)FindControl("PostIcon");
			roleIcon = (RoleIcons)FindControl("RoleIcon");
			joinedAttribute = (UserAttribute)FindControl("JoinedAttribute");
			locationAttribute = (UserAttribute)FindControl("LocationAttribute");
			postsAttribute = (UserAttribute)FindControl("PostsAttribute");
			pointsAttribute = (UserAttribute)FindControl("PointsAttribute");
			emoticon = (Literal)FindControl("Emoticon");
			subject = (Literal)FindControl("Subject");
			postAttachment = (PostAttachment)FindControl("PostAttachment");
			postView = (PostView)FindControl("PostView");
			postAnchor = (HtmlAnchor)FindControl("PostAnchor");
			buttonsForPoster = (PostImageButtons)FindControl("ButtonsForPoster");
			postPoints = (Literal)FindControl("PostPoints");
			postIPAddress = (Literal)FindControl("PostIPAddress");
			reportLink = (HyperLink)FindControl("ReportLink");
			threadStatus = FindControl("ThreadStatus") as StatusDropDownList;
			threadStatusLabel = FindControl("ThreadStatusLabel") as ResourceControl;
			PostViewWrapper = FindControl("PostViewWrapper") as HtmlGenericControl;
			favoritePopupMenu = FindControl("FavoritePopupMenu") as FavoritePopupMenu;
			contactPopupMenu = FindControl("ContactPopupMenu") as ContactPopupMenu;
			trackingButton = FindControl( "TrackingButton" ) as ITrackedThread;
			rateThread = (RatePost)FindControl( "RateThread" );
			quickReply = (HyperLink) FindControl( "quickReplyLink" );
			tagEditorPanel = (InlineTagEditorPanel) FindControl("InlineTagEditorPanel");

			InitializeChildControls();
		}

		private void InitializeChildControls() 
		{
		}


		#endregion

		private void ModerationMenu_PostModerateRefresh (object sender, EventArgs e)
		{
			HttpContext.Current.Response.Redirect(HttpContext.Current.Request.Url.ToString(), true);
		}

		#region DataBinding
		public override void DataBind() 
		{
			base.DataBind();

				Head.AddSiteNameTitle(post.Subject, Context);
				if(this.forum.IsPrivate)
				{
					UsersOnline.PrivateLocation();
				}
				else
				{
					UsersOnline.SetLocation(post.Subject);
				}

			if (tagEditorPanel != null)
			{
				tagEditorPanel.PostID = post.PostID;
				tagEditorPanel.SelectedTags = post.Categories;
			}

			if(trackingButton != null && topPost != null && thread != null)
			{
				trackingButton.IsTracked = ThreadTracking.IsTracked(post.ThreadID,csContext.User.UserID);
				trackingButton.ThreadID = thread.ThreadID;
			}

			if (rateThread != null && topPost != null && thread != null)
			{
				rateThread.Post = topPost;
				rateThread.Thread = thread;
                
				if (CSContext.Current.SiteSettings.SectionRatingType == SectionRatingType.ThreadRating)
					rateThread.Visible = true;
			}

			if (forumName != null)
				forumName.Text = post.Subject;

			if (threadLink != null)
			{
				threadLink.Text = ResourceManager.GetString("SinglePostView_ViewThread");
				threadLink.NavigateUrl = Globals.GetSiteUrls().Post(post.PostID);
			}

			User user = post.User;
			Boolean userCanReply = UserCanReply();

			if (postDate != null)
				postDate.Text = Formatter.FormatAgoDate(post.PostDate);

			if (ratePost != null)
			{
				ratePost.Post = post;
				if (CSContext.Current.SiteSettings.SectionRatingType == SectionRatingType.PostRating)
					ratePost.Visible = true;
			}

			if (replyButton != null) 
			{
				replyButton.Post = post;
				replyButton.Visible = userCanReply;
			}

			if (quoteButton != null) 
			{
				quoteButton.Post = post;
				quoteButton.Visible = userCanReply;
			}

			if (deleteButton != null) 
			{
				deleteButton.Post = post;
				deleteButton.Visible = permission.Delete;
			}

			if (editButton != null) 
			{
				editButton.Post = post;
				editButton.Visible = permission.Edit && (!forum.IsModerated || (user.ModerationLevel == ModerationLevel.Unmoderated));
			}

			if (modPopupMenu != null)
			{
				modPopupMenu.Post = post;
				modPopupMenu.Forum = forum;

				modPopupMenu.PostModerateRefresh += new EventHandler(ModerationMenu_PostModerateRefresh);
			}

			if (favoritePopupMenu != null)
			{
				favoritePopupMenu.PostID = post.PostID;
				favoritePopupMenu.SectionID = forum.SectionID;
				favoritePopupMenu.UserID = post.User.UserID;
				favoritePopupMenu.ApplicationType = ApplicationType.Forum;
			}

			if (contactPopupMenu != null)
			{
				if (post.User.IsAnonymous)
					contactPopupMenu.Visible = false;
				else
					contactPopupMenu.UserID = post.User.UserID;
			}

			// Notice the following controls that the user should be seen as anonymous
			//
			bool showUserAsAnonymous = (post.IsAnonymousPost && siteEnableUserPostingAsAnonymous && forumEnableUserPostingAsAnonymous);

			if (onlineStatus != null) 
			{ 
				onlineStatus.User = user;
				onlineStatus.IsCloakedUser = showUserAsAnonymous;
			}

			if (avatar != null) 
			{
				avatar.User = user;
				avatar.IsCloakedUser = showUserAsAnonymous;
			}

			if (username != null)
			{
				if (post.PostShouldBeIgnored)
				{
					username.Text = Formatter.FormatUsername ( user.UserID, post.Username, true, false, true );
				}
				else
				{
					username.Text = Formatter.FormatUsername ( user.UserID, post.Username, showUserAsAnonymous );
				}
			}

			if (postIcon != null) 
			{
				postIcon.User = user;
				postIcon.IsCloakedUser = showUserAsAnonymous;
			}

			if (roleIcon != null) 
			{
				roleIcon.User = user;
				roleIcon.IsCloakedUser = showUserAsAnonymous;
			}

			if (joinedAttribute != null) 
			{
				joinedAttribute.User = user;
				joinedAttribute.IsCloakedUser = showUserAsAnonymous;
			}

			if (locationAttribute != null) 
			{
				locationAttribute.User = user;
				locationAttribute.IsCloakedUser = showUserAsAnonymous;
			}

			if (postsAttribute != null) 
			{
				postsAttribute.User = user;
				postsAttribute.IsCloakedUser = showUserAsAnonymous;
			}

			if (pointsAttribute != null)
			{
				pointsAttribute.User = user;
				pointsAttribute.IsCloakedUser = showUserAsAnonymous;
			}

			if (emoticon != null)
				emoticon.Text = Formatter.GetEmotionMarkup( post.EmoticonID );

			if (subject != null)
				subject.Text = post.Subject;
		
			if (postAttachment!= null)
				postAttachment.Post = post;

			if (postView != null)
				postView.Post = post;

			if(quickReply != null)
			{
				if(!post.IsLocked && !currentUser.IsAnonymous && userCanReply)
				{
					quickReply.NavigateUrl =  "javascript:" + "showQuickReply(" + post.PostID.ToString() + ")";
					quickReply.Attributes.Add("onclick", "showQuickReply(" + post.PostID.ToString() + ")");
					quickReply.Text = ResourceManager.GetString("QuickReply");
				}
				else
				{
					quickReply.Visible = false;
				}
				//PostViewWrapper.Attributes.Add("ondblclick", "showQuickReply(" + post.PostID.ToString() + ")");
				//JavaScript.RegisterControlForToolTip(PostViewWrapper,string.Format(ResourceManager.GetString("QuickReply_Popup_Message"),post.User.DisplayName),150);
			}

			if (postAnchor != null)
				postAnchor.Name = post.PostID.ToString();

			if (buttonsForPoster != null) 
			{
				buttonsForPoster.User = user;
				buttonsForPoster.IsCloakedUser = showUserAsAnonymous;
			}

			if (postPoints != null)
				postPoints.Text = Formatter.PostPoints( post );

			if (postIPAddress != null)
				postIPAddress.Text = Formatter.PostIPAddress( post );

			if ((reportLink != null) && (reportForum != null))
			{
				reportLink.Visible = !user.IsAnonymous;

				ForumUrls forumUrls = new ForumUrls();
				reportLink.NavigateUrl = forumUrls.Report(reportForum.SectionID)  + "&ReportPostID=" + post.PostID.ToString();
				reportLink.Text = ResourceManager.GetString("Report");
			}

		}

		private Boolean UserCanReply() 
		{
			if (currentUser.IsAnonymous)
				return true;
			
			Boolean permissionToReply = permission.Reply;
			Boolean anonUserCanPost = ( CSContext.Current.SiteSettings.EnableAnonymousUserPosting && forum.EnableAnonymousPosting );
			return ( permissionToReply && ( !currentUser.IsAnonymous || anonUserCanPost ) );
		}

		private Boolean UserCanPost() 
		{
			if (currentUser.IsAnonymous)
				return true;

			Boolean permissionToPost = permission.Post;
			Boolean anonUserCanPost = ( CSContext.Current.SiteSettings.EnableAnonymousUserPosting && forum.EnableAnonymousPosting );
			return ( permissionToPost && ( !currentUser.IsAnonymous || anonUserCanPost ) );
		}

		protected string BuildQuickReplyScript()
		{
			string url = ForumUrls.Instance().QuickReply;

			StringBuilder sb = new StringBuilder();
			sb.AppendFormat(@"<script type=""text/javascript"">{0}", Environment.NewLine);
			sb.AppendFormat(@"function showQuickReply(postID) {{{0}", Environment.NewLine);
			sb.AppendFormat(@" Telligent_Modal.Open('{0}'+postID,{1},{2},reLoadPage); {3}", url,600,400, Environment.NewLine);
			sb.AppendFormat(@"}}{0}", Environment.NewLine);

			//            sb.Append("function reloadCallback(res){	if(shouldRefresh){refresh();}}");
			//            sb.Append(Environment.NewLine);


			sb.Append("function reLoadPage(shouldRefresh){	if(shouldRefresh){refresh();}}");
			sb.Append(Environment.NewLine);

			sb.AppendFormat(@"</script>{0}", Environment.NewLine);
			return sb.ToString();
		}
		#endregion
	}
}
