using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using System.IO;
using System.Net;
using System.Web;
using System.Text.RegularExpressions;
using System.Diagnostics;
using pcmp.Setting;
using System.Threading;

namespace pcmp.Forms
{
    public partial class FormPeCaInfo : DockContent
    {
        string pecaurl;
        string htmlurl;
        string htmldir;

        public FormPeCaInfo()
        {
            this.Text = "PeerCast情報";
            Application.Idle += new EventHandler(Application_Idle);
        }

        void Application_Idle(object sender, EventArgs e)
        {
            Application.Idle -= new EventHandler(Application_Idle);
            InitializeFormPeCaInfo();
        }

        private void InitializeFormPeCaInfo()
        {
            InitializeComponent();

            pecaurl = "http://" + Settings.GeneralSetting.NetworkSetting.HostAddr;
            htmlurl = pecaurl + "/html/pcmp/";
            htmldir = Path.Combine(
                Path.GetDirectoryName(Settings.GeneralSetting.PeerCastPath),
                "html\\pcmp");

            if (!CheckHtmlFiles())
            {
                buttonCopyHtml.Visible = true;
                labelinfo.Visible = true;
                buttonApplyPeCaSetting.Enabled = false;
            }

            RefreshValue();
        }

        private bool CheckHtmlFiles()
        {
            if (!Directory.Exists(htmldir)) return false;
            if (!File.Exists(Path.Combine(htmldir, "PeCaInfo.html"))) return false;
            if (!File.Exists(Path.Combine(htmldir, "ChannelInfo.html"))) return false;
            if (!File.Exists(Path.Combine(htmldir, "RelayInfoList.html"))) return false;
            return true;
        }

        private void CopyHtmlFiles()
        {
            if (!Directory.Exists(htmldir))
                Directory.CreateDirectory(htmldir);

            string srcdir = Path.Combine(Application.StartupPath, "html\\pcmp\\");
            if (!File.Exists(Path.Combine(htmldir, "PeCaInfo.html")))
                File.Copy(Path.Combine(srcdir, "PeCaInfo.html"), Path.Combine(htmldir, "PeCaInfo.html"));

            if (!File.Exists(Path.Combine(htmldir, "ChannelInfo.html")))
                File.Copy(Path.Combine(srcdir, "ChannelInfo.html"), Path.Combine(htmldir, "ChannelInfo.html"));

            if (!File.Exists(Path.Combine(htmldir, "RelayInfoList.html")))
                File.Copy(Path.Combine(srcdir, "RelayInfoList.html"), Path.Combine(htmldir, "RelayInfoList.html"));

            labelinfo.Visible = false;
            buttonCopyHtml.Visible = false;
            buttonApplyPeCaSetting.Enabled = true;

            RefreshValue();
        }

        private void RefreshValue()
        {
            pecaurl = "http://" + Settings.GeneralSetting.NetworkSetting.HostAddr;
            htmlurl = pecaurl + "/html/pcmp/";
            htmldir = Path.Combine(
                Path.GetDirectoryName(Settings.GeneralSetting.PeerCastPath),
                "html\\pcmp");

            if (!Directory.Exists(htmldir)) return;
            if (!File.Exists(Path.Combine(htmldir, "PeCaInfo.html")))
            {
                if (MessageBox.Show("情報を取得するために必要なhtmlファイルが見つかりません。\r\nコピーしますか？", "エラー", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    CopyHtmlFiles();
                    RefreshChannelInfo();
                }
                return;
            }

            buttonRefreshPeCaInfo.Enabled = false;

            HttpWebRequest webreq = (HttpWebRequest)WebRequest.Create(new Uri(htmlurl + "PeCaInfo.html"));
            webreq.BeginGetResponse(new AsyncCallback(DownloadPeCaInfoCompleted), webreq);

            //Thread thread = new Thread(delegate()
            //    {
            //        WebClient wc = new WebClient();
            //        wc.Encoding = Encoding.UTF8;
            //        string text = string.Empty;
            //        try
            //        {
            //            text = wc.DownloadString(new Uri(htmlurl + "PeCaInfo.html"));
            //        }
            //        catch (WebException) { }

            //        DownloadPeCaInfoCompleted(text);
            //    });
            //thread.Start();
        }

        void DownloadPeCaInfoCompleted(IAsyncResult ar)
        {
            StreamReader sr = null;
            string html = string.Empty;
            try
            {
                HttpWebResponse webres = (HttpWebResponse)((HttpWebRequest)ar.AsyncState).EndGetResponse(ar);
                sr = new StreamReader(webres.GetResponseStream(), Encoding.UTF8);
                html = sr.ReadToEnd();
            }
            catch (WebException) { }
            finally
            {
                if (sr != null) sr.Close();
            }

            string[] s = html.Split(new string[] { "\r\n" }, StringSplitOptions.None);
            if (s.Length == 21)
            {
                this.Invoke((MethodInvoker)delegate
                {
                    textBoxPeCaVer.Text = s[0];
                    textBoxLocalIP.Text = s[1];
                    textBoxServerIP.Text = s[2];
                    textBoxFirewall.Text = s[3];
                    textBoxUptime.Text = HttpUtility.HtmlDecode(s[4]);
                    textBoxChannelCache.Text = s[5];
                    textBoxHostOption.Text = s[6];
                    textBoxBandWidthDL.Text = s[7];
                    textBoxBandWidthUL.Text = s[8];
                    textBoxBandWidth.Text = s[9];
                    textBoxDirectConnect.Text = s[10];
                    textBoxRelayConnect.Text = s[11];
                    textBoxCINCOUT.Text = s[12];
                    textBoxPGNU.Text = s[13];
                    textBoxIncoming.Text = s[14];
                    textBoxPort1Connect.Text = s[15];
                    textBoxPort2Connect.Text = s[16];
                    textBoxMaxUL.Text = s[17];
                    textBoxMaxRelay.Text = s[18];
                    textBoxMaxRelayPerChannel.Text = s[19];
                    textBoxMaxRelayIndexText.Text = s[20];
                });
            }

            this.Invoke((MethodInvoker)delegate
            {
                buttonRefreshPeCaInfo.Enabled = true;
            });
        }

        private void buttonRefreshPeCaInfo_Click(object sender, EventArgs e)
        {
            RefreshValue();
        }

        private void buttonApplyPeCaSetting_Click(object sender, EventArgs e)
        {
            string url = pecaurl +
                string.Format("/admin?cmd=apply&maxup={0}&maxrelays={1}&maxrelaypc={2}&maxRelaysIndexTxt={3}",
                textBoxMaxUL.Text, textBoxMaxRelay.Text, textBoxMaxRelayPerChannel.Text, textBoxMaxRelayIndexText.Text);
            new WebClient().DownloadStringAsync(new Uri(url));

            RefreshValue();
        }

        private void buttonRefreshChannelInfo_Click(object sender, EventArgs e)
        {
            RefreshChannelInfo();
        }

        private void RefreshChannelInfo()
        {
            listViewChannels.Items.Clear();

            if (!Directory.Exists(htmldir)) return;
            if (!File.Exists(Path.Combine(htmldir, "ChannelInfo.html")))
            {
                if (MessageBox.Show("情報を取得するために必要なhtmlファイルが見つかりません。\r\nコピーしますか？", "エラー", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    CopyHtmlFiles();
                    RefreshChannelInfo();
                }
                return;
            }

            buttonRefreshChannelInfo.Enabled = false;
            WebClient wc = new WebClient();
            wc.Encoding = Encoding.UTF8;
            wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadChannelInfoCompleted);
            wc.DownloadStringAsync(new Uri(htmlurl + "ChannelInfo.html"));
        }

        void DownloadChannelInfoCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            listViewChannels.Items.Clear();
            string html = e.Result;
            // \r\n で終わっていれば末尾の \r\n を削除
            if (html.EndsWith("\r\n")) html = html.Remove(html.Length - 2);
            string[] st = new string[] { "\r\n" };
            string[] s = html.Split(st, StringSplitOptions.None);

            for (int i = 0; i < s.Length; i++)
            {
                if (i % 8 != 0) continue;
                ListViewItem item = new ListViewItem();
                item.Text = s[i];
                item.SubItems.Add(s[i + 1]);
                item.SubItems.Add(s[i + 2]);
                item.SubItems.Add(s[i + 3]);
                item.SubItems.Add(s[i + 4]);
                item.SubItems.Add(s[i + 5]);
                item.SubItems.Add(s[i + 6]);
                item.SubItems.Add(s[i + 7]);
                listViewChannels.Items.Add(item);
            }

            buttonRefreshChannelInfo.Enabled = true;
        }

        private void listViewChannels_SelectedIndexChanged(object sender, EventArgs e)
        {
            listViewRelays.Items.Clear();

            if (listViewChannels.SelectedItems.Count == 0)
            {
                buttonBump.Enabled = false;
                buttonKeep.Enabled = false;
                buttonStop.Enabled = false;
                buttonPlayChannel.Enabled = false;
                return;
            }

            buttonBump.Enabled = true;
            buttonKeep.Enabled = true;
            buttonStop.Enabled = true;
            buttonPlayChannel.Enabled = true;

            ListViewItem selItem = listViewChannels.SelectedItems[0];
            string ID = selItem.SubItems[6].Text;
            WebClient wc = new WebClient();
            wc.Encoding = Encoding.UTF8;
            wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadRelayInfoListCompleted);
            wc.DownloadStringAsync(new Uri(htmlurl + "RelayInfoList.html?id=" + ID));
        }

        private void DownloadRelayInfoListCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            listViewRelays.Items.Clear();
            string html = e.Result;
            if (html.EndsWith("\r\n")) html = html.Remove(html.Length - 2);
            string[] st = new string[] { "\r\n" };
            string[] s = html.Split(st, StringSplitOptions.None);

            for (int i = 0; i < s.Length; i++)
            {
                if (i % 7 != 0) continue;
                ListViewItem item = new ListViewItem();
                string str;
                Color color = ProcessHtmlTag(s[i], out str);
                item.Text = str;
                item.ForeColor = color;
                item.SubItems.Add(s[i + 1]);
                item.SubItems.Add(s[i + 2]);
                item.SubItems.Add(s[i + 3]);
                item.SubItems.Add(s[i + 4]);
                item.SubItems.Add(s[i + 5]);
                item.SubItems.Add(s[i + 6]);
                listViewRelays.Items.Add(item);
            }
        }

        private Color ProcessHtmlTag(string html, out string str)
        {
            Match m = Regex.Match(html, "<font color=([^>]+)>([^<]*)</font>");
            if (!m.Success)
            {
                str = html;
                return Color.Black;
            }
            else
            {
                str = m.Groups[2].Value;
                return Color.FromName(m.Groups[1].Value);
            }
        }

        private void buttonPlayChannel_Click(object sender, EventArgs e)
        {
            Process.Start(string.Format("{0}/pls/{1}.pls", pecaurl, listViewChannels.SelectedItems[0].SubItems[6].Text));
            RefreshChannelInfo();
        }

        private void buttonBump_Click(object sender, EventArgs e)
        {
            string url = string.Format("{0}/admin?cmd=bump&id={1}", pecaurl, listViewChannels.SelectedItems[0].SubItems[6].Text);
            new WebClient().DownloadStringAsync(new Uri(url));
            RefreshChannelInfo();
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            string url = string.Format("{0}/admin?cmd=stop&id={1}", pecaurl, listViewChannels.SelectedItems[0].SubItems[6].Text);
            new WebClient().DownloadStringAsync(new Uri(url));
            RefreshChannelInfo();
        }

        private void buttonKeep_Click(object sender, EventArgs e)
        {
            string url = string.Format("{0}/admin?cmd=keep&id={1}", pecaurl, listViewChannels.SelectedItems[0].SubItems[6].Text);
            new WebClient().DownloadStringAsync(new Uri(url));
            RefreshChannelInfo();
        }

        internal void ApplySetting()
        {
        }

        private void buttonCopyHtml_Click(object sender, EventArgs e)
        {
            buttonApplyPeCaSetting.Enabled = false;
            CopyHtmlFiles();
        }
    }
}