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

using System;

using CommunityServer.Components;

namespace CommunityServer.Blogs.Components
{
    /// <summary>
    /// Core Weblog content object. Extends Post
    /// </summary>
    [Serializable]
	public class WeblogPost : Post
    {
        public WeblogPost()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        public Weblog Weblog
        {
            get{ return Section as Weblog;}
        }

		#region Tracking
		public bool UserIsTracked
		{
			get
			{
				return GetIsTracked(CSContext.Current.User.UserID);
			}
		}

		public bool GetIsTracked(int userID)
		{
			return ThreadTracking.IsTracked(this.ThreadID,userID);
		}
		#endregion

        #region private
        
        private string[] categories;
    	private int authorID;
		private int aggViews;
        #endregion

        #region Public

		/// <summary>
		/// Used to bind the Title URL or user profile link to the CA datagrid
		/// </summary>
		public string AuthorUrl
		{
			get
			{
				if(this.HasTitleUrl)
					return this.TitleUrl;
				else
					return SiteUrls.Instance().UserProfile(this.Username); 
			}
		}
 		
        /// <summary>
        /// Url to use instead of default title link
        /// </summary>
        public string TitleUrl
        {
            get{return this.GetExtendedAttribute("TitleUrl");}
            set{this.SetExtendedAttribute("TitleUrl",value);}
        }

		/// <summary>
        /// Used to define a post as a RollerBlogPost
        /// </summary>
        [Obsolete("Replaced by IsExternal which is queryable")]
        public bool IsRollerBlogPost
        {
			get{ return GetBool("RollerBlogPost", false); }
			set{ this.SetExtendedAttribute("RollerBlogPost",value.ToString()); }
        }

		/// <summary>
		/// Used to bind the view link to the CA datagrid
		/// </summary>
		public string ViewPostURL
		{
			get
			{
				if (this.BlogPostType == BlogPostType.Post || this.BlogPostType == BlogPostType.Article)
					return BlogUrls.Instance().Post(this, this.Weblog);
				else
					return BlogUrls.Instance().ShortLink(this.ParentID);
			}
		}
		
		/// <summary>
        /// Name of site making the trackback
        /// </summary>
        public string TrackBackName
        {
            get{return this.GetExtendedAttribute("trackbackName");}
            set{this.SetExtendedAttribute("trackbackName",value);}
        }

		public string Custom
		{
			get{return GetString("Custom",null);}
			set{this.SetExtendedAttribute("Custom",value);}
		}

		/// <summary>
		/// Name submitted when the post was saved
		/// </summary>
		public string SubmittedUserName
		{
			get{return GetString("SubmittedUserName",null);}
			set{this.SetExtendedAttribute("SubmittedUserName",value);}
		}

		/// <summary>
		/// When the post was saved, did the user submit a different name
		/// </summary>
		public bool HasSubmittedUserName
		{
			get{ return !Globals.IsNullorEmpty(this.SubmittedUserName);}
		}

		public string DisplayName
		{
			get 
			{
				if (this.BlogPostType == BlogPostType.Trackback)
					return !Globals.IsNullorEmpty(TrackBackName) ? TrackBackName : "TrackBack";
				
				if (this.User == null)
					this.User = Users.GetUser(this.UserID, this.Username, false, true);

				if (this.User != null && this.User.IsAnonymous && HasSubmittedUserName)
					return this.SubmittedUserName;
				else if (this.User != null)
					return this.User.DisplayName;
				else
					return this.Username;
			}
		}


        /// <summary>
        /// Is this post aggregated
        /// </summary>
        public bool IsAggregated
        {
            get{return GetPostConfig(BlogPostConfig.IsAggregated);}
            set{SetPostConfig(BlogPostConfig.IsAggregated, value);}
        }

        /// <summary>
        /// Is this post from an external resource?
        /// </summary>
        public bool IsExternal
        {
            get{return GetPostConfig(BlogPostConfig.IsExternal);}
            set{SetPostConfig(BlogPostConfig.IsExternal, value);}
        }


        /// <summary>
        /// Always display the excerpt?
        /// </summary>
        public bool DisplayExcerpt
        {
            get{return GetPostConfig(BlogPostConfig.DisplayExcerpt);}
            set{SetPostConfig(BlogPostConfig.DisplayExcerpt, value);}
        }
        

        /// <summary>
        /// Is this post aggregated to the community root site
        /// </summary>
        public bool IsCommunityAggregated
        {
            get{return GetPostConfig(BlogPostConfig.IsCommunityAggregated);}
            set{SetPostConfig(BlogPostConfig.IsCommunityAggregated, value);}
        }

        /// <summary>
        /// Should this post syndicated the excerpt only?
        /// </summary>
        public bool SyndicateExcerpt
        {
            get{return GetPostConfig(BlogPostConfig.SyndicateExcerpt);}
            set{SetPostConfig(BlogPostConfig.SyndicateExcerpt, value);}
        }

		public CommentModerationType ModerationType
		{
			get
			{
				if(GetPostConfig((BlogPostConfig)16))
					return CommentModerationType.All;

				return (CommentModerationType)Enum.Parse(typeof(CommentModerationType),GetString("CommentModerationType","None"),false);
			}
			set
			{
				SetExtendedAttribute("CommentModerationType",value.ToString());
			}
		}

		internal bool EverTracked
		{
			get{return GetBool("EverPublished",false);}
			set{ SetExtendedAttribute("EverPublished",value.ToString());}
		}

		/// <summary>
		/// returns true if the Post is approved and th PostDate is less than the current datetime
		/// </summary>
		public bool IsPostEnabled
		{
			get
			{
				return IsApproved && (this.PostDate <= DateTime.Now);
			}
		}


		//Need a better pattern here!

		/// <summary>
		/// This value is not persisted! The first time a Weblog Post is saved and EverTracked is set to true, this value
		/// will be true. CSModule subscribers can use this property to determine if one time notifications should be made.
		/// 
		/// </summary>
		internal bool EnableExternalNotificatons;

		public bool EnableRatings
		{
			get{return GetBool("EnableRatings",true);}
			set{ SetExtendedAttribute("EnableRatings",value.ToString());}
		}

		public bool EnableTrackBacks
		{
			get{return GetBool("EnableTrackBacks",true);}
			set{ SetExtendedAttribute("EnableTrackBacks",value.ToString());}
		}

		public bool EnableXmlRpcPings
		{
			get{return GetBool("EnableXmlRpcPings",true);}
			set{ SetExtendedAttribute("EnableXmlRpcPings",value.ToString());}
		}

        public int ExcerptSize
        {
            get{return GetInt("ExcerptSize",250);}
            set{ SetExtendedAttribute("ExcerptSize",value.ToString());}
        }

        /// <summary>
        /// Summary of the blog feedback. Not used as an API
        /// </summary>
        public BlogPostConfig PostConfig
        {
            get{return (BlogPostConfig)PostConfigurationValue;}
            set{PostConfigurationValue = (int)value;}
        }

        /// <summary>
        /// list of categories this post was made to
        /// </summary>
        public string[] Categories
        {
            get{return categories;}
            set{categories = value;}
        }

        /// <summary>
        /// Specific type of blog post (Post, Article, Comment, Trackback)
        /// </summary>
        public BlogPostType BlogPostType
        {
            get{return (BlogPostType)ApplicationPostTypeValue;}
            set{ApplicationPostTypeValue = (int)value;}
        }

		/// <summary>
		/// Localized string version of BlogPostType used in Control Panel
		/// </summary>
		public string BlogPostTypeName
		{
			get 
			{
				switch (BlogPostType)
				{
					case BlogPostType.Post:
						return ResourceManager.GetString("Weblog_Terms_Post");
					case BlogPostType.Article:
						return ResourceManager.GetString("Weblog_Terms_Article");
					case BlogPostType.Comment:
						return ResourceManager.GetString("Weblog_Terms_Comment");
					case BlogPostType.Trackback:
						return ResourceManager.GetString("Weblog_Terms_Trackback");
					default:
						return BlogPostType.ToString();					
				}
			}
		}

		/// <summary>
		/// The UserID of the person who wrote the post
		/// </summary>
		public int AuthorID
		{
			get { return authorID; }
			set { authorID = value; }
		}

		/// <summary>
		/// The number of aggregate views
		/// </summary>
		public int AggViews
		{
			get { return aggViews; }
			set { aggViews = value; }
		}

		/// <summary>
		/// The type of feedback the owner should receive notification for. Overrides the Weblog value.
		/// </summary>
		public FeedbackNotificationType FeedbackNotificationType
		{
			get{ return (FeedbackNotificationType)GetInt("feedbackNotificationType", (int)this.Weblog.FeedbackNotificationType); }
			set{ this.SetExtendedAttribute("feedbackNotificationType",((int)value).ToString()); }
		}

		public bool EnableAllOwnerNotification
		{
			get{ return GetBool("enableAllOwnerNotification", false); }
			set{ SetExtendedAttribute("enableAllOwnerNotification", value.ToString()); }

		}

		/// <summary>
		/// Returns true if the BlogPostType is a feedback item
		/// </summary>
		public bool IsFeedback
		{
			get{
				if (this.BlogPostType == BlogPostType.Post  || this.BlogPostType == BlogPostType.Article)
					return false;
				else
					return true;
			}
		}

		/// <summary>
		/// Should this post be cross-posted to other blogs using the Cross Posting settings for the parent blog
		/// </summary>
		public bool EnableCrossPosting
		{
			get{ return GetBool("enableCrossPosting", false); }
			set{ this.SetExtendedAttribute("enableCrossPosting",value.ToString()); }
		}

        #endregion

        #region Public Helpers

        public DateTime CurrentUserTime
        {
            get {return CommunityServer.Components.UserTime.ConvertToUserTime(this.PostDate,CSContext.Current.User.Profile.Timezone);}
        }

        /// <summary>
        /// Does this post have a title url
        /// </summary>
        public bool HasTitleUrl
        {
            get{return (TitleUrl != null && TitleUrl.Length > 0);}
        }

        /// <summary>
        /// Does this post of have name
        /// </summary>
        public bool HasName
        {
            get{return (Name != null && Name.Length > 0);}
        }

 
        /// <summary>
        /// Does this post have categories
        /// </summary>
        public bool HasCategories
        {
            get{return (Categories != null && Categories.Length > 0);}
        }

		/// <summary>
		/// Returns true if ths post is from the blog owner
		/// </summary>
		public bool IsOwner
		{
			get
			{
				if (!Globals.IsNullorEmpty(this.Username) && this.Section != null && this.Section.OwnerArray != null)
				{
					for (int i = 0; i < this.Section.OwnerArray.Length; i++)
					{
						if (string.Compare(this.Section.OwnerArray[i], this.Username, true) == 0)
							return true;
					}
				}

				return false;
			}
		}

        #endregion

        #region Private Helpers

        /// <summary>
        /// Helper to set the PostConfig value
        /// </summary>
        /// <param name="bpc"></param>
        /// <param name="isSelected"></param>
        protected void SetPostConfig(BlogPostConfig bpc, bool isSelected)
        {
            PostConfig = PostConfigHelper.SetPostConfig(PostConfig,bpc,isSelected);
        }

        /// <summary>
        /// Helper to get the current post config value
        /// </summary>
        /// <param name="bpc"></param>
        /// <returns></returns>
        protected bool GetPostConfig(BlogPostConfig bpc)
        {
            return PostConfigHelper.IsPostConfigSelected(PostConfig,bpc);
        }



        #endregion

        #region Section
        private Section section = null; 

        /// <summary>
        /// Override Section. Returns the partent "Weblog/Section" for this post
        /// </summary>
        public override Section Section
        {
            get
            {
                if(section == null)
                {
                    section = Weblogs.GetWeblog(this.SectionID,true);
                }
                return section;
            }
            set
            {
                section = value;
            }
        }

        #endregion


	}


}
