using BookmarkManager;
using bzit.bomg.Models;
using RyzStudio.Windows.Forms;
using RyzStudio.Windows.ThemedForms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Net;
using System.Threading.Tasks;
using System.Windows.Forms;
using TProgressBar = RyzStudio.Windows.Forms.TCustomProgressBar;

namespace FizzyLauncher
{
    public class UpdateIconsForm : TDialogForm
    {
        private System.Windows.Forms.Label label1;
        private TButton button1;
        private RyzStudio.Windows.Forms.THorizontalSeparator tHorizontalSeparator1;
        private RyzStudio.Windows.Forms.THorizontalSeparator tHorizontalSeparator2;
        private Label label2;
        private PictureBox pictureBox2;

        private ToolTip toolTip1;
        private System.ComponentModel.IContainer components;

        protected BookmarkTreeView bookmarkTreeView = null;
        protected IconDatabase iconDatabase = null;

        protected WebParser webParser = null;
        protected WebClient webClient = null;
        private TYesNoPickerBox pickerBox1;
        private TButton button2;


        protected bool isBusy = false;
        private RyzStudio.Windows.ThemedForms.TProgressBar progressBar1;
        protected bool requestCancellation = false;


        public UpdateIconsForm(BookmarkTreeView treeView, IconDatabase database)
        {
            InitializeComponent();

            bookmarkTreeView = treeView;
            iconDatabase = database;

            pickerBox1.InnerControl.SelectedIndexChanged += comboBox1_SelectedIndexChanged;

        }

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.label1 = new System.Windows.Forms.Label();
            this.button1 = new RyzStudio.Windows.ThemedForms.TButton();
            this.tHorizontalSeparator1 = new RyzStudio.Windows.Forms.THorizontalSeparator();
            this.tHorizontalSeparator2 = new RyzStudio.Windows.Forms.THorizontalSeparator();
            this.label2 = new System.Windows.Forms.Label();
            this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
            this.pictureBox2 = new System.Windows.Forms.PictureBox();
            this.pickerBox1 = new RyzStudio.Windows.ThemedForms.TYesNoPickerBox();
            this.button2 = new RyzStudio.Windows.ThemedForms.TButton();
            this.progressBar1 = new RyzStudio.Windows.ThemedForms.TProgressBar();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
            this.SuspendLayout();
            //
            // label1
            //
            this.label1.AutoSize = true;
            this.label1.BackColor = System.Drawing.Color.Transparent;
            this.label1.ForeColor = System.Drawing.SystemColors.ControlText;
            this.label1.Location = new System.Drawing.Point(10, 21);
            this.label1.Margin = new System.Windows.Forms.Padding(0);
            this.label1.Name = "label1";
            this.label1.Padding = new System.Windows.Forms.Padding(0, 9, 0, 10);
            this.label1.Size = new System.Drawing.Size(154, 34);
            this.label1.TabIndex = 153;
            this.label1.Text = "Find outstanding icons only";
            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            //
            // button1
            //
            this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.button1.BackColor = System.Drawing.Color.Transparent;
            this.button1.DefaultImage = null;
            this.button1.DownImage = null;
            this.button1.IsSelected = false;
            this.button1.LabelText = "&Close";
            this.button1.Location = new System.Drawing.Point(241, 469);
            this.button1.Margin = new System.Windows.Forms.Padding(10);
            this.button1.Name = "button1";
            this.button1.OverImage = null;
            this.button1.Padding = new System.Windows.Forms.Padding(4, 4, 3, 3);
            this.button1.Size = new System.Drawing.Size(128, 32);
            this.button1.TabIndex = 173;
            this.button1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.button1_MouseClick);
            //
            // tHorizontalSeparator1
            //
            this.tHorizontalSeparator1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
            | System.Windows.Forms.AnchorStyles.Right)));
            this.tHorizontalSeparator1.AutoScrollMargin = new System.Drawing.Size(0, 0);
            this.tHorizontalSeparator1.AutoScrollMinSize = new System.Drawing.Size(0, 0);
            this.tHorizontalSeparator1.BackColor = System.Drawing.Color.Transparent;
            this.tHorizontalSeparator1.Location = new System.Drawing.Point(10, 437);
            this.tHorizontalSeparator1.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0);
            this.tHorizontalSeparator1.MaximumSize = new System.Drawing.Size(4920, 2);
            this.tHorizontalSeparator1.MinimumSize = new System.Drawing.Size(0, 22);
            this.tHorizontalSeparator1.Name = "tHorizontalSeparator1";
            this.tHorizontalSeparator1.Padding = new System.Windows.Forms.Padding(0, 10, 0, 10);
            this.tHorizontalSeparator1.Size = new System.Drawing.Size(364, 22);
            this.tHorizontalSeparator1.TabIndex = 188;
            //
            // tHorizontalSeparator2
            //
            this.tHorizontalSeparator2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
            | System.Windows.Forms.AnchorStyles.Right)));
            this.tHorizontalSeparator2.AutoScrollMargin = new System.Drawing.Size(0, 0);
            this.tHorizontalSeparator2.AutoScrollMinSize = new System.Drawing.Size(0, 0);
            this.tHorizontalSeparator2.BackColor = System.Drawing.Color.Transparent;
            this.tHorizontalSeparator2.Location = new System.Drawing.Point(10, 59);
            this.tHorizontalSeparator2.Margin = new System.Windows.Forms.Padding(10, 0, 10, 0);
            this.tHorizontalSeparator2.MaximumSize = new System.Drawing.Size(4920, 2);
            this.tHorizontalSeparator2.MinimumSize = new System.Drawing.Size(0, 22);
            this.tHorizontalSeparator2.Name = "tHorizontalSeparator2";
            this.tHorizontalSeparator2.Padding = new System.Windows.Forms.Padding(0, 10, 0, 10);
            this.tHorizontalSeparator2.Size = new System.Drawing.Size(364, 22);
            this.tHorizontalSeparator2.TabIndex = 190;
            //
            // label2
            //
            this.label2.AutoSize = true;
            this.label2.BackColor = System.Drawing.Color.Transparent;
            this.label2.ForeColor = System.Drawing.SystemColors.ControlText;
            this.label2.Location = new System.Drawing.Point(10, 85);
            this.label2.Margin = new System.Windows.Forms.Padding(0);
            this.label2.Name = "label2";
            this.label2.Padding = new System.Windows.Forms.Padding(0, 9, 0, 10);
            this.label2.Size = new System.Drawing.Size(52, 34);
            this.label2.TabIndex = 195;
            this.label2.Text = "Progress";
            this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            //
            // pictureBox2
            //
            this.pictureBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.pictureBox2.BackColor = System.Drawing.Color.Transparent;
            this.pictureBox2.ErrorImage = null;
            this.pictureBox2.InitialImage = null;
            this.pictureBox2.Location = new System.Drawing.Point(196, 469);
            this.pictureBox2.Name = "pictureBox2";
            this.pictureBox2.Size = new System.Drawing.Size(32, 32);
            this.pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
            this.pictureBox2.TabIndex = 202;
            this.pictureBox2.TabStop = false;
            //
            // pickerBox1
            //
            this.pickerBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.pickerBox1.BackColor = System.Drawing.Color.Transparent;
            this.pickerBox1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
            this.pickerBox1.Location = new System.Drawing.Point(285, 21);
            this.pickerBox1.Margin = new System.Windows.Forms.Padding(10, 4, 10, 4);
            this.pickerBox1.Name = "pickerBox1";
            this.pickerBox1.Padding = new System.Windows.Forms.Padding(10, 6, 7, 5);
            this.pickerBox1.Size = new System.Drawing.Size(84, 34);
            this.pickerBox1.SubmitButton = null;
            this.pickerBox1.TabIndex = 203;
            this.pickerBox1.Value = true;
            //
            // button2
            //
            this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.button2.BackColor = System.Drawing.Color.Transparent;
            this.button2.DefaultImage = null;
            this.button2.DownImage = null;
            this.button2.IsSelected = false;
            this.button2.LabelText = "&Run";
            this.button2.Location = new System.Drawing.Point(241, 168);
            this.button2.Margin = new System.Windows.Forms.Padding(10);
            this.button2.Name = "button2";
            this.button2.OverImage = null;
            this.button2.Padding = new System.Windows.Forms.Padding(4, 4, 3, 3);
            this.button2.Size = new System.Drawing.Size(128, 32);
            this.button2.TabIndex = 205;
            this.button2.MouseClick += new System.Windows.Forms.MouseEventHandler(this.button2_MouseClick);
            //
            // progressBar1
            //
            this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
            | System.Windows.Forms.AnchorStyles.Right)));
            this.progressBar1.BackColor = System.Drawing.Color.Transparent;
            this.progressBar1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
            this.progressBar1.Location = new System.Drawing.Point(10, 119);
            this.progressBar1.Margin = new System.Windows.Forms.Padding(10, 6, 10, 6);
            this.progressBar1.Name = "progressBar1";
            this.progressBar1.Padding = new System.Windows.Forms.Padding(6, 6, 5, 5);
            this.progressBar1.Size = new System.Drawing.Size(359, 33);
            this.progressBar1.TabIndex = 206;
            //
            // UpdateIconsForm
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(384, 521);
            this.Controls.Add(this.progressBar1);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.pickerBox1);
            this.Controls.Add(this.pictureBox2);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.tHorizontalSeparator2);
            this.Controls.Add(this.tHorizontalSeparator1);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.label1);
            this.KeyPreview = true;
            this.MinimumSize = new System.Drawing.Size(400, 560);
            this.Name = "UpdateIconsForm";
            this.Text = "Update Icons";
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            comboBox1_SelectedIndexChanged(null, null);
        }

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);

            this.DialogResult = DialogResult.None;
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);

            if (IsBusy)
            {
                e.Cancel = true;
            }
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                if (!IsBusy)
                {
                    this.Close();
                }
            }

            base.OnKeyDown(e);
        }


        protected bool IsBusy
        {
            get => isBusy;
            set
            {
                isBusy = value;

                ThreadControl.SetValue(pictureBox2, (isBusy ? AppResource.loading_block : null));

                ThreadControl.SetEnable(pickerBox1, !isBusy);
                button2.LabelText = (isBusy ? "&Stop" : "&Run");
            }
        }


        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (IsBusy)
            {
                return;
            }

            List<BookmarkItem> bookmarkList = GetBookmarkFilteredList();

            progressBar1.InnerControl.Reset(bookmarkList.Count);
        }

        private async void button2_MouseClick(object sender, MouseEventArgs e)
        {
            await Task.Run(() =>
            {
                if (IsBusy)
                {
                    requestCancellation = true;
                    return;
                }

                IsBusy = true;

                WebParser webParser = new WebParser();
                List<BookmarkItem> bookmarkList = GetBookmarkFilteredList();

                progressBar1.InnerControl.Reset(bookmarkList.Count);

                for (int i=0; i<bookmarkList.Count; i++)
                {
                    progressBar1.InnerControl.Value = (i + 1);

                    if (requestCancellation) break;

                    BookmarkItem item = bookmarkList[i];

                    BookmarkResult result = webParser.RetrieveDetails(item.SiteAddress);
                    if (result == null)
                    {
                        continue;
                    }

                    if (string.IsNullOrWhiteSpace(result.IconURL))
                    {
                        continue;
                    }

                    if (requestCancellation) break;

                    Image favicon = webParser.RetrieveImage(result.IconURL);
                    if (favicon == null)
                    {
                        continue;
                    }

                    iconDatabase.AddIcon(item.ToHash(), favicon);
                }

                IsBusy = false;
                requestCancellation = false;
            });
        }

        private void button1_MouseClick(object sender, MouseEventArgs e)
        {
            this.DialogResult = DialogResult.OK;
            this.Close();
        }


        protected List<BookmarkItem> GetBookmarkFilteredList()
        {
            List<BookmarkItem> rs = bookmarkTreeView.GetBookmarkList();

            // remove empty
            for (int i = 0; i < rs.Count; i++)
            {
                if (string.IsNullOrWhiteSpace(rs[i].SiteAddress))
                {
                    rs.Remove(rs[i]);
                }
            }

            if (pickerBox1.Value)
            {
                for (int i = 0; i < rs.Count; i++)
                {
                    if (iconDatabase.HasIcon(rs[i].ToHash()))
                    {
                        rs.Remove(rs[i]);
                    }
                }
            }

            return rs;
        }


    }
}