using System.Net;
using System.IO;
using System.Xml;
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;

namespace ExWeb
{
    public partial class Mod_Picasa : System.Web.UI.UserControl
    {
        public static string Help_Description =
            "Anzeige eines PicasaAlbums"
            + "\r\n\r\nDarstellungvorschrift in externer xsl-Datei Mod_Picasa.xsl. "
            + "Diese xsl-Datei muss nur geändert werden, wenn man das Aussehen der aneinander-gereihten Bildern verändern möchte."
            + "Benötigte Parameter sind: entweder <tt>rss</tt>, die Adresse des RSS-Feeds oder <tt>user[,album[,photo]]</tt>"
            + "\r\n\r\nAlle Attribute können auch als Kommandozeilenparameter übergeben werden."
            + "\r\nDaher kann das Modul auch in der Form <tt>http://exweb.clubcomputer.at?<parameter></tt> im Rahmen eines iFrame angewendet werden."
            + "Siehe Beispiel <tt>picasa_iframe.aspx</tt>."
            ;

        public static string[][] Help_Attributes = new string[][]
        {
            // Attribut, Wert, DefaultWert, Optional, Hilfe
            new string[] {"Type", "tree code content", "content","opt","Was wird dargestellt","Type=\"tree\""},
            new string[] {"Rss","string","","","RSS-Link auf der Picasa-Seite","Rss=\"https://picasaweb.google.com/data/feed/base/user/107011206873118411907?alt=rss&kind=album&hl=de&imgmax=1600\""},
            new string[] {"User","string","","","Google+-User","user=\"rapidfranz\""},
            new string[] {"Album","string","","opt","Picasa-Album","album=...\"1\""},
            new string[] {"Photo","string","","opt","Picasa-Photo","photo=...\"1\""},
            new string[] {"Fil", "file", "","opt","Name der Style-Sheet-Datei","Fil=\"datei.html\""},
            new string[] {"Pat","path", "/","opt","Pfad der Style-Sheet-Datei","Pat=\"/meinedokumente\""},
            new string[] {"Text", "string", "","opt","Code der Style-Sheet-Datei","Text=\"<p>Das ist darzustellen</p>\""},
            new string[] {"Expand","0 1","0","opt","TreeView aufklappen oder zuklappen (nur mode=xmltree","expand=\"1\""},
            new string[] {"Title","0 1","1","opt","Titel zeigen (gallery,album,photo)","title=\"0\""},
            new string[] {"Image","0 1","1","opt","Bild(er) zeigen (gallery,album,photo)","image=\"0\""},
        };
        enum DISPLAY_TYPE { TREE, CODE, CONTENT };
        DISPLAY_TYPE _type = DISPLAY_TYPE.CONTENT;
        public string type
        {
            get
            {
                switch (_type)
                {
                    default:
                    case DISPLAY_TYPE.TREE:
                        return "tree";
                    case DISPLAY_TYPE.CODE:
                        return "code";
                    case DISPLAY_TYPE.CONTENT:
                        return "content";
                }
            }
            set
            {
                switch (value.ToLower())
                {
                    case "tree":
                        _type = DISPLAY_TYPE.TREE;
                        break;
                    case "code":
                        _type = DISPLAY_TYPE.CODE;
                        break;
                    case "content":
                        _type = DISPLAY_TYPE.CONTENT;
                        break;
                }
            }
        }
        protected string _rss = "";
        public string rss
        {
            set
            {
                _rss = value;
            }
        }
        protected string _user = ""; // "103374753388611853315"; // RapidFranz
        public string user
        {
            set
            {
                _user = value;
            }
        }
        protected string _album = ""; // "5880925084114572097"; // Admira-Rapid
        public string album
        {
            set
            {
                _album = value;
            }
        }
        protected string _photo = ""; // "5880925098672261842"; // Admira-Rapid erstes Foto
        public string photo
        {
            set
            {
                _photo = value;
            }
        }
        string _Fil = "";
        public string Fil
        {
            set
            {
                _Fil = value;
            }
        }
        string _Pat = "/";
        public string Pat
        {
            set
            {
                if (!value.EndsWith("/")) value += "/";
                _Pat = value;
            }
        }
        string _Text = "";
        public string Text
        {
            set
            {
                _Text = value;
            }
        }
        bool _Expand = false;
        public string Expand
        {
            set
            {
                _Expand = (value == "1");
            }
        }
        bool _Feed = true;
        public string Feed
        {
            set
            {
                _Feed = (value == "1");
            }
        }
        bool _Title = true;
        public string Title
        {
            set
            {
                _Title = (value == "1");
            }
        }
        bool _Image = true;
        public string Image
        {
            set
            {
                _Image = (value == "1");
            }
        }
        bool _Name = false;
        public string Name
        {
            set
            {
                _Name = (value == "1");
            }
        }
        bool _large = false;
        public string large
        {
            set
            {
                _large = (value == "1");
            }
        }
        string _Target = "_self";
        public string Target
        {
            set
            {
                _Target = value;
            }
        }
        string _patg = ".*";
        public string patg
        {
            set
            {
                _patg = value;
            }
        }
        string GetQS(string Name)
        {
            string Value = Request.QueryString[Name];
            if (Value == null) Value = "";
            return Value;
        }
        void SetValue(ref string Name, string Value)
        {
            if (Value != "") Name = Value;
        }
        void SetValue(ref bool Name, string Value)
        {
            if (Value != "") Name = (Value == "1");
        }
        string RequestRSS = "https://picasaweb.google.com/data/";
        string RequestRSSback = "https://picasaweb.google.com/data/";
        enum ALBUM_TYPE { GALLERY, ALBUM, PHOTO, PHOTO_L };
        ALBUM_TYPE display_type = ALBUM_TYPE.GALLERY;

        string GetQSParameter(string QS, string name)
        {
            string Value = "";
            string ToSearch = "/" + name + "/";
            int NamePosition = QS.IndexOf(ToSearch);
            if (NamePosition > 0)
            {
                int LengthOfName = ToSearch.Length;
                int PositionOfNestSlash = QS.IndexOf("/", NamePosition + LengthOfName);
                int Start = NamePosition + ToSearch.Length;
                int Length = PositionOfNestSlash - NamePosition - LengthOfName;
                Value = QS.Substring(Start, Length);
            }
            return Value;
        }
        void Page_Init(object sender, EventArgs e)
        {
            type = GetQS("type");
            SetValue(ref _Expand, GetQS("expand"));
            SetValue(ref _Title, GetQS("title"));
            SetValue(ref _Image, GetQS("image"));
            SetValue(ref _Name, GetQS("name"));
            SetValue(ref _Target, GetQS("target"));
            SetValue(ref _patg, GetQS("patg"));
            SetValue(ref _large, GetQS("large"));
            string rssURL = GetQS("rss");
            if (rssURL != "")
            {
                _rss = rssURL;
            }
            if (_rss == "")
            {
                SetValue(ref _user, GetQS("user"));
                SetValue(ref _album, GetQS("album"));
                SetValue(ref _photo, GetQS("photo"));
            }
            else
            {
                // analysiere rss-Feed
                _rss = _rss.ToLower();
                if (_rss.Contains("?"))
                    _rss = _rss.Substring(0, _rss.IndexOf('?'));
                if (!_rss.EndsWith("/")) _rss = _rss + "/";
                _rss = _rss.Substring(_rss.IndexOf('/', 8)); // skip "http://" or "https://"
                string strUser = GetQSParameter(_rss, "user");
                if (strUser != "")
                {
                    _user = strUser;
                    _album = GetQSParameter(_rss, "albumid");
                    _photo = GetQSParameter(_rss, "photoid");
                }
            }
            if (_user == "")
            {
                return;
            }
            else
            {
                RequestRSS += (_Feed ? "feed" : "entry") + "/base";
                RequestRSSback += (_Feed ? "feed" : "entry") + "/base";
                RequestRSS += "/user/" + _user;
                if (_album == "")
                {
                    RequestRSS += "?alt=rss&kind=album&hl=de&access=public&imgmax=1600";
                    RequestRSSback = "";
                    display_type = ALBUM_TYPE.GALLERY;
                }
                else
                {
                    RequestRSS += "/albumid/" + _album;
                    RequestRSSback += "/user/" + _user;
                    if (_photo == "")
                    {
                        RequestRSS += "?alt=rss&kind=photo&hl=de";
                        RequestRSSback += "?alt=rss&kind=album&hl=de&access=public&imgmax=1600";
                        display_type = ALBUM_TYPE.ALBUM;
                    }
                    else
                    {
                        /*
                        if (_large)
                        {
                            RequestRSS += "/photoid/" + _photo + "?alt=rss&hl=de";
                        }
                        else
                        {
                            RequestRSS += "?alt=rss&kind=photo&hl=de";
                        }
                         * */
                        RequestRSS += "?alt=rss&kind=photo&hl=de";
                        RequestRSSback += "/albumid/" + _album;
                        RequestRSSback += "?alt=rss&kind=photo&hl=de";
                        
                        display_type = (_large ?  ALBUM_TYPE.PHOTO_L : ALBUM_TYPE.PHOTO);
                    }
                }
            }
        }
        void Page_Load(object sender, EventArgs e)
        {
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            try
            {
                request = (HttpWebRequest)WebRequest.Create(RequestRSS);
                response = (HttpWebResponse)request.GetResponse();
            }
            catch
            {
                return;
            }
            StreamReader reader = new StreamReader(response.GetResponseStream());

            this.Controls.Clear();
            string Xml = reader.ReadToEnd();
            Xml = XmlInsert(Xml); // insert cotrols for use in xsl file
            switch (_type)
            {
                case DISPLAY_TYPE.TREE:
                    {
                        XmlDocument myXmlDocument = new XmlDocument();
                        myXmlDocument.Load(Mod.GenerateStreamFromString(Xml));
                        Mod_Xsl2TreeView transform = new Mod_Xsl2TreeView(myXmlDocument);
                        this.Controls.Clear();
                        TreeView tv = transform.tv;
                        if (_Expand)
                        {
                            tv.ExpandAll();
                        }
                        else
                        {
                            tv.CollapseAll();
                        }
                        this.Controls.Add(tv);
                    }
                    break;
                case DISPLAY_TYPE.CODE:
                    {
                        string output = Mod.XmlIndent(Xml);

                        // display
                        Mod_Inline mi = (Mod_Inline)LoadControl("~/Mod/Mod_Inline.ascx");
                        mi.Mode = "high";
                        mi.Width = "640";
                        mi.Text = output;
                        mi.Extension = "xml";
                        this.Controls.Add(mi);

                        // funktioniert leider nicht wegen Page.LoadComplete()
                        // Mod_Picasa_Code.Text = output;
                        // Mod_Picasa_Code.Page_Load(null, null);
                    }
                    break;
                case DISPLAY_TYPE.CONTENT:
                    {
                        string XslCode = GetXslCode();
                        string XslFile = "";
                        switch (display_type)
                        {
                            case ALBUM_TYPE.GALLERY:
                                XslFile = (_Feed ? "~/mod/Mod_Picasa_Gallery.xsl" : "~/mod/Mod_Picasa_Gallery_Entry.xsl");
                                break;
                            case ALBUM_TYPE.ALBUM:
                                XslFile = (_Feed ? "~/mod/Mod_Picasa_Album.xsl" : "~/mod/Mod_Picasa_Album_Entry.xsl");
                                break;
                            case ALBUM_TYPE.PHOTO:
                                XslFile = (_Feed ? "~/mod/Mod_Picasa_Photo.xsl" : "~/mod/Mod_Picasa_Photo_Entry.xsl");
                                break;
                        }
                        /*
                        if (XslCode == "") XslCode = File.ReadAllText(Server.MapPath(XslFile));
                        string output = Mod.XmlXslTransform(Xml, XslCode);
                        Controls.Add(new LiteralControl(output));
                         */
                        string output = "";
                        System.Xml.XmlDocument rssDoc = new System.Xml.XmlDocument();
                        rssDoc.Load(Mod.GenerateStreamFromString(Xml));
                        System.Xml.XmlNode title = rssDoc.SelectSingleNode("/rss/channel/title");
                        System.Xml.XmlNode link = rssDoc.SelectSingleNode("/rss/channel/link");
                        
                        // output += RequestRSSback == "" ? "" : getLink("<<", "/picasa.aspx?rss=" + RequestRSSback, "") + " ";
                        // output += getLink(getPic("/images/picasa.jpg"), link.InnerText, "_blank");
                        // output += title.InnerText + "<br/>";

                        XmlNamespaceManager nsmgr = new XmlNamespaceManager(rssDoc.NameTable);
                        nsmgr.AddNamespace("media", "http://search.yahoo.com/mrss/");
                        System.Xml.XmlNodeList Images = rssDoc.SelectNodes("/rss/channel/item");
                        for (int i = 0; i < Images.Count; i++)
                        {
                            output += InsertPicture(display_type, Images.Item(i), nsmgr);
                        }
                        Controls.Add(new LiteralControl(output));
                    }
                    break;
            }
        }
        string InsertPicture(ALBUM_TYPE display_type, System.Xml.XmlNode Image, XmlNamespaceManager nsmgr)
        {
            string Output = "";
            switch (display_type)
            {
                case ALBUM_TYPE.PHOTO:
                case ALBUM_TYPE.PHOTO_L:
                    System.Xml.XmlNode link_image = Image.SelectSingleNode("link");
                    if (!link_image.InnerText.EndsWith(_photo))
                    {
                        return Output;
                    }
                    break;
            }
            string title = Image.SelectSingleNode("title").InnerText;
            if (display_type == ALBUM_TYPE.GALLERY)
            {
                Match m = Regex.Match(title, _patg);
                if (!(m.Captures.Count>0))
                    return Output;
            }
            System.Xml.XmlNode guid = Image.SelectSingleNode("guid");
            // Output += getLink(title, "/Picasa.aspx?rss=" + guid.InnerText, "") + "<br/>";
            System.Xml.XmlNode thumb = null;
            switch (display_type)
            {
                case ALBUM_TYPE.PHOTO_L:
                    thumb = Image.SelectSingleNode("media:group/media:content", nsmgr);
                    break;
                case ALBUM_TYPE.PHOTO:
                case ALBUM_TYPE.ALBUM:
                    thumb = Image.SelectSingleNode("media:group/media:thumbnail[2]", nsmgr);
                    break;
                case ALBUM_TYPE.GALLERY:
                    thumb = Image.SelectSingleNode("media:group/media:thumbnail", nsmgr);
                    break;
            }
            // text-align:center;vertical-align:middle;
            Output += 
                getLink
                (
                    getPic
                    (
                        thumb.Attributes["url"].InnerText, 
                        title, 
                        thumb.Attributes["width"].InnerText, 
                        thumb.Attributes["height"].InnerText,
                        display_type
                    ), 
                    "/picasa.aspx?"+(display_type == ALBUM_TYPE.PHOTO?"large=1&":"")+"rss=" + guid.InnerText, 
                    ""
                );
            Output = 
                "<div style='margin:10px 10px 0px 0px;padding:5px;border:1px solid lightgray;float:left;overflow:hidden;'>" 
                + Output 
                + "</div>";
            return Output;
        }
        string getPic(string Src)
        {
            return
                "<img src='" + Src + "' />";
        }
        string getPic(string Src, string title, string s_width, string s_height, ALBUM_TYPE display_type)
        {
            int picwidth=120;

            switch (display_type)
            {
                case ALBUM_TYPE.PHOTO_L:
                    return
                        "<table><tr><td><img src='" + Src + "' title='" + title + "' /></td></tr></table>";
            }
            int width = int.Parse(s_width);
            int height = int.Parse(s_height);
            double faktor;
            if (width > height) // Querformat
            {
                faktor = (picwidth * 1.0) / width;
            }
            else
            {
                faktor = (picwidth * 1.0) / height;
            }
            width = (int)(width * faktor);
            height = (int)(height * faktor);
            switch (display_type)
            {
                case ALBUM_TYPE.PHOTO:
                    return
                        "<table><tr><td " + (width > height ? "width='" + picwidth + "' " : "height='" + picwidth + "' ") + " align='center' valign='middle'><img src='" + Src + "' title='" + title + "' width='" + width + "' height='" + height + "' style='vertical-align:middle;' /></td></tr></table>";
                default:
                    return
                        "<table><tr><td width='" + picwidth + "' height='" + picwidth + "' align='center' valign='middle'><img src='" + Src + "' title='" + title + "' width='" + width + "' height='" + height + "' style='vertical-align:middle;' /></td></tr></table>";
            }
        }
        string getLink(string Text, string Href, string Target)
        {
            return
                "<a"
                + " href='" + Href + "'"
                + (Target == "" ? "" : " target='" + Target + "'")
                + ">" + Text + "</a>";
        }
        XmlElement getXmlElement(XmlDocument xml, string name, string value)
        {
            XmlElement elem = xml.CreateElement(name);
            elem.InnerText = value;
            return elem;
        }
        string XmlInsert(string Xml)
        {
            XmlDocument myXmlDocument = new XmlDocument();
            Stream strm = Mod.GenerateStreamFromString(Xml);
            myXmlDocument.Load(strm);
            // XmlNode channel = myXmlDocument.GetElementsByTagName("channel")[0];
            XmlNode my = myXmlDocument.DocumentElement;
            // XmlNode my = myXmlDocument.CreateNode(XmlNodeType.Element, "my", "");
            my.PrependChild(getXmlElement(myXmlDocument, "title", (_Title ? "1" : "0")));
            my.PrependChild(getXmlElement(myXmlDocument, "image", (_Image ? "1" : "0")));
            my.PrependChild(getXmlElement(myXmlDocument, "name", (_Name ? "1" : "0")));
            my.PrependChild(getXmlElement(myXmlDocument, "target", _Target));
            my.PrependChild(getXmlElement(myXmlDocument, "back", RequestRSSback));
            my.PrependChild(getXmlElement(myXmlDocument, "user", _user));
            my.PrependChild(getXmlElement(myXmlDocument, "album", _album));
            my.PrependChild(getXmlElement(myXmlDocument, "photo", _photo));
            // root.PrependChild(my);
            return myXmlDocument.OuterXml;
        }
        string GetXslCode()
        {
            string TextToDisplay = "";
            string Extension = "xml";
            if (_Fil == "")
            {
                TextToDisplay = _Text;
            }
            else
            {
                string AbsolutePath = Server.MapPath(_Pat);
                if (!AbsolutePath.EndsWith("\\")) AbsolutePath += "\\";
                Extension = Path.GetExtension(_Fil).ToLower();
                if (Extension.StartsWith(".")) Extension = Extension.Substring(1);
                if (File.Exists(AbsolutePath + _Fil))
                {
                    TextToDisplay = File.ReadAllText(AbsolutePath + _Fil);
                }
            }
            return TextToDisplay;
        }
    }
}