//------------------------------------------------------------------------------
// <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.WebControls;
using CommunityServer.Components;
using CommunityServer.Controls;
using CommunityServer.Discussions.Components;

namespace CommunityServer.Discussions.Controls 
{
    // *********************************************************************
    //  ModerationMenu
    //
    /// <summary>
    /// This control renders a moderation menu used by forum moderators
    /// to moderate new posts.
    /// </summary>
    // ********************************************************************/ 	
    public class ModerationMenu : TemplatedWebControl 
    {
        #region Child Controls

        Label PostID;
        HyperLink Approve;
		LinkButton ApproveView;
        LinkButton ToggleLockUnlockPost;
        HyperLink ToggleModerateUnModerateUser;
        HyperLink Move;
        HyperLink MergeSplit;
        HyperLink DeletePost;
        HyperLink EditPost;
        HyperLink EditUser;
        HyperLink ModerationHistory;

        ForumPost post;
        Forum forum;
        CSContext csContext;
        bool canModerate = false;
        bool canEdit = false;

        #endregion

		protected override void OnInit(EventArgs e) 
		{
			csContext = CSContext.Current;

			if (SkinName == null)
				ExternalSkinFileName = "Moderation/Skin-ModerationMenu.ascx";
			else
				ExternalSkinFileName = SkinName;

			AjaxManager.Register(this,"Moderation", true, AjaxDebug.None);
			BuildCallbackScript();

			base.OnInit(e);
		}

		private void BuildCallbackScript()
		{
			StringBuilder sb = new StringBuilder();

			sb.Append("\n<script language='javascript' type=\"text/javascript\">\n");
			sb.Append("\nfunction DoApprovePost(containerID, postID)\n{\n\tModeration.ApprovePostAjax(containerID, postID, ApprovePostCallback);\n}\n");
			sb.Append("\nfunction DoToggleModeration(containerID, userID, controlID)\n{\n\tModeration.ToggleModerationAjax(containerID, userID, controlID, ToggleModerationCallback);\n}\n");
			sb.Append("\nfunction DoQuickDelete(url)\n{\n\tTelligent_Modal.Open(url, 600, 500, QuickDeleteCallback);\n}\n");
			sb.Append("\nfunction DoQuickHistory(url)\n{\n\tTelligent_Modal.Open(url, 600, 300, null);\n}\n");
			sb.Append("\nfunction ApprovePostCallback(response)\n{\n\tHidePost(response.value);\n}\n");
			sb.Append("\nfunction ToggleModerationCallback(response)\n{\n\tSetText(response.value[0], response.value[1]);\n}\n");
			sb.Append("\nfunction QuickDeleteCallback(postID)\n{\n\tif (postID != -1)\n\tHidePost(postID);\n}\n");
			sb.Append("\nfunction HidePost(postID)\n{\n\tvar control = document.getElementById('Post_' + postID);\n\tcontrol.style.display = 'none';\n}\n");
			sb.Append("\nfunction SetText(controlID, text)\n{\n\tvar control = document.getElementById(controlID);\n\tcontrol.innerHTML = text;\n}\n");
			sb.Append("\n</script>");

			Page.RegisterClientScriptBlock("DoWrappersAndAJAXCallbacks", sb.ToString());
		}

        protected override void OnLoad(EventArgs e) 
        {
            DataBind();

            base.OnLoad(e);
        }

        #region DataBind

        public override void DataBind() 
        {
            base.DataBind();
         
            // If the current user does not have moderate permissions on the post, return.
            //
            User user = csContext.User;

            if (this.Post == null)
                return;

            int postID = this.Post.PostID;
            
            // If we don't have the forum, then go get it
            if (forum == null)
                forum = this.Post.Forum;

            canModerate = Permissions.ValidatePermissions( forum, Permission.Moderate, user );
            canModerate |= user.IsForumAdministrator;

            canEdit = Permissions.ValidatePermissions( forum, Permission.EditOthers, user );

            // Stop here if no permissions
            //
            if (!canModerate && !canEdit)
            {
                this.Visible = false;
                return;
            }

            bool trueRedirect = this.UsePathToRedirect;

            if (null != PostID) 
                PostID.Text = this.Post.PostID.ToString();

			// Add the Approve click event handler.
			//
			if (null != Approve) 
			{
				Approve.NavigateUrl = string.Format("javascript:DoApprovePost('{0}', {1});", this.ClientID, this.Post.PostID.ToString());
				Approve.Text = ResourceManager.GetString("ModerationMenu_Approve");
			}

            // Add the ApproveView click event handler.
            //
            if (null != ApproveView) 
            {
                ApproveView.Text = ResourceManager.GetString("ModerationMenu_ApproveView");
                ApproveView.CommandArgument = this.Post.PostID.ToString();
            }

            // Set the EditPost url to the ModeratePostEdit url.
            //
            if (null != EditPost) 
            {
                EditPost.Visible = true;
                // Set the text for the hyperlink
                EditPost.Text = ResourceManager.GetString("ModeratePost_EditPost");
                EditPost.NavigateUrl = Globals.GetSiteUrls().ModeratePostEdit(this.Post.PostID, Globals.UrlEncode(HttpContext.Current.Request.Url.PathAndQuery + "#" + this.Post.PostID.ToString()));
            }

            // Set the DeleteApprovedPost url based on the post level of the post.
            //
			if (null != DeletePost)
			{
				// Set the text for the hyperlink
				//
				if (this.Post.PostLevel == 1) 
					DeletePost.Text = ResourceManager.GetString("ModerationMenu_DeleteThread");
				else
					DeletePost.Text = ResourceManager.GetString("ModerationMenu_DeletePost");

				DeletePost.NavigateUrl = Globals.GetSiteUrls().ModeratePostDelete(this.Post.PostID, Globals.UrlEncode(HttpContext.Current.Request.Url.PathAndQuery));
			}

            // Set the Move url to the ModeratePostMove url if the post level is 1, otherwise disable the move control.
            //
            if (null != Move) 
            {
                if (this.Post.PostLevel == 1) 
                {
                    Move.Text = ResourceManager.GetString("ModeratePost_Move");
                    Move.NavigateUrl = Globals.GetSiteUrls().ModeratePostMove(this.Post.PostID, Globals.UrlEncode(HttpContext.Current.Request.Url.PathAndQuery));
                }
                else
                {
                    Move.Text = Move.Text = ResourceManager.GetString("ModeratePost_Move");
                    Move.NavigateUrl = "";
                    Move.ForeColor = System.Drawing.Color.Gray;
                }
            }

            // Set the Split url to the ModerateThreadSplit url
            //
            if (null != MergeSplit) 
            {
                if (this.Post.PostLevel > 1) 
                {
                    MergeSplit.Text = ResourceManager.GetString("ModerateThread_Split");
                    MergeSplit.NavigateUrl = Globals.GetSiteUrls().ModerateThreadSplit(this.Post.PostID, Globals.UrlEncode(HttpContext.Current.Request.Url.PathAndQuery));
                } 
                else 
                {
                    MergeSplit.NavigateUrl = Globals.GetSiteUrls().ModerateThreadJoin(this.Post.PostID, HttpContext.Current.Request.Url.PathAndQuery);
                    MergeSplit.Text = ResourceManager.GetString("ModerateThread_Join");
                }
            }

            // Toggle Lock / Unlock Post
            //
            if (null != ToggleLockUnlockPost) 
            {
                if (this.Post.PostLevel > 1) 
                {
                    ToggleLockUnlockPost.Visible = false;
                    FindControl("HideLockSpan").Visible = false;
                } 
                else 
                {
                    if (this.Post.IsLocked) 
                    {
                        ToggleLockUnlockPost.Text = ResourceManager.GetString("ModerateThread_UnLock_Thread");
                    } 
                    else 
                    {
                        ToggleLockUnlockPost.Text = ResourceManager.GetString("ModerateThread_Lock_Thread");
                    }
                }

                ToggleLockUnlockPost.CommandArgument = this.Post.PostID.ToString();
            }

            if (canModerate) 
            {
                // set the EditUser url
                //
                if (null != EditUser) 
                {
                    // Set the text for the hyperlink
                    EditUser.Text = ResourceManager.GetString("ModeratePost_EditUser");
                    EditUser.NavigateUrl = Globals.GetSiteUrls().ControlPanelUserEdit(this.Post.User.UserID);
                }
			
                // Toggle Moderate / Unmoderate User
                //
                if (null != ToggleModerateUnModerateUser) 
                {
                    // TODO: Get a fresh copy of user data to have moderation status working right
                    //
                    //User freshUserData = Users.GetUser( this.Post.User.UserID, false, false );
                    //switch (freshUserData.ModerationLevel)

					ToggleModerateUnModerateUser.NavigateUrl = string.Format("javascript:DoToggleModeration('{0}', {1}, '{2}');", this.ClientID, Post.User.UserID.ToString(), ToggleModerateUnModerateUser.ClientID);
                    switch (this.Post.User.ModerationLevel) 
                    {
                        case ModerationLevel.Unmoderated:
                            ToggleModerateUnModerateUser.Text = ResourceManager.GetString("ModerateThread_Moderate_User");
                            break;

                        case ModerationLevel.Moderated:
                            ToggleModerateUnModerateUser.Text = ResourceManager.GetString("ModerateThread_UnModerate_User");
                            break;

                        default:
                            ToggleModerateUnModerateUser.Enabled = false;
                            break;

                    }
                }

                // Set the ModerationHistory url.
                //
                if (null != ModerationHistory && 
                    csContext.SiteSettings.EnableUserModerationCounters) 
                {
                    ModerationHistory.Text = ResourceManager.GetString("ModeratePost_ModerationHistory");
                    ModerationHistory.NavigateUrl = string.Format("javascript:DoQuickHistory('{0}')", Globals.GetSiteUrls().ModerationQuickHistory(Post.PostID));
                }
                else
                {
                    if (null != ModerationHistory)
                        ModerationHistory.Enabled = false;
                }
            }
            else 
            {
                if (EditUser != null)
                    EditUser.Enabled = false;
				
                if (ToggleModerateUnModerateUser != null)
                   ToggleModerateUnModerateUser.Enabled = false;

                if (ModerationHistory != null)
                    ModerationHistory.Enabled = false;
            }
        }
        
        #endregion

        #region Skin

		protected override void AttachChildControls() 
		{
			PostID = (Label) FindControl("PostID");
			Approve = (HyperLink) FindControl("Approve");
			ApproveView = (LinkButton) FindControl("ApproveView");
			EditPost = (HyperLink) FindControl("EditPost");
			DeletePost = (HyperLink) FindControl("DeletePost");
			Move = (HyperLink) FindControl("Move");
			MergeSplit = (HyperLink) FindControl("MergeSplit");
			ToggleLockUnlockPost = (LinkButton) FindControl("ToggleLockUnlockPost");
			EditUser = (HyperLink) FindControl("EditUser");
			ToggleModerateUnModerateUser = (HyperLink) FindControl("ToggleModerateUnModerateUser");
			ModerationHistory = (HyperLink) FindControl("History");

			InitializeChildControls();
		}

        private void InitializeChildControls() 
        {
            if (null != ApproveView) 
                ApproveView.Click += new EventHandler(ApproveView_Click);

            if (null != ToggleLockUnlockPost) 
                ToggleLockUnlockPost.Click += new EventHandler(LockUnlock_Click);
        }

        #endregion

        #region Properties

        /// <summary>
        /// Property UsePathToRedirect (bool)
        /// </summary>
        public bool UsePathToRedirect
        {
            get 
            {  
                object obj = ViewState["UsePathToRedirect"];
                return obj == null ? false : (bool)obj;
            }
            set {  ViewState["UsePathToRedirect"] = value; }
        }

        // *********************************************************************
        //  Post
        //
        /// <summary>
        /// Gets or sets the post to moderate.
        /// </summary>
        // ***********************************************************************/
        public ForumPost Post 
        {
            get 
            {
                if ( post == null ) 
                {
                    Object state = ViewState["Post"];
                    if ( state != null ) 
                    {
                        Int32 postID = (Int32)state;
                        post = Posts.GetPost( postID, CSContext.Current.User.UserID, false );
                    }
                }
                return post;
            }
            set 
            {
                post = value;
                if ( post != null ) 
                {
                    ViewState[ "Post" ] = post.PostID;
                } 
                else 
                {
                    ViewState.Remove( "Post" );
                }
            }
        }

		// *********************************************************************
		//  Forum
		//
		/// <summary>
		/// Gets or sets the forum the post is in..
		/// </summary>
		// ***********************************************************************/
		public Forum Forum 
		{
			get 
			{
				if ( forum == null ) 
				{
					Object state = ViewState["SectionID"];
					if ( state != null ) 
					{
						Int32 sectionID = (Int32)state;
						forum = Forums.GetForum(sectionID);
					}
				}
				return forum;
			}
			set 
			{
				forum = value;
				if ( forum != null ) 
				{
					ViewState[ "SectionID" ] = forum.SectionID;
				} 
				else 
				{
					ViewState.Remove( "SectionID" );
				}
			}
		}

        #endregion

        #region Events

        public event EventHandler PostModerateRefresh;
        private void OnPostModerateRefresh(EventArgs e)
		{
			if(PostModerateRefresh != null)
				PostModerateRefresh(null, e);
		}

        #endregion

        #region Event Handlers

		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public string ApprovePostAjax(int postID)
		{
			ApprovePost(postID);

			// Prepare response (hide approved post)
			return postID.ToString();
		}

		public void ApprovePost(int postID)
		{
			ForumPost post = Posts.GetPost(postID, csContext.User.UserID);
			Moderate.ApprovePost(post, csContext.User.UserID);
		}

		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public string[] ToggleModerationAjax(int userID, string controlID)
		{
			User user = Users.GetUser(userID, false, false);
			Moderate.ToggleUserSettings(ModerateUserSetting.ToggleModerate, user, csContext.User.UserID);

			// Prepare response (toggle text "moderate user" <--> "unmoderate user")
			string text = (user.ModerationLevel == ModerationLevel.Moderated) ? ResourceManager.GetString("ModerateThread_Moderate_User") : ResourceManager.GetString("ModerateThread_UnModerate_User");
			return new string[] {controlID, text};
		}

        // *********************************************************************
        //  LockUnlock_Click
        //
        /// <summary>
        /// Event handler for approving a post and replying to the post.
        /// </summary>
        // ***********************************************************************/
        private void LockUnlock_Click (object sender, EventArgs e) 
        {
            LinkButton b = (LinkButton) sender;

            int postID = int.Parse(b.CommandArgument);
            ForumPost post = Posts.GetPost(postID, csContext.User.UserID);

			// Check for access before submitting
			Permissions.AccessCheck( post.Section, Permission.Moderate, csContext.User, post );

			// Doing this twice just in case the exception thrown from the access check doesn't fully abort execution
            if(Permissions.ValidatePermissions(post.Section, Permission.Moderate, csContext.User, post))
				Moderate.TogglePostSettings(ModeratePostSetting.ToggleLock, post, csContext.User.UserID);

			// Fire an event to refresh the thread
			OnPostModerateRefresh(e);
        }

        // *********************************************************************
        //  ApproveView_Click
        //
        /// <summary>
        /// Event handler for approving a post and viewing the post.
        /// </summary>
        // ***********************************************************************/
        private void ApproveView_Click(object sender, EventArgs e) 
        {
            LinkButton b = (LinkButton) sender;

            int postID = int.Parse(b.CommandArgument);

			ApprovePost(postID);

            // Redirect the user to the PostReply url.
            Context.Response.Redirect(Globals.GetSiteUrls().Post(postID));
            Context.Response.End();
        }
        #endregion
    }
}
