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

using System;
using System.Collections;
using System.Text;
using System.Text.RegularExpressions;
using CommunityServer.Components;

namespace CommunityServer.Reader.Components
{
	/// <summary>
	/// Summary description for Post.
	/// </summary>
	public class FeedPost : CSCopy, IContent
	{

		#region Private Members

		private int _feedPostId;
		private int _feedId;
		private string _author;
		private string _title;
		private string _description;
		private string _source;
		private string _guidName;
		private bool _guidIsPermaLink;
		private string _link;
		private DateTime _pubDate;
		private string _commentsUrl;
		private string _enclosureUrl;
		private long _enclosureLength;
		private string _enclosureType;
		private DateTime _lastReadPostDate;
		private bool _hasRead;
		private string _creator;
		private string _commentApiUrl;
		private string _commentRssUrl;
		private int _commentCount = int.MinValue;
		private string _feedTitle;
		private string _feedLink;

		#endregion

		#region Constructor(s)

		public FeedPost()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		#endregion

		#region Properties

		public int FeedPostId
		{
			get { return _feedPostId; }
			set { _feedPostId = value; }
		}

		public int FeedId
		{
			get { return _feedId; }
			set { _feedId = value; }
		}

		public string Author
		{
			get { return _author; }
			set { _author = value; }
		}

		public string Title
		{
			get { return _title; }	
			set { _title = value; }
		}

		public string Description
		{
			get { return _description; }
			set { _description = value; }
		}

		public string Source
		{
			get { return _source; }
			set { _source = value; }
		}

		public string GuidName
		{
			get { return _guidName; }
			set { _guidName = value; }
		}

		public bool GuidIsPermaLink
		{
			get { return _guidIsPermaLink; }
			set { _guidIsPermaLink = value; }
		}

		public string Link
		{
			get { return _link; }	
			set { _link = value; }
		}

		public DateTime PubDate
		{
			get { return _pubDate; }	
			set { _pubDate = value; }
		}

		public string CommentsUrl
		{
			get { return _commentsUrl; }	
			set { _commentsUrl = value; }
		}

		public string EnclosureUrl
		{
			get { return _enclosureUrl; }
			set { _enclosureUrl = value; }
		}

		public long EnclosureLength
		{
			get { return _enclosureLength; }
			set { _enclosureLength = value; }
		}

		public string EnclosureType
		{
			get { return _enclosureType; }
			set { _enclosureType = value; }
		}

		public DateTime LastReadPostDate
		{
			get { return _lastReadPostDate; }
			set { _lastReadPostDate = value; }
		}

		public bool HasRead
		{
			get { return _hasRead; }	
			set { _hasRead = value; }
		}

		public string Creator
		{
			get { return _creator; }
			set { _creator = value; }
		}

		public string CommentApiUrl
		{
			get { return _commentApiUrl; }
			set { _commentApiUrl = value; }
		}

		public string CommentRssUrl
		{
			get { return _commentRssUrl; }
			set { _commentRssUrl = value; }
		}

		public int CommentCount
		{
			get { return _commentCount; }
			set { _commentCount = value; }
		}

		public string FeedTitle
		{
			get { return _feedTitle; }
			set { _feedTitle = value; }
		}

		public string FeedLink
		{
			get { return _feedLink; }
			set { _feedLink = value; }
		}

		#endregion

        #region IContent Members

        string IContent.Body
        {
            get
            {
                return this.Description;
            }
            set
            {
                this.Description = value;
            }
        }

        private string _formattedbody = null;
        string IContent.FormattedBody
        {
            get
            {
				if(_formattedbody == null)
				{
					Uri u = new Uri(this.Link);
					_formattedbody =  FixupHrefs(this.Description, u.GetLeftPart(UriPartial.Authority));
				}

				return _formattedbody;
            }
            set
            {
                _formattedbody = value;
            }
        }

		static Regex rHref = new Regex("\\s*(href|src)\\s*=\\s*(?:\"(?<1>[^\"]*)\"|(?<1>\\S+))", RegexOptions.IgnoreCase|RegexOptions.Compiled);

		/// <summary>
		/// fixup all relative URL's to absolute URL's
		/// (relative to this site is wrong when viewing blog posts from other sites!)
		/// </summary>
		/// <returns></returns>
		public static string FixupHrefs(string sData, string url)
		{
			MatchCollection mcHref = rHref.Matches(sData);
			StringBuilder sb = new StringBuilder(sData);
		
			// walk backwards through the matches so we
			// can use all the indexes even after modifying the string
			for (int i=mcHref.Count; i>0; i--)
			{
				// get info about the href
				Match mHref = mcHref[i-1];

				string sTest = sb.ToString().Substring(mHref.Index, mHref.Length);

				// sTest is in the form of ref|src="url
				if (sTest.IndexOf("http:") == -1 && sTest.IndexOf("https:") == -1)
					sb.Insert(mHref.Index+sTest.IndexOfAny(new char[]{'"', '\''})+1, url);
			}

			return sb.ToString();
		}

        string IContent.RenderedBody(CommunityServer.Components.PostTarget target)
        {
            IContent fp = this.Copy() as IContent;
            CSEvents.PreRenderPost(fp,ApplicationType.FeedReader,target);
            return fp.FormattedBody;
        }

        #endregion

        #region CSCopy

        public override object Copy()
        {
            FeedPost fp = base.Copy() as FeedPost;
            if(fp != null)
            {
                fp.Author = this.Author;
                fp.CommentApiUrl = this.CommentApiUrl;
                fp.CommentCount = this.CommentCount;
                fp.CommentRssUrl = this.CommentRssUrl;
                fp.CommentsUrl = this.CommentsUrl;
                fp.Creator = this.Creator;
                fp.Description = this.Description;
                fp.EnclosureLength = this.EnclosureLength;
                fp.EnclosureType = this.EnclosureType;
                fp.EnclosureUrl = this.EnclosureUrl;
                fp.FeedId = this.FeedId;
                fp.FeedLink = this.FeedLink;
                fp.FeedPostId = this.FeedPostId;
                fp.FeedTitle = this.FeedTitle;
                fp.GuidIsPermaLink = this.GuidIsPermaLink;
                fp.GuidName = this.GuidName;
                fp.HasRead = this.HasRead;
                fp.LastReadPostDate = this.LastReadPostDate;
                fp.Link = this.Link;
                fp.PubDate = this.PubDate;
                fp.Source = this.Source;
                fp.Title = this.Title;
                
            }

            return fp;
        }

        #endregion
    }

    public class FeedPostSet : IEnumerable
    {
        private ArrayList _posts = new ArrayList();
        private int _totalRecords = 0;

        public int TotalRecords
        {
            get{return _totalRecords;}
            set{_totalRecords = value;}
        }

        public void Add(FeedPost post)
        {
            _posts.Add(post);
        }

        public int Count
        {
            get{ return _posts.Count;}   
        }
        #region IEnumerable Members

        public IEnumerator GetEnumerator()
        {
            return _posts.GetEnumerator();
        }

        public FeedPost this[int i]
        {
            get
            {
                return _posts[i] as FeedPost;
            }
        }

        #endregion
    }

    public class FeedPosts
    {
        public static FeedPostSet GetRollerPosts(int pageIndex, int pageSize)
        {
            int userId = Users.GetAnonymousUser().UserID;

            string key = string.Format("RP:{0}:{1}:{2}",userId, pageSize,pageIndex);


            FeedPostSet posts = CSCache.Get(key) as FeedPostSet;
            if(posts == null)
            {
                posts =  FeedReaderDataProvider.Instance().GetRollerPosts(userId,pageIndex,pageSize);
                if(pageIndex == 0)
                    CSCache.Insert(key,posts,CSCache.MinuteFactor * 10);
                else
                    CSCache.Insert(key,posts,CSCache.MinuteFactor * 3);
            }

            return posts;
        }
    }

}
