using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace aNd1coder.Common
{
    /// <summary>
    /// Rss??
    /// </summary>
    public class RssBase
    {

        #region RssBase constructor
        public RssBase(XmlTextWriter rssWriter)
        {
            this.rssWriter = rssWriter;
        }
        public RssBase(XmlTextWriter rssWriter, bool hasMedia, IList<ItemInfo> items)
        {
            this.rssWriter = rssWriter;
            this.hasMedia = hasMedia;
            this.items = items;
        }
        #endregion

        [Serializable]
        public sealed class ItemInfo
        {

            #region ItemInfo constructor
            public ItemInfo() { }
            public ItemInfo(string itemTitle, string itemLink, string itemDescription, string itemPubDate, string itemAuthor, string itemGuid)
            {
                this.itemTitle = itemTitle;
                this.itemLink = itemLink;
                this.itemDescription = itemDescription;
                this.itemAuthor = itemAuthor;
                this.itemGuid = itemGuid;
                this.itemPubDate = itemPubDate;
            }
            public ItemInfo(string itemTitle, string itemLink, string itemDescription, string itemPubDate, string itemAuthor,
                           string itemGuid, string mediaContentUrl, string mediaTitle, string mediaDescription,
                           string mediaThumbUrl, string mediaThumbWidth, string mediaThumbHeight, string mediaAuthor)
            {
                this.itemTitle = itemTitle;
                this.itemLink = itemLink;
                this.itemDescription = itemDescription;
                this.itemPubDate = itemPubDate;
                this.itemAuthor = itemAuthor;
                this.itemGuid = itemGuid;
                this.mediaContentUrl = mediaContentUrl;
                this.mediaTitle = mediaTitle;
                this.mediaDescription = mediaDescription;
                this.mediaThumbUrl = mediaThumbUrl;
                this.mediaThumbWidth = mediaThumbWidth;
                this.mediaThumbHeight = mediaThumbHeight;
                this.mediaAuthor = mediaAuthor;
            }
            #endregion

            #region Internal item variables
            // Item variables
            private string itemTitle;
            private string itemLink;
            private string itemDescription;
            private string itemPubDate = DateTime.Now.ToString("r");
            private string itemDateTaken = DateTime.Now.ToString();
            private string itemAuthor;
            private string itemGuid;
            // Media variables
            private string mediaContentUrl;
            private string mediaTitle;
            private string mediaDescription;
            private string mediaThumbUrl;
            private string mediaThumbWidth;
            private string mediaThumbHeight;
            private string mediaAuthor;
            #endregion

            #region Item properties
            public string ItemTitle
            {
                set { itemTitle = value; }
                get { return itemTitle; }
            }
            public string ItemLink
            {
                set { itemLink = value; }
                get { return itemLink; }
            }
            public string ItemDescription
            {
                set { itemDescription = value; }
                get { return itemDescription; }
            }
            public string ItemPubDate
            {
                set { itemPubDate = value; }
                get { return itemPubDate; }
            }
            public string ItemDateTaken
            {
                set { itemDateTaken = value; }
                get { return itemDateTaken; }
            }
            public string ItemAuthor
            {
                set { itemAuthor = value; }
                get { return itemAuthor; }
            }
            public string ItemGuid
            {
                set { itemGuid = value; }
                get { return itemGuid; }
            }
            public string MediaContentUrl
            {
                set { mediaContentUrl = value; }
                get { return mediaContentUrl; }
            }
            public string MediaTitle
            {
                set { mediaTitle = value; }
                get { return mediaTitle; }
            }
            public string MediaDescription
            {
                set { mediaDescription = value; }
                get { return mediaDescription; }
            }
            public string MediaThumbUrl
            {
                set { mediaThumbUrl = value; }
                get { return mediaThumbUrl; }
            }
            public string MediaThumbWidth
            {
                set { mediaThumbWidth = value; }
                get { return mediaThumbWidth; }
            }
            public string MediaThumbHeight
            {
                set { mediaThumbHeight = value; }
                get { return mediaThumbHeight; }
            }
            public string MediaAuthor
            {
                set { mediaAuthor = value; }
                get { return mediaAuthor; }
            }
            #endregion

        }

        #region Const string
        private const string TITLE = "MyMedia RSS";
        private const string XMLNS_MEDIA = "http://www.MyWii.com.au";
        private const string XMLNS_DC = "http://purl.org/dc/elements/1.1/";
        private const string LINK = "http://www.MyWii.com.au/";
        private const string DESCRIPTION = "description";
        private const string LANGUAGE = "en-us";
        private const string COPYRIGHT = "Copyright 2006";
        private const string GENERATOR = "MyMedia RSS Generator";
        private const string IMAGE_URL = "http://www.MyWii.com.au/img/main/feed.gif";
        private const string IMAGE_TITLE = "MyWii";
        private const string IMAGE_LINK = "http://www.MyWii.com.au";
        private string PUB_DATE = DateTime.Now.ToString("r");
        private string LAST_BUILD_DATE = DateTime.Now.ToString("r");

        #endregion

        #region Internal member variables
        private XmlTextWriter rssWriter;
        private bool hasMedia;
        private IList<ItemInfo> items;
        #endregion


        #region Properties
        public XmlTextWriter RssWriter
        {
            set { rssWriter = value; }
            get { return rssWriter; }
        }
        public bool HasMedia
        {
            set { hasMedia = value; }
            get { return hasMedia; }
        }
        public IList<ItemInfo> Items
        {
            set { items = value; }
            get { return items; }
        }

        #endregion


        #region Private method

        private void WritePrologue()
        {
            rssWriter.WriteStartDocument();
            rssWriter.WriteStartElement("rss");
            rssWriter.WriteAttributeString("version", "2.0");
            rssWriter.WriteAttributeString("xmlns:media", XMLNS_MEDIA);
            rssWriter.WriteAttributeString("xmlns:dc", XMLNS_DC);
            rssWriter.WriteString("\n    ");
            // Write in channel block
            rssWriter.WriteStartElement("channel");
            rssWriter.WriteString("\n     ");
            rssWriter.WriteElementString("title", TITLE);
            rssWriter.WriteString("\n     ");
            rssWriter.WriteElementString("link", LINK);
            rssWriter.WriteString("\n     ");
            rssWriter.WriteElementString("description", DESCRIPTION);
            rssWriter.WriteString("\n     ");
            rssWriter.WriteElementString("pubDate", PUB_DATE);
            rssWriter.WriteString("\n     ");
            rssWriter.WriteElementString("lastBuildDate", LAST_BUILD_DATE);
            rssWriter.WriteString("\n     ");
            rssWriter.WriteElementString("language", LANGUAGE);
            rssWriter.WriteString("\n     ");
            rssWriter.WriteElementString("copyright", COPYRIGHT);
            rssWriter.WriteString("\n     ");
            rssWriter.WriteElementString("generator", GENERATOR);
            rssWriter.WriteString("\n     ");
            // Write in image block
            rssWriter.WriteStartElement("image");
            rssWriter.WriteString("\n        ");
            rssWriter.WriteElementString("url", IMAGE_URL);
            rssWriter.WriteString("\n        ");
            rssWriter.WriteElementString("title", IMAGE_TITLE);
            rssWriter.WriteString("\n        ");
            rssWriter.WriteElementString("link", IMAGE_LINK);
            rssWriter.WriteString("\n     ");
            rssWriter.WriteEndElement();
            rssWriter.WriteString("\n     ");
        }

        /**/
        /// <summary>
        /// Write in items
        /// </summary>
        private void WriteItem(ItemInfo item)
        {
            // Write in item block
            rssWriter.WriteStartElement("item");
            rssWriter.WriteString("\n        ");
            rssWriter.WriteElementString("title", item.ItemTitle);
            rssWriter.WriteString("\n        ");
            rssWriter.WriteElementString("link", item.ItemLink);
            rssWriter.WriteString("\n        ");

            rssWriter.WriteStartElement("description");
            rssWriter.WriteString("\n         ");
            rssWriter.WriteCData(item.ItemDescription);
            rssWriter.WriteString("\n        ");
            rssWriter.WriteEndElement();

            rssWriter.WriteString("\n        ");
            rssWriter.WriteElementString("pubDate", item.ItemPubDate);
            rssWriter.WriteString("\n        ");
            rssWriter.WriteElementString("dc:date.Taken", item.ItemDateTaken);
            rssWriter.WriteString("\n        ");
            rssWriter.WriteElementString("author", item.ItemAuthor);
            rssWriter.WriteString("\n        ");
            rssWriter.WriteStartElement("guid");
            rssWriter.WriteAttributeString("isPermaLink", "false");
            rssWriter.WriteString(item.ItemGuid);
            rssWriter.WriteEndElement();


            // Write item media here

        }

        /**/
        /// <summary>
        /// Write in item media
        /// </summary>
        /// <param name="item">ItemInfo item</param>
        private void WriteItemMedia(ItemInfo item)
        {
            // Write in media
            rssWriter.WriteString("\n        ");
            rssWriter.WriteStartElement("media:content");
            rssWriter.WriteAttributeString("url", item.MediaContentUrl);
            rssWriter.WriteAttributeString("type", "image/jpeg");
            rssWriter.WriteEndElement();
            rssWriter.WriteString("\n        ");
            rssWriter.WriteElementString("media:title", item.MediaTitle);
            rssWriter.WriteString("\n        ");
            rssWriter.WriteStartElement("media:text");
            rssWriter.WriteAttributeString("type", "html");
            rssWriter.WriteString(item.MediaDescription);
            rssWriter.WriteEndElement();
            rssWriter.WriteString("\n        ");
            rssWriter.WriteStartElement("media:thumbnail");
            rssWriter.WriteAttributeString("url", item.MediaThumbUrl);
            rssWriter.WriteAttributeString("height", item.MediaThumbHeight);
            rssWriter.WriteAttributeString("width", item.MediaThumbWidth);
            rssWriter.WriteEndElement();
            rssWriter.WriteString("\n        ");
            rssWriter.WriteStartElement("media:credit");
            rssWriter.WriteAttributeString("role", "photographer");
            rssWriter.WriteString(item.MediaAuthor);
            rssWriter.WriteEndElement();
            rssWriter.WriteString("\n     ");

        }

        /**/
        /// <summary>
        /// Close item element 
        /// </summary>
        private void WriteItemEnd()
        {
            rssWriter.WriteString("\n     ");
            rssWriter.WriteEndElement();
            rssWriter.WriteString("\n     ");
        }

        /**/
        /// <summary>
        /// Close all the elements
        /// </summary>
        private void WriteEnd()
        {
            rssWriter.WriteEndElement();
            rssWriter.WriteString("\n");
            rssWriter.WriteEndElement();
            rssWriter.WriteEndDocument();
        }
        #endregion

        /**/
        /// <summary>
        /// Write RSS feed
        /// </summary>
        public void WriteRSS()
        {
            WritePrologue();
            foreach (ItemInfo info in items)
            {
                WriteItem(info);
                if (hasMedia)
                    WriteItemMedia(info);
                WriteItemEnd();
            }
            WriteEnd();
        }
    }
}