using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Web;

namespace Azyobuzi.Twirunrun
{
    public class StatusBrowser : WebBrowser
    {
        public StatusBrowser()
        {
            scripts = new StatusBrowserScripts(this);
        }

        private StatusBrowserScripts scripts;
        public StatusBrowserScripts Scripts
        {
            get
            {
                return scripts;
            }
        }
    }

    public class StatusBrowserScripts
    {
        private StatusBrowser browser;
        public StatusBrowserScripts(StatusBrowser ownerBrowser)
        {
            this.browser = ownerBrowser;
            browser.DocumentCompleted += (sender, e) => doc = browser.Document;
            if (browser.Document != null)
                doc = browser.Document;
        }

        private HtmlDocument doc;

        private void CheckUri()//resultPage.htmlではない場合に例外を発生させる
        {
            if (!browser.Url.AbsolutePath.EndsWith("resultPage.html", StringComparison.InvariantCultureIgnoreCase))
                throw new InvalidOperationException("ブラウザのURIがresultPage.htmlではありません。");
        }

        public void ClearResult()
        {
            doc.InvokeScript("clearResult");
        }

        private string CreateHtml(string statusText)
        {
            return statusText.HtmlEncode()
                .RegexReplace(@"https?://[\w\d/%#$&?()~_.=+\-!]+", (match) =>
                    string.Format(@"<a href=""{0}"">{1}</a>",
                        match.ToString().HtmlAttributeEncode(), match.ToString().HtmlEncode()))
                .RegexReplace(@"[@＠][a-zA-Z0-9_]+"/*\wだとうまく認識しない*/, (match) =>
                    string.Format(@"{0}<a href=""https://twitter.com/{1}"">{1}</a>", match.ToString()[0], match.ToString().Substring(1)))
                .RegexReplace(@"(^|[^\w&])([#＃][a-zA-Z0-9_\-]+)", (match) =>
                    string.Format(@"{0}<a href=""https://twitter.com/search?q={1}"">{2}</a>", match.Groups[1].ToString(), Uri.EscapeDataString(match.Groups[2].ToString()).HtmlAttributeEncode(), match.Groups[2].ToString()));
        }

        private string CreateNameHtml(StatusInfo status)
        {
            string re;
            if (status.Type == StatusTypes.Retweet)
            {
                re = string.Format("{0}/{1} (RT by {2})",
                    status.User.Identifier.ScreenName,
                    status.User.Name,
                    Settings.Instance.NameType == NameTypes.Name ? status.Tweet.User.Name : status.Tweet.User.Identifier.ScreenName
                    );
            }
            else
            {
                re = string.Format("{0}/{1}", status.User.Identifier.ScreenName, status.User.Name);
            }
            return re.HtmlEncode();
        }

        public void ShowStatus(StatusInfo status)
        {
            doc.InvokeScript(
                "showStatus",
                Extensions.CreateArray(
                    CreateHtml(status.Text),
                    CreateNameHtml(status),
                    status.CreatedAt.ToString().HtmlEncode(),
                    status.Source != null ? "via " + status.Source.ToString() : "<br />",
                    status.ProfileImageUri.HtmlAttributeEncode()
                )
            );
        }

        public void AddStatus(StatusInfo status)
        {
            doc.InvokeScript(
                "addStatus",
                Extensions.CreateArray(
                    CreateHtml(status.Text),
                    CreateNameHtml(status),
                    status.CreatedAt.ToString().HtmlEncode(),
                    status.Source != null ? "via " + status.Source.ToString() : "<br />",
                    status.ProfileImageUri.HtmlAttributeEncode()
                )
            );
        }
    }
}
