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

using System;
using System.Collections;
using System.IO;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using CommunityServer.Components;
using CommunityServer.Controls;
using CommunityServer.Discussions.Components;
using CA = ComponentArt.Web.UI;
using TWC = Telligent.Web.UI;

namespace CommunityServer.Discussions.Controls 
{
    /// <summary>
    /// This Web control allows the user to create a new post or edit an existing post.
    /// The Mode property determines what action is being taken.  A value of NewPost, the
    /// default, constructs Web controls for creating a new post; a value of ReplyToPost
    /// assumes the person is replying to an existing post; a value of EditPost allows the
    /// user to edit an existing post.
    /// </summary>
    /// <remarks>
    /// When adding a new post, the ForumID must be specified, which indicates what forum the
    /// new post belongs to.  When replying to a post, the PostID property must be specified, indicating
    /// the post that is being replied to.  When editing a post, the PostID property must be
    /// specified, indicating the post to edit.  Failure to specify these required properties
    /// will cause an Exception to be thrown.
    /// </remarks>    
    public class CreateEditPost: TemplatedWebControl 
    {
        #region Member Variables

        //ViewOptions postView;
        Editor postBody = null;        
        DropDownList pinnedPost;
        //ForumRolloverImageButton allowReply;
        CheckBox isLocked;
        CheckBox subscribeToThread;
        TextBox forumsPostedTo;

        CheckBox isAnonymousPost;
        PostIconRadioButtonList postIcon;
		PostFlatPreview postFlatPreview;
        TWC.TabbedPanes editorTabs;
        InkWebControl inkControl = null;
        CheckBox enableInk = null;
		TextBox videoUrl = null;
		TextBox videoImageUrl = null;
		TextBox videoDuration = null;
		TextBox videoHeight = null;
		TextBox videoWidth = null;
        HtmlInputHidden ServerUploadTempID, ServerFilename;
		Modal AddUpdateAttachment;
		IText Filename;
		PollEditor PollEditor;
		CheckBox IncludePoll;

		TagEditor Tags;
		PlaceHolder TaggingArea;

        CSContext csContext = CSContext.Current;
        bool userMayPostAsAnonymous = false;
        Forum forum;
        ForumPost postReplyingTo;
        User user;

        #endregion

        #region CreateEditPost Constructor

        /// <remarks>
        /// Class contructor used to determine the mode of the server control.
        /// Also it inits whatever is needed to be known about current post.
        /// </remarks>
        public CreateEditPost () 
        {
            // Fire the authorize post event
            //
            CSEvents.AuthorizePost();
            
            // Get the current user
            //
            user = csContext.User;

            // Is the user anonymous?
            //
            if (!csContext.Context.Request.IsAuthenticated)
                user = Users.GetAnonymousUser();

            // Do we have a PostID?
            //
            if (csContext.PostID > 0) 
            {
                postReplyingTo = Posts.GetPost(csContext.PostID, csContext.User.UserID);
                forum = postReplyingTo.Section as Forum;
                PostMode = CreateEditPostMode.ReplyToPost;
            }

            // Do we have a ForumID?
            //
            if (csContext.SectionID > 0) 
            {
                forum = Forums.GetForum(csContext.SectionID, false, true);
                PostMode = CreateEditPostMode.NewPost;
            }

            // Are we reporting a post?
            //
            if (csContext.GetIntFromQueryString("ReportPostID", -1) > 0)
                PostMode = CreateEditPostMode.ReportingPost;

            // Is this a private message?
            //
            if ((csContext.SectionID == 0) && (csContext.UserID > 0)) 
            {
                Users.ValidateUserAccess(Users.GetUser(csContext.UserID,false), csContext.User);
                forum = Forums.GetForum(0);
                PostMode = CreateEditPostMode.NewPrivateMessage;
            }

            // Security check to see if the forum allows anonymous posts
            //
            if ( user.IsAnonymous && (!forum.EnableAnonymousPosting || !csContext.SiteSettings.EnableAnonymousUserPosting) ) 
            {
                if (!csContext.Context.Request.IsAuthenticated) 
                {
                    csContext.Context.Response.Redirect(Globals.GetSiteUrls().Login);
                    csContext.Context.Response.End();
                }
            }

            // If we don't have either a forum id or a post id we have an error
            //
            if ((csContext.SectionID < 0) && (csContext.PostID < 0)) 
            {
                throw new CSException(CSExceptionType.PostNotFound);
            }

            /*
            // Is a mode specified?
            //
            if (null != Context.Request.QueryString["Mode"]) 
            {
                string mode = Context.Request.QueryString["Mode"];

//                if (mode == "flat")
//                    postView = ViewOptions.Flat;
//                else
//                    postView = ViewOptions.Threaded;

            } 
            else if (null != Context.Request.Form["Mode"]) 
            {
                string mode = Context.Request.Form["Mode"];

//                if (mode == "flat")
//                    postView = ViewOptions.Flat;
//                else
//                    postView = ViewOptions.Threaded;
            }*/
        }

        #endregion

        protected override void OnInit(EventArgs e) 
        {
            if (SkinName == null)                
                ExternalSkinFileName = "View-CreateEditPost.ascx";
            else 
                ExternalSkinFileName = SkinName;
			
			AjaxManager.Register(this,"CreateEditPost");

            base.OnInit(e);
        }
        
        #region Initialize skin and other display methods

        CA.CallBack SearchCallBack;

        #region AttachChildControls
        // *********************************************************************
        //  Initializeskin
        //
        /// <remarks>
        /// Initialize the control template and populate the control with values
        /// </remarks>
        // ***********************************************************************/
        override protected void AttachChildControls() 
        {
            SearchCallBack = FindControl("SearchCallBack") as CA.CallBack;
            SearchCallBack.Callback +=new CA.CallBack.CallbackEventHandler(SearchCallBack_Callback);



            FindControl("Icons").Visible = (csContext.SiteSettings.EnableEmoticons && csContext.User.Profile.EnableEmoticons);
            // Is the post locked checkbox
            //
            isLocked = (CheckBox) FindControl("IsLocked");
            isLocked.Text = ResourceManager.GetString("CreateEditPost_IsLocked");
                        
            // Is anonymous posting enabled?
            //
            if (ForumConfiguration.Instance().EnableUserPostingAsAnonymous && 
                forum.EnableAnonymousPostingForUsers) 
            {
                userMayPostAsAnonymous = true;
            } 
            else 
            { 
                userMayPostAsAnonymous = false;
            }

            // If we aren't using Emoticons do not render them.
            if (csContext.SiteSettings.EnableEmoticons) 
            {
                postIcon = (PostIconRadioButtonList) FindControl( "PostIcon" );
                postIcon.AutoCreate = false;
                postIcon.DataBind();
            }

            // Get the attachment controls
            //
            Filename = FindText("Filename");
			ServerUploadTempID = (HtmlInputHidden) FindControl("ServerUploadTempID");
			ServerFilename = (HtmlInputHidden) FindControl("ServerFilename");
			AddUpdateAttachment = (Modal) FindControl("AddUpdateAttachment");
			postFlatPreview = (PostFlatPreview) FindControl("PostFlatPreview");
            editorTabs = FindControl("EditorTabs") as TWC.TabbedPanes;
            inkControl = FindControl("inkControl") as InkWebControl;
            enableInk = FindControl("EnableInk") as CheckBox;
			videoUrl = FindControl("VideoUrl") as TextBox;
			videoImageUrl = FindControl("VideoImageUrl") as TextBox;
			videoDuration = FindControl("VideoDuration") as TextBox;
			videoHeight = FindControl("VideoHeight") as TextBox;
			videoWidth = FindControl("VideoWidth") as TextBox;

			Tags = FindControl("Tags") as TagEditor;
			TaggingArea = FindControl("TaggingArea") as PlaceHolder;

			if (postFlatPreview != null)
				postFlatPreview.Visible = false;

            // Does the user wish to subscribe to threads checkbox
            //
            if (!user.IsAnonymous) 
            {
                subscribeToThread = (CheckBox) FindControl("SubscribeToThread");
                subscribeToThread.Text = ResourceManager.GetString("CreateEditPost_SubscribeToThread");

                subscribeToThread.Checked = user.EnableThreadTracking;
                subscribeToThread.Visible = user.EnableThreadTracking;
            } 
            else 
            {
                subscribeToThread = (CheckBox) FindControl("SubscribeToThread");
                subscribeToThread.Checked = false;
                subscribeToThread.Visible = false;
                
                // Make it unavailable for anonymous users
                //
                userMayPostAsAnonymous = false;
            }

            // Get anonymous posting reference
            //
            isAnonymousPost = (CheckBox) FindControl( "IsAnonymousPost" );
            isAnonymousPost.Text = ResourceManager.GetString( "CreateEditPost_IsAnonymousPost" );
            if (userMayPostAsAnonymous)
                isAnonymousPost.Visible = true;
            else
                isAnonymousPost.Visible = false;

			IncludePoll = (CheckBox) FindControl("IncludePoll");
			PollEditor = (PollEditor) FindControl("PollEditor");

            // Set the ID
            //
            base.ID = "PostForm";

            if ((PostMode == CreateEditPostMode.ReplyToPost) && (forum.SectionID == 0))
                PostMode = CreateEditPostMode.ReplyPrivateMessage;
			
            // Optionally display reply, post, and preview
            //
            switch (PostMode) 
            {
                case CreateEditPostMode.NewPrivateMessage:
                    DisplayPost();
                    
                    break;

                case CreateEditPostMode.ReplyPrivateMessage:
                case CreateEditPostMode.ReplyToPost:
                    DisplayReply();
                    DisplayPost();
                    
                    break;

                default:
                    DisplayPost();
                    
                    break;
            }

            // Check if flood interval is enabled and if the user needs to wait.
            //
            if ((PostMode == CreateEditPostMode.NewPost) || (PostMode == CreateEditPostMode.ReplyToPost))
				if(ForumConfiguration.Instance().EnableFloodIntervalChecking && !user.IsForumAdministrator)
					if(!Users.CheckUserLastPostDate(user, ForumConfiguration.Instance().PostInterval))
						throw new CSException(CSExceptionType.FloodDenied);

			
        }
        #endregion
        
        #region DisplayPost
        /***********************************************************************
        // DisplayPost
        //
        /// <remarks>
        /// When a user replies to a post, the user control that controls the UI
        /// is loaded and passed to this method. Elements of the form are then wired
        /// up to handle events, such as button clicks
        /// </remarks>
        /// <param name="control">Usercontrol used to control UI formatting</param>
        ***********************************************************************/
        private void DisplayPost() 
        {            
            ForumPost post = null;
            bool isQuote = false;
            string replyPrePend = ResourceManager.GetString("CreateEditPost_ReplyPrePend");

            Label title = FindControl("ForumName") as Label;
            Label desc = FindControl("ForumDescription") as Label;
            postBody = FindControl("PostBody") as Editor;

            //RadioButtonList postIcon;
            bool allowAttachment = this.AllowAttachments; // call this only one in this method

            // Are we quoting another post?
            //
            if (csContext.Context.Request.QueryString["Quote"] != null) 
            {                				
                isQuote = true;
            }

            if (isQuote || ((PostMode == CreateEditPostMode.ReplyToPost) || (PostMode == CreateEditPostMode.ReplyPrivateMessage)))
            {
                post = Posts.GetPost(csContext.PostID, csContext.User.UserID);
            }

            User user = csContext.User;

            // Is the user allowed to add new attachments?
            //
            if (allowAttachment) 
            {
				if (FindControl("editAttachment") != null) 
					FindControl("editAttachment").Visible = true;

				if (postReplyingTo != null && postReplyingTo.HasAttachment)
				{
					if (PostMode == CreateEditPostMode.EditPost)
					{
					if (Filename != null)
						Filename.Text = postReplyingTo.AttachmentFilename;

					if (ServerUploadTempID != null)
						ServerUploadTempID.Value = "Existing";
				}
				}

				if (AddUpdateAttachment != null)
				{
					AddUpdateAttachment.Url = ForumUrls.Instance().UploadAttachment(this.forum.SectionID);
				}

                inkControl.Enabled = AllowInk;

				SetPaneVisible("InkPane", inkControl.Enabled);
            }

			SetPaneVisible("VideoPane", AllowVideo);
			SetPaneVisible("PollPane", AllowPoll);

			if (IncludePoll != null && postReplyingTo != null)
				IncludePoll.Checked = postReplyingTo.HasPoll;

			if (TaggingArea != null)
				TaggingArea.Visible = AllowTagging;

			if (AllowTagging && this.Tags != null)
				Tags.AvailableTags = PostCategories.GetCategories(this.forum.SectionID, true, true);

            // Set the title message
            //
            switch (PostMode) 
            {
                case CreateEditPostMode.NewPost:
                    // Access Check
                    //
                    Permissions.AccessCheck(forum, Permission.Post, user);
                    
                    title.Text = ResourceManager.GetString("CreateEditPost_Title_PostNewMessage");
                    desc.Text = ResourceManager.GetString("CreateEditPost_Title_PostNewMessageDesc");
                    Head.AddSiteNameTitle(title.Text,Context);

					// PollEditor must always be bound
					if (PollEditor != null)
						PollEditor.DataBind();

                    break;

                case CreateEditPostMode.NewPrivateMessage:
                    FindControl("MessageTo").Visible = true;
                    Head.AddSiteNameTitle(ResourceManager.GetString("ViewUserProfile_PrivateMessage"), Context);

                    break;

                case CreateEditPostMode.ReplyPrivateMessage:
                case CreateEditPostMode.ReplyToPost:
                    // Access Check
                    //
                    if (post != null) 
                        Permissions.AccessCheck(forum, Permission.Reply, user, post);

                    title.Text = ResourceManager.GetString("CreateEditPost_Title_ReplyMessage");
                    desc.Text = string.Format(ResourceManager.GetString("CreateEditPost_Inline1"), post.Subject);					
				    Head.AddSiteNameTitle(ResourceManager.GetString("CreateEditPost_Title_ReplyMessage") + " - " + post.Subject,Context);

					break;

                case CreateEditPostMode.ReportingPost:
                    // TODO: Access Check !?
                    //
                    break;

                case CreateEditPostMode.EditPost:
                    // Don't allow to edit an XML poll
                    //
                    if (postReplyingTo.PostType == PostContentType.Xml)
                    {
                        if (!Globals.IsNullorEmpty(csContext.ReturnUrl))
                            Context.Response.Redirect(csContext.ReturnUrl);
                        else
                            Context.Response.Redirect(Globals.GetSiteUrls().Home);
                    }

                    // Access Check
                    //
                    Permissions.AccessCheck(forum, Permission.Edit, csContext.User, postReplyingTo);

                    title.Text = ResourceManager.GetString("CreateEditPost_Title_EditMessage");
                    desc.Text = string.Format(ResourceManager.GetString("CreateEditPost_Title_EditMessageDesc"), postReplyingTo.Subject);
                    Head.AddSiteNameTitle(ResourceManager.GetString("CreateEditPost_Title_EditMessage") + " - " + postReplyingTo.Subject,Context);
                    // Set the editor of the post
                    if (FindControl("PostEditor") != null)
						((Label)FindControl("PostEditor")).Text = user.DisplayName;

                    // Set the editor of the post
                    if (FindControl("Edit") != null)
                        FindControl("Edit").Visible = true;

                    // Set the isLocked Text
                    isLocked.Text = ResourceManager.GetString("CreateEditPost_IsLocked");

					if (FindControl("EditNotesArea") != null)
						FindControl("EditNotesArea").Visible = true;

					if (FindControl("CurrentEditNotesBody") != null) 
					{
						TextBox t = (TextBox) FindControl("CurrentEditNotesBody");
						t.Text = postReplyingTo.EditNotes;
					}

					RequiredFieldValidator editNotesValidator = (RequiredFieldValidator) FindControl("editNotesValidator");
					if (editNotesValidator != null ) 
					{
						editNotesValidator.ErrorMessage = ResourceManager.GetString("CreateEditPost_EditNotesRequired");
						editNotesValidator.Enabled = ForumConfiguration.Instance().RequireEditNotes;
					}

                    // Maintain state on postback
                    //
                    if (!Page.IsPostBack) 
                    {
                        // Is the post locked?
                        if (postReplyingTo.IsLocked)
                            isLocked.Checked = true;

                        // Set the Subject
                        if (FindControl("PostSubject") != null) 
                        {
                            ((TextBox) FindControl("PostSubject")).Text = csContext.Context.Server.HtmlDecode(postReplyingTo.Subject);
                        }

                        postBody.Text = postReplyingTo.Body;
                    
                        // Check if post was anonymous and set it so
                        if (userMayPostAsAnonymous /*isAnonymousPost.Visible*/)
                        { 
                            isAnonymousPost.Checked = postReplyingTo.IsAnonymousPost;
                        }

                        // Do we have a post icon?
                        if (postIcon != null)
                            postIcon.SelectedValue = postReplyingTo.EmoticonID.ToString();

                        if(postReplyingTo.HasInk && inkControl.Enabled)
                        {
                            InkData ink = Ink.Get(postReplyingTo.InkID);
                            if(ink != null)
                            {
                                inkControl.InkData = ink.InkString;
                            }
                        }

						if (postReplyingTo.HasVideo)
						{
							videoUrl.Text = postReplyingTo.VideoUrl;
							videoImageUrl.Text = postReplyingTo.VideoImageUrl;
							videoDuration.Text = postReplyingTo.VideoDuration;
							
							if (videoHeight != null)
								videoHeight.Text = postReplyingTo.VideoHeight >= 0 ? postReplyingTo.VideoHeight.ToString() : string.Empty;
							
							if (videoWidth != null)
								videoWidth.Text = postReplyingTo.VideoWidth >= 0 ? postReplyingTo.VideoWidth.ToString() : string.Empty;
						}

						if (postReplyingTo.HasPoll && PollEditor != null)
						{
							if (IncludePoll != null)
								IncludePoll.Checked = true;
						}
                    }

					// PollEditor must always be bound
					if (PollEditor != null)
					{
						PollEditor.Post = postReplyingTo;
						PollEditor.DataBind();
					}

					if (AllowTagging && this.Tags != null)
					{
						ArrayList categories = Posts.GetPostCategories(postReplyingTo.PostID);
						string[] tags = new string[categories.Count];
						int i = 0;
						foreach (PostCategory pc in categories)
						{
							tags[i] = pc.Name;
							i++;
						}		

						Tags.SelectedTags = tags;	
					}

                    break;
            }

			if (this.Tags != null)
				this.Tags.DataBind();

            // Set the subject if necessary
            //
            if ((PostMode == CreateEditPostMode.ReplyToPost) || 
                (PostMode == CreateEditPostMode.ReplyPrivateMessage))
            {			
                // Do we need to prepend, e.g. 'Re: '?
                //
                if (post.Subject.StartsWith(replyPrePend))
                    ((TextBox) FindControl("PostSubject")).Text = Globals.HtmlDecode(post.Subject);
                else
                    ((TextBox) FindControl("PostSubject")).Text = replyPrePend + Globals.HtmlDecode(post.Subject);
            }

            // Set the to if necessary

            if (PostMode == CreateEditPostMode.NewPrivateMessage) 
            {
                FindControl("MessageTo").Visible = true;
				((TextBox)FindControl("To")).Text = Users.GetUser(csContext.UserID, false).DisplayName;
            }

            if (PostMode == CreateEditPostMode.ReplyPrivateMessage) 
            {
                FindControl("MessageTo").Visible = true;

                ((TextBox) FindControl("To")).Text = PrivateMessages.GetFormattedRecipients(post.ThreadID, post.User, user.UserID);
            }

            if (PostMode == CreateEditPostMode.ReplyPrivateMessage || 
                PostMode == CreateEditPostMode.NewPrivateMessage)
            {
                subscribeToThread.Visible = false;
                subscribeToThread.Checked = false;

            }				

            // Set the Body
            //
            postBody.EnableHtmlModeEditing = true;// user.IsForumAdministrator;

            // Set forums we are posting to
            //
            forumsPostedTo = FindControl("Forums") as TextBox;
            forumsPostedTo.Text = forum.Name;
            forumsPostedTo.ReadOnly = true;

            // If we are quoting a previous post, display that post
            //
            if (isQuote) 
				postBody.Text = "[quote user=\"" + post.User.DisplayName + "\"]" + post.Body + "[/quote]";

			// Set the DisplayName
            if (FindControl("PostAuthor") != null)
				((Label)FindControl("PostAuthor")).Text = user.DisplayName;

            EnableSticky( postReplyingTo );

            // Wireup the post button
            if (FindControl("PostButton").GetType().UnderlyingSystemType.ToString() == typeof(Button).ToString() ) 
            {
                Button button = (Button) FindControl("PostButton");
                button.Text = ResourceManager.GetString("CreateEditPost_PostButton");
                button.Click  += new EventHandler(PostButton_Click);
            } 
            else 
            {
                ForumRolloverImageButton button = (ForumRolloverImageButton) FindControl("PostButton");
                button.Alt = ResourceManager.GetString("CreateEditPost_PostButton");
                button.Click  += new EventHandler(PostButton_Click);
            }

            // Wire up the cancel button
            if (FindControl("CancelButton") != null) 
            {
                Button button = (Button) FindControl("CancelButton");
                button.Text = ResourceManager.GetString("CreateEditPost_Cancel");
                button.Click += new EventHandler(CancelButton_Click);
            }

            UsersOnline.SetLocation("Create/Edit Forum Post", null);
        }

		protected void SetPaneVisible(string paneId, bool visible)
		{
			if (editorTabs != null)
			{
				TWC.TabbedPane pane = editorTabs.FindControl(paneId) as TWC.TabbedPane;
				if (pane != null)
					pane.Visible = visible;
			}
		}
        #endregion

        #region EnableSticky
        private void EnableSticky(ForumPost post) 
        {
            // Is the user allowed to create sticky posts?
            //
            if (!user.IsAnonymous) 
            {				
                // Do we allow the user to make pinned posts?
                if ((
                    (user.IsForumAdministrator) 
                    || (Permissions.ValidatePermissions( forum, Permission.Sticky, user )) 
                    || (Moderate.CheckIfUserIsModerator(user.UserID, forum.SectionID))
                    ) 
                    &&	(PostMode != CreateEditPostMode.ReplyToPost)) 
                {

                    FindControl("AllowPinnedPosts").Visible = true;
	            
                    pinnedPost = (DropDownList) FindControl("PinnedPost");
                    pinnedPost.Items.Add(new ListItem( ResourceManager.GetString("CreateEditPost_Sticky_0"), "0" ));
                    pinnedPost.Items.Add(new ListItem( ResourceManager.GetString("CreateEditPost_Sticky_1"), "1" ));
                    pinnedPost.Items.Add(new ListItem( ResourceManager.GetString("CreateEditPost_Sticky_3"), "3" ));
                    pinnedPost.Items.Add(new ListItem( ResourceManager.GetString("CreateEditPost_Sticky_7"), "7" ));
                    pinnedPost.Items.Add(new ListItem( ResourceManager.GetString("CreateEditPost_Sticky_14"), "14" ));
                    pinnedPost.Items.Add(new ListItem( ResourceManager.GetString("CreateEditPost_Sticky_30"), "30" ));
                    pinnedPost.Items.Add(new ListItem( ResourceManager.GetString("CreateEditPost_Sticky_90"), "90" ));
                    pinnedPost.Items.Add(new ListItem( ResourceManager.GetString("CreateEditPost_Sticky_180"), "180" ));
                    pinnedPost.Items.Add(new ListItem( ResourceManager.GetString("CreateEditPost_Sticky_360"), "366" ));
					if ((user.IsForumAdministrator) || (Permissions.ValidatePermissions(forum, Permission.Announcement, user)) || (Moderate.CheckIfUserIsModerator(user.UserID, forum.SectionID)))
                    pinnedPost.Items.Add(new ListItem( ResourceManager.GetString("CreateEditPost_Sticky_999"), "999" ));

                    // Do an autopost back incase we need to flip the isLocked checkbox
                    pinnedPost.AutoPostBack = true;
                    pinnedPost.SelectedIndexChanged += new EventHandler(PinnedPost_Changed);

                    // If we're editing a post, populate with the previous sticky setting
                    if (PostMode == CreateEditPostMode.EditPost && post != null)
                    { 
                        Thread thread = Threads.GetThread(post.ThreadID);
                        if (thread != null && thread.IsSticky)
                        {
                            // Get time span for 2 years
                            TimeSpan anouncementTsp = (DateTime.Now - DateTime.Now.AddYears( -2 ));
                            
                            TimeSpan remainder = thread.StickyDate.Subtract(DateTime.Now);

                            // The check is +1 day, since it is set for midnight and can sometimes be up to one day extra
                            if (remainder <= TimeSpan.FromDays(2))
                                pinnedPost.Items.FindByValue("1").Selected = true;
                            else if (remainder <= TimeSpan.FromDays(4))
                                pinnedPost.Items.FindByValue("3").Selected = true;
                            else if (remainder <= TimeSpan.FromDays(8))
                                pinnedPost.Items.FindByValue("7").Selected = true;
                            else if (remainder <= TimeSpan.FromDays(15))
                                pinnedPost.Items.FindByValue("14").Selected = true;
                            else if (remainder <= TimeSpan.FromDays(31))
                                pinnedPost.Items.FindByValue("30").Selected = true;
                            else if (remainder <= TimeSpan.FromDays(92))
                                pinnedPost.Items.FindByValue("90").Selected = true;
                            else if (remainder <= TimeSpan.FromDays(183))
                                pinnedPost.Items.FindByValue("180").Selected = true;
                            else if (remainder <= TimeSpan.FromDays(367))
                                pinnedPost.Items.FindByValue("366").Selected = true;
                            else  
                            {
                                if (remainder >= TimeSpan.FromDays( anouncementTsp.Days )) // this should be an anouncement
                                    pinnedPost.Items.FindByValue("999").Selected = true;
                            }
                        }
                    }
                }
            }
        }
        #endregion
        
        #region DisplayReply
        /***********************************************************************
        // DisplayReply
        //
        /// <remarks>
        /// When a user replies to a post, the user control that controls the UI
        /// is loaded and passed to this method. Details such as the username, subject,
        /// and message are extracted and displayed.
        /// </remarks>
        /// <param name="control">Usercontrol used to control UI formatting</param>
        ***********************************************************************/
        private void DisplayReply() 
        {
            //ForumPost post = null;
            Literal postBody;
            Literal postDetails;

            if ((PostMode == CreateEditPostMode.NewPost) || 
                (PostMode == CreateEditPostMode.ReportingPost) ||
                (PostMode == CreateEditPostMode.EditPost))
                return;
            
            // Turn off when we deal with a poll
            if (postReplyingTo.HasPoll)
                return;

            FindControl("Reply").Visible = true;

            // Set the post body
            postBody = FindControl("ReplyBody") as Literal;
            postBody.Text = postReplyingTo.FormattedBody;
            
            bool swowUserAsAnonymous = (postReplyingTo.IsAnonymousPost && ForumConfiguration.Instance().EnableUserPostingAsAnonymous && forum.EnableAnonymousPostingForUsers);
            string username = "";

            if (!swowUserAsAnonymous)
                username = postReplyingTo.User.DisplayName;
            else
                username = ResourceManager.GetString("DefaultAnonymousUsername");

            postDetails = FindControl("ReplyDetails") as Literal;
            postDetails.Text = string.Format(ResourceManager.GetString("CreateEditPost_ReplyFormat"), username, Formatter.FormatDate(postReplyingTo.PostDate, true));

            // Access check
            //
            Permissions.AccessCheck(forum, Permission.Reply, csContext.User, postReplyingTo);

            // Don't allow replies to locked posts
            if (postReplyingTo.IsLocked) 
            {
                HttpContext.Current.Response.Redirect(Globals.GetSiteUrls().Post(csContext.PostID));
                HttpContext.Current.Response.End();
            }
        }
        #endregion

        #endregion

        #region Events

        #region PinnedPost_Changed
        /***********************************************************************
        // PinnedPost_Changed
        //
        /// <remarks>
        /// Event raised when the pinned post drop down list changes. If the user
        /// selected announcemnt we need to find the allow replies check box, check it,
        /// and then disable it.
        /// </remarks>
        /// <param name="control">Usercontrol used to control UI formatting</param>
        ***********************************************************************/
        private void PinnedPost_Changed (Object sender, EventArgs e) 
        {

            // Do we have an announcement?
            if (Convert.ToInt32(pinnedPost.SelectedItem.Value) == 999) 
            {
                //allowReply.ButtonOn = true;

                // Check it and show disabled
                isLocked.Checked = true;
                isLocked.Enabled = false;
            } 
            else if (!isLocked.Checked) 
            {
                //allowReply.ButtonOn = false;

                // Show it enabled and uncheck it only if wasn't checked before postback.
                isLocked.Checked = false;
                isLocked.Enabled = true;
            } 
            else 
            {
                // Just enable and keep it as it was before postback
                isLocked.Enabled = true;
            }
        }
        #endregion
      
        #region PostButton_Click
        /***********************************************************************
        // PostButton_Click
        //
        /// <remarks>
        /// This event handler fires when the preview button is clicked.  It needs
        /// to show/hide the appropriate panels.
        /// </remarks>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ************************************************************************/
		private void PostButton_Click (Object sender, EventArgs e) 
		{
			// Only proceed if the post is valid
			//
			if (!Page.IsValid || (this.AllowPoll && IncludePoll != null && IncludePoll.Checked && PollEditor != null && !PollEditor.IsValid)) 
				return;

		    ArrayList pmReceipients = new ArrayList();
			Thread postToAdd = PreparePost(pmReceipients);
			ForumPost newPost;
			int reportedPostID = -1;

			if (PostMode == CreateEditPostMode.ReportingPost) 
			{
				reportedPostID = csContext.GetIntFromQueryString("ReportPostID",-1);
			}

			if (PostMode == CreateEditPostMode.NewPrivateMessage) 
			{
				newPost = PrivateMessages.AddPrivateMessagePost(postToAdd, user, pmReceipients);
			} 
			else 
			{
				newPost = AddPost(postToAdd, PostMode);

				if (PostMode == CreateEditPostMode.ReplyPrivateMessage)
				{
					postToAdd.IsTracked = false;

					// do we have recipients to send to?
					if (pmReceipients.Count > 0)
						PrivateMessages.AddRecipients(pmReceipients, newPost);
				}
			}

			// Redirect the user
			//
			if (newPost.IsApproved) 
			{
				switch (PostMode) 
				{
					case CreateEditPostMode.NewPost:
						Context.Response.Redirect( ForumUrls.Instance().PostInPage(newPost.PostID, newPost.PostID), true );
						break;

					case CreateEditPostMode.ReplyToPost:
						Thread thread = Threads.GetThread(newPost.ThreadID);
						int replies = thread.Replies;
						string url;
						if (replies > ForumConfiguration.Instance().PostsPerPage) 
						{
							int page;
				
							if (user.PostSortOrder == SortOrder.Descending)
								page = 1;
							else
								page = 1 + replies / ForumConfiguration.Instance().PostsPerPage;

							url = ForumUrls.Instance().PostPaged(newPost.PostID, page);
						} 
						else 
						{
							url = ForumUrls.Instance().PostInPage(newPost.PostID, newPost.PostID);
						}

						Context.Response.Redirect( url, true );
						break;

					case CreateEditPostMode.EditPost:
						Context.Response.Redirect( csContext.ReturnUrl, true );
						break;

					case CreateEditPostMode.NewPrivateMessage:
						Context.Response.Redirect( Globals.GetSiteUrls().Post(newPost.PostID), true);
						break;

					case CreateEditPostMode.ReportingPost:
						Context.Response.Redirect( ForumUrls.Instance().PostInPage(reportedPostID, reportedPostID), true);
						break;

					default:
						Context.Response.Redirect( ForumUrls.Instance().PostInPage(newPost.PostID, newPost.PostID), true);
						break;
				}
			} 
			else 
			{
				//throw new CSException(CSExceptionType.PostPendingModeration);
				Context.Response.Redirect( ForumUrls.Instance().PostPendingModeration(newPost.Forum.SectionID) );
			}   
		}

		private Thread PreparePost(ArrayList pmReceipients)
		{
            Thread postToAdd = new Thread();
            RadioButtonList postIcon;
            int reportedPostID	= -1;

            // Is this an edit?
            if (PostMode == CreateEditPostMode.EditPost)
            {
                if (postReplyingTo.PostID != postReplyingTo.ParentID)
                {
                    postToAdd.ParentID = postReplyingTo.ParentID;
                }

                postToAdd.PostLevel = postReplyingTo.PostLevel;
                postToAdd.SectionID = postReplyingTo.SectionID;
                // Get initial post's posting date 
                postToAdd.PostDate = postReplyingTo.PostDate;
				postToAdd.CopyPollDataFrom(postReplyingTo);

                // Get the current StickyDate
                Thread thread = Threads.GetThread(postReplyingTo.ThreadID);
                postToAdd.IsSticky = thread.IsSticky;
                postToAdd.StickyDate = thread.StickyDate;
            }
            else
            {
                postToAdd.SectionID = forum.SectionID;
                postToAdd.ParentID = 0;
            }

  		
             // Is the user allowed to add attachments?
            //
            if (!AllowAttachments && ServerUploadTempID != null)
                ServerUploadTempID.Value = "";

            // Get details on the post to be added
            //
            postToAdd.Username = user.Username;
            postToAdd.Subject = ((TextBox) FindControl("PostSubject")).Text;
            postToAdd.IsLocked = ((CheckBox) FindControl("IsLocked")).Checked;
            postToAdd.IsTracked = this.subscribeToThread.Checked;
            postToAdd.User = user;
            
            // Save if this post sould be seen as anonymous
            //
            if (userMayPostAsAnonymous) 
            { 
                postToAdd.IsAnonymousPost = isAnonymousPost.Checked;
            } 
            else 
            { 
                postToAdd.IsAnonymousPost = false;
            }

            // If the user making the post is ignored, the post should be too. 
            postToAdd.IsIgnoredPost = user.IsIgnored;

            // Do we have a post icon?
            //
            postIcon =  (RadioButtonList) FindControl("PostIcon");

            if (postIcon != null)
                if (postIcon.SelectedValue != "")
                    postToAdd.EmoticonID = int.Parse(postIcon.SelectedValue);

            // Set the body of the post
            //
            SetBodyContents( postToAdd );

            // Set sticky post, but only change the setting if they have permission to do stickys
            //
            if (Permissions.ValidatePermissions( forum, Permission.Sticky, user ))
                SetSticky( postToAdd );

            // Do we have edit notes?
            //
            if (PostMode == CreateEditPostMode.EditPost)
                SetEditNotes( postToAdd );

            // Check for a reporting post. If so create a link to the offending post.
            if (PostMode == CreateEditPostMode.ReportingPost) 
            {
                reportedPostID = csContext.GetIntFromQueryString("ReportPostID",-1);
                if (reportedPostID != -1) 
                {
                    ForumPost reportedPost = Posts.GetPost( reportedPostID, csContext.UserID );

                    if( reportedPost != null ) 
                    {
                        postToAdd.Body += "<br /><br />";
                        postToAdd.Body += "<br />" + string.Format(ResourceManager.GetString("Moderate_PostsToModerateDescription"), reportedPost.Section.Name);
                        postToAdd.Body += "<br />" + ResourceManager.GetString("PostFlatView_PostDate") + reportedPost.PostDate.ToString(ResourceManager.GetString("Utility_CurrentTime_dateFormat")) + " " + string.Format( ResourceManager.GetString("Utility_CurrentTime_formatGMT"), csContext.SiteSettings.TimezoneOffset.ToString() );
                        postToAdd.Body += "<br />" + ResourceManager.GetString("PostFlatView_PostSubject") + " <b>[url=\"" + ForumUrls.Instance().PostSingle(reportedPost.PostID) + "\"]" + reportedPost.Subject + "[/url]</b>";
						postToAdd.Body += "<br />" + ResourceManager.GetString("PostFlatView_ReportingAuthor") + "[url=\"" + Globals.GetSiteUrls().UserProfile(reportedPost.User.DisplayName) + "\"]" + reportedPost.User.DisplayName + "[/url]";

                        postToAdd.Body += "<hr>" + reportedPost.Body;
                    }
                }
            }

            // Attempt to get recipients
            string[] recipients = ((TextBox) FindControl("To")).Text.Split(';');

            if (recipients.Length > 0) 
            {
                pmReceipients.Clear();

                pmReceipients.Add(user);
                pmReceipients.Add(Users.GetUser(csContext.UserID,false));

                //To Issues:
                //1. We are using display name and have no lookup API
                //2. We are do not let users specify anyone, so no sense looping. 

//                foreach (string username in recipients) 
//                {
//                    try 
//                    {
//                        User u = Users.FindUserByUsername(username);
//
//                        pmReceipients.Add(u);
//                    } 
//                    catch {}
//                }
            }

            // If the post is a private message, add the 
            // users that are able to view the post
            if (PostMode == CreateEditPostMode.NewPrivateMessage) 
            {

                postToAdd.SectionID = 0;
                postToAdd.Section = Forums.GetForum(0);
                postToAdd.IsTracked = false;
            } 
            else 
            {
                // Set thread Status with forum's 
                // default set ThreadStatus value.
                //
                if (PostMode == CreateEditPostMode.NewPost && ForumConfiguration.Instance().EnableThreadStatus && forum.EnableThreadStatus)
                {
                    postToAdd.Status = forum.DefaultThreadStatusValue;
                }
            }

            if(AllowInk && enableInk.Checked)
            {
                if(PostMode == CreateEditPostMode.NewPost)
                {
                    postToAdd.InkID = CreateInk(postToAdd.SectionID);
                     
                }
                else
                {
                    if(postToAdd.HasInk)
                    {
                        InkData ink = Ink.Get(postToAdd.InkID);
                        if(ink != null)
                        {
                            ink.InkString = inkControl.InkData;
                            ink.DateUpdated = DateTime.Now;
                            Ink.Update(ink);
                        }
                        else
                        {
                            ink.InkID = CreateInk(postToAdd.SectionID);
                        }
                    }
                    else
                    {
                        postToAdd.InkID = CreateInk(postToAdd.SectionID);
                    }
                }
                
            }
            else
            {
                if(postToAdd.HasInk)
                {
                    InkData data = new InkData();
                    data.SectionID = postToAdd.SectionID;
                    data.InkID = postToAdd.InkID;
                    Ink.Delete(data);
                    postToAdd.InkID = -1;
                }
            }

			if (AllowPoll && IncludePoll != null && IncludePoll.Checked && PollEditor != null)
			{
				PollEditor.Post = postToAdd;
				PollEditor.SavePollItemsToPost();
			}
			else
				postToAdd.HasPoll = false;

			if (AllowTagging && Tags != null)
				postToAdd.Categories = Tags.SelectedTags;

			if (AllowVideo)
			{
				if (videoUrl.Text.Trim().Length > 0)
				{
					postToAdd.SetPostMedia(PostMediaType.Video, true);
					postToAdd.VideoUrl = videoUrl.Text.Trim();
					postToAdd.VideoImageUrl = videoImageUrl.Text.Trim();
					postToAdd.VideoDuration = videoDuration.Text.Trim();

					if (videoHeight != null && videoHeight.Text.Length > 0)
						postToAdd.VideoHeight = int.Parse(videoHeight.Text);

					if (videoWidth != null && videoWidth.Text.Length > 0)
						postToAdd.VideoWidth = int.Parse(videoWidth.Text);
				}
				else
					postToAdd.SetPostMedia(PostMediaType.Video, false);
			}

			return postToAdd;
        }

        private int CreateInk(int sectionID)
        {
            if(!Globals.IsNullorEmpty(inkControl.InkData))
            {
                InkData ink = new InkData();
                ink.UserID = user.UserID;
                ink.SectionID = sectionID;
                ink.InkString = inkControl.InkData;
                ink.DateUpdated = DateTime.Now;
                ink.ApplicationType = ApplicationType.Forum;
                return Ink.Add(ink);
            }
            return -1;
        }

        #endregion
        
        #region CancelButton_Click
        /***********************************************************************
        // CancelButton_Click
        //
        /// <remarks>
        /// Event raised when the user decides to cancel the post.
        /// </remarks>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ************************************************************************/
        private void CancelButton_Click (Object sender, EventArgs e) 
        {
            string redirectUrl = null;
			
            if ( csContext.PostID > 0 ) 
            {
                ForumPost post = Posts.GetPost(csContext.PostID, csContext.User.UserID);
                redirectUrl = Globals.GetSiteUrls().Post(post.PostID) + "#" + csContext.PostID;
            } 
            else 
            {
                // LN 6/24/04: Updated due to a bug reported
                // in forums.asp.net.
                if (csContext.SectionID == 0) 
                {
                    if (csContext.UserID > 0)
                        redirectUrl = Globals.GetSiteUrls().UserProfile(csContext.UserID);
                    else
                        redirectUrl = Globals.GetSiteUrls().UserPrivateMessages; 
                } 
                else 
                {
                    if( csContext.SectionID > 0)
                        redirectUrl = ForumUrls.Instance().Forum(csContext.SectionID);
                    else
                        redirectUrl = Globals.GetSiteUrls().ForumsHome;
                }
            }
			
            Page.Response.Redirect(redirectUrl);
            Page.Response.End();
        }
        #endregion

        #region PreviewButton_Click

		[AjaxMethod(IncludeControlValuesWithCallBack=true)]
		public string PreviewPost()
		{
			Thread postToAdd = PreparePost(new ArrayList());
			if (PostMode == CreateEditPostMode.NewPrivateMessage) 
			{
				postToAdd.PostDate = DateTime.Now;
				PrivateMessages.FormatPrivateMessagePost(postToAdd);
			} 
			else 
			{
				switch (PostMode) 
				{
					case CreateEditPostMode.NewPost:
						postToAdd.SectionID = csContext.SectionID;	
						postToAdd.PostDate = DateTime.Now;
						break;

					case CreateEditPostMode.ReplyPrivateMessage:
					case CreateEditPostMode.ReplyToPost:
						postToAdd.ParentID = csContext.PostID;
						postToAdd.PostDate = DateTime.Now;
						break;

					case CreateEditPostMode.EditPost:
						postToAdd.PostID = csContext.PostID;
						break;

					case CreateEditPostMode.ReportingPost:
						postToAdd.SectionID = csContext.SectionID;
						postToAdd.PostDate = DateTime.Now;
						break;
				}

				Posts.FormatPost(postToAdd);
			}

			if (postFlatPreview != null)
			{
				ArrayList posts = new ArrayList();
				if (postToAdd.ParentID > 0)
					posts.Add(Posts.GetPost(postToAdd.ParentID, csContext.User.UserID, false, false));

				posts.Add(postToAdd);

				postFlatPreview.Visible = true;
				postFlatPreview.DataSource = posts;
				postFlatPreview.DataBind();

			    StringWriter stringWriter = new StringWriter();
				HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
				postFlatPreview.RenderControl(htmlWriter);

				return stringWriter.ToString();
			}
			else
				return postToAdd.FormattedBody;		
		}

        /***********************************************************************
        // PreviewButton_Click
        //
        /// <remarks>
        /// This event handler fires when the preview button is clicked.  It needs
        /// to show/hide the appropriate panels.
        /// </remarks>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ************************************************************************/
        private void PreviewButton_Click (Object sender, EventArgs e) 
        {
            // Only do this stuff if the page is valid
            if (!Page.IsValid) 
                return;
			
            // The event was raised by a button in the user control
            // the is the UI for the form -- get the Parent, e.g. the User Control
            Control form = ((Control) sender).Parent;
            if (form == null)
                return;

            form.FindControl("EditButton").Visible = true;
            form.FindControl("PreviewButton").Visible = false;

            // Find and enable the Preview display
            form.FindControl("Preview").Visible = true;

            // Find and hide the ReplyTo display and Post
            form.FindControl("Post").Visible = false;

            // Set the title text
            if (form.FindControl("PostTitle") != null) 
            {
                if (form.FindControl("PostTitle").GetType().UnderlyingSystemType.ToString() == typeof(Label).ToString() )
                    ((Label) form.FindControl("PostTitle")).Text = "Preview Message";
                else
                    ((Literal) form.FindControl("PostTitle")).Text = "Preview Message";
            }

            // Preview the post subject
            //
            Literal previewSubject = (Literal) form.FindControl( "PreviewSubject" );
            TextBox postSubject = (TextBox) form.FindControl( "PostSubject" );            
            previewSubject.Text = Globals.HtmlEncode( postSubject.Text );

			string signature = "";
			if (PostMode == CreateEditPostMode.EditPost)
				signature = Globals.FormatSignature(postReplyingTo.User.Profile.SignatureFormatted);
			else
				signature = Globals.FormatSignature(user.Profile.SignatureFormatted);

			Thread postToAdd = PreparePost(new ArrayList());
			if (PostMode == CreateEditPostMode.NewPrivateMessage) 
			{
				PrivateMessages.FormatPrivateMessagePost(postToAdd);
			} 
			else 
			{
				switch (PostMode) 
				{
					case CreateEditPostMode.NewPost:
						postToAdd.SectionID = csContext.SectionID;	
						break;

					case CreateEditPostMode.ReplyPrivateMessage:
					case CreateEditPostMode.ReplyToPost:
						postToAdd.ParentID = csContext.PostID;
						break;

					case CreateEditPostMode.EditPost:
						postToAdd.PostID = csContext.PostID;
						break;

					case CreateEditPostMode.ReportingPost:
						postToAdd.SectionID = csContext.SectionID;
						break;
				}

				Posts.FormatPost(postToAdd);
			}


            // Preview the post body
            //
            Literal previewBody = (Literal) form.FindControl( "PreviewBody" );
            previewBody.Text = postToAdd.FormattedBody + signature;
        }
        #endregion
        
        #endregion

        #region Supporting Methods

        #region SetEditNotes
        void SetEditNotes(ForumPost p) 
        {
            string[] editItems = new string[4];
			editItems[0] = user.DisplayName;
            editItems[1] = DateTime.Now.ToString(csContext.SiteSettings.TimeFormat);
            editItems[2] = csContext.SiteSettings.TimezoneOffset.ToString();
            editItems[3] = DateTime.Now.ToString(csContext.SiteSettings.DateFormat);

            TextBox edit = (TextBox) FindControl("EditNotesBody");
            TextBox notes = (TextBox) FindControl("CurrentEditNotesBody");

			string editNotes = String.Empty;
			if (edit != null)
				editNotes += "\n" + edit.Text;

			if (notes != null)
				editNotes += "\n\n" + notes.Text;

            // TDD 3/18/2004
            // this was changed to go ahead and save the note in safe HTML format and not to do it on every
            // viewing of the post.
			p.EditNotes = Formatter.EditNotes( String.Format( csContext.Context.Server.HtmlDecode(ResourceManager.GetString("CreateEditPost_EditNotesRecord")), editItems) + editNotes );
        }
        #endregion

        #region SetBodyContents
        void SetBodyContents(ForumPost p) 
        {
            postBody = (Editor) FindControl("postBody");

            if (postBody.IsRichTextCapable) 
            {
                p.PostType = PostContentType.HTML;
                p.Body = postBody.Text;
            } 
            else 
            {
                p.PostType = PostContentType.Text;
                p.Body = postBody.Text;
            }
        }
        #endregion
        
        #region SetSticky
        void SetSticky (Thread p) 
        {
            // Are we pinning the post?
            //
            if ((pinnedPost != null) && (Convert.ToInt32(pinnedPost.SelectedItem.Value) > 0)) 
            {                
                p.IsSticky = true;

                switch (Convert.ToInt32(pinnedPost.SelectedItem.Value)) 
                {
                    case 1:
                        p.StickyDate = DateTime.Now.Date.AddDays(1);
                        break;

                    case 3:
                        p.StickyDate = DateTime.Now.Date.AddDays(3);
                        break;

                    case 7:
                        p.StickyDate = DateTime.Now.Date.AddDays(7);
                        break;

                    case 14:
                        p.StickyDate = DateTime.Now.Date.AddDays(14);
                        break;

                    case 30:
                        p.StickyDate = DateTime.Now.Date.AddMonths(1);
                        break;

                    case 90:
                        p.StickyDate = DateTime.Now.Date.AddMonths(3);
                        break;

                    case 180:
                        p.StickyDate = DateTime.Now.Date.AddMonths(6);
                        break;

                    case 366:
                        p.StickyDate = DateTime.Now.Date.AddYears(1);
                        break;

                    case 999:
                        p.StickyDate = DateTime.Now.Date.AddYears(25);
                        break;
                }
            }
            else
            {
                // Was it previously sticky?
                if (p.IsSticky)
                {
                    // Not sticky by now
                    p.IsSticky = false;
                    
                    // Make its sticky date the post's posting date because
                    // by default we order threads by sticky info descending.
                    // Thus thread's position will be given by its post date.
                    p.StickyDate = p.PostDate;
                    //p.StickyDate = DateTime.Now.AddDays(-1);
                }
            }
        }
        #endregion
        
        #region AddPost
        ForumPost AddPost(ForumPost post, CreateEditPostMode mode) 
        {
            ForumPost newPost = null;

			bool hasAttachment = false;
            Guid attachmentGuid = Guid.Empty;
			string attachmentFilename = String.Empty;
			bool attachmentIsExisting = false;
			if (ServerUploadTempID != null && ServerFilename != null && ServerUploadTempID.Value != "Existing" && !Globals.IsNullorEmpty(ServerUploadTempID.Value))
			{
				attachmentGuid = new Guid(ServerUploadTempID.Value);
				attachmentFilename =  ServerFilename.Value;
				hasAttachment = true;
				attachmentIsExisting = false;
			}
			else if (ServerUploadTempID != null && ServerUploadTempID.Value == "Existing")
			{
				hasAttachment = true;
				attachmentIsExisting = true;
			}

            switch (mode) 
            {
                case CreateEditPostMode.NewPost:
                    post.SectionID = csContext.SectionID;	
					
					if (hasAttachment)
						newPost = Posts.AddPost(post, user, attachmentGuid, attachmentFilename);
					else
						newPost = Posts.AddPost(post, user);

                    break;

                case CreateEditPostMode.ReplyPrivateMessage:
                case CreateEditPostMode.ReplyToPost:
                    post.ParentID = csContext.PostID;

					if (hasAttachment)
						newPost = Posts.AddPost(post, user, attachmentGuid, attachmentFilename);
					else
						newPost = Posts.AddPost(post, user);

                    break;

                case CreateEditPostMode.EditPost:
                    post.PostID = csContext.PostID;

					if (hasAttachment && !attachmentIsExisting)
						Posts.UpdatePost(post, attachmentGuid, attachmentFilename, user.UserID);
					else
					{
						if (!attachmentIsExisting)
							Posts.DeleteAttachment(post);

						Posts.UpdatePost(post, user.UserID);
					}
                    
					newPost = Posts.GetPost(post.PostID, user.UserID);
                    break;

                case CreateEditPostMode.ReportingPost:
                    post.SectionID = csContext.SectionID;

					if (hasAttachment)
						newPost = Posts.AddPost(post, user, attachmentGuid, attachmentFilename);
					else
						newPost = Posts.AddPost(post, user);

                    break;

            }

            return newPost;
        }
        #endregion
        
        #region AllowAttachments

        bool AllowInk
        {
            get
            {
				return csContext.SiteSettings.EnableInk && csContext.User.EnableInk && Permissions.ValidatePermissions(forum, Permission.Ink, user);
            }
        }

		bool AllowVideo
		{
			get
			{
				bool hasPermission = (Permissions.ValidatePermissions(forum, Permission.Video, user));
				bool isNewPost = (PostMode == CreateEditPostMode.NewPost);
				bool isEditThreadStarter = (PostMode == CreateEditPostMode.EditPost) && (postReplyingTo.PostLevel == 1);
				return (hasPermission && (isNewPost || isEditThreadStarter));
			}
		}

		bool AllowPoll
		{
			get
			{
				ForumPermission forumPermission = forum.ResolvePermission(user) as ForumPermission;
				bool isNewPost = (PostMode == CreateEditPostMode.NewPost);
				bool isEditThreadStarter = (PostMode == CreateEditPostMode.EditPost) && (postReplyingTo.PostLevel == 1);
				return (forumPermission.CreatePoll && (isNewPost || isEditThreadStarter));
			}
		}

        bool AllowAttachments 
        {
            get 
            {
                User user = csContext.User;
                return user.IsForumAdministrator || ForumConfiguration.Instance().EnableAttachments;
            }
        }

		bool AllowTagging
		{
			get
			{
				return ForumConfiguration.Instance().EnableTagging && 
                    PostMode != CreateEditPostMode.NewPrivateMessage && 
                    PostMode != CreateEditPostMode.ReplyPrivateMessage;
			}
		}

        #endregion

        #endregion

        #region Properies
        /// <value>
        /// Indicates whether the post being made is a new post, a reply to an existing post, or an
        /// editing of an existing post.  The allowable values are NewPost, ReplyToPost, and EditPost.
        /// </value>
        /// <remarks>When setting the Mode property to NewPost, you must supply a ForumID property.
        /// When setting the Mode to ReplyToPost or EditPost, you must supply a PostID property.</remarks>
        public CreateEditPostMode PostMode 
        {
            get 
            {
                Object state = ViewState[ "mode" ];
                if ( state != null ) 
                {
                    return (CreateEditPostMode) state;
                }
                return CreateEditPostMode.NewPost;
            }
            set { ViewState["mode"] = value; }
        }
        #endregion

        private void SearchCallBack_Callback(object sender, CA.CallBackEventArgs e)
        {
            Repeater searchRepeater = FindControl("SearchRepeater") as Repeater;
            SearchQuery query = new SearchQuery();
            query.PageIndex = 0;
            query.PageSize = 10;
            query.SortBy = SearchSort.DateDescending;
            query.QueryText = e.Parameter;
                    
            SearchResultSet searchResult = CSSearch.Search(query);
            if(searchResult.TotalRecords > 0)
            {
                searchRepeater.DataSource = searchResult.Posts;
                searchRepeater.DataBind();
                searchRepeater.RenderControl(e.Output);
            }
            else
            {
                Literal l = new Literal();
                l.Text = "Sorry, no related posts";
                l.RenderControl(e.Output);
            }
        }
    }
}
