namespace RyzStudio.Windows.ThemedForms
{
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Drawing.Design;
    using System.Windows.Forms;
    using Resources = AppLauncher.Properties.Resources;

    public partial class BorderlessToolForm : System.Windows.Forms.Form
    {
        protected bool isBusy = false;

        protected Color topFillColour = Color.FromArgb(15, 15, 15);
        protected int topFillHeight = 32;
        protected int borderWidth = 1;

        private bool windowDragging = false;
        private Point windowOffset = new Point();
        private Point windowSize = new Point();

        public BorderlessToolForm() : base()
        {
            this.InitializeComponent();

            this.BackColor = Color.FromArgb(246, 246, 246);
            this.Padding = new Padding(1);

			this.topFillColour = Color.FromArgb(51, 51, 51);
			this.topFillHeight = 32;

			this.BackColor = Color.FromArgb(179, 179, 179);
            this.FormBorderStyle = FormBorderStyle.None;

            imgbxMinimise.Click += pictureBox1_Click;
            imgbxMaximise.Click += pictureBox2_Click;
            imgbxClose.Click += pictureBox3_Click;
            imgbxMenu.Click += pictureBox4_Click;

            updatePictureBox2Image();
        }

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

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

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics g = e.Graphics;

            Rectangle areaTop = new Rectangle(this.DisplayRectangle.Left, this.Padding.Top, this.DisplayRectangle.Width, topFillHeight);
            Rectangle areaBorder = new Rectangle(this.ClientRectangle.X, this.ClientRectangle.Y, this.ClientRectangle.Width - borderWidth, this.ClientRectangle.Height - borderWidth);

            // draw header
            if (topFillHeight > 0)
            {
                g.FillRectangle(new SolidBrush(topFillColour), areaTop);
            }

            // draw logo
            //if (this.TitleLogo != null)
            //{
            //    g.DrawImageUnscaled(this.TitleLogo, this.Padding.Left, this.Padding.Top);
            //}

            g.DrawRectangle(new Pen(Color.Black, borderWidth), areaBorder);
        }

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

            updatePictureBox2Image();

            this.Invalidate();
        }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new Color BackColor { get => base.BackColor; set => base.BackColor = value; }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new FormBorderStyle FormBorderStyle { get => base.FormBorderStyle; set => base.FormBorderStyle = value; }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new Padding Padding { get => base.Padding; set => base.Padding = value; }

        [Category("Appearance"), Browsable(true)]
        public string Description
        {
            get
            {
                return lblDescription.Text?.Replace("\n", "\\n");
            }
            set
            {
                lblDescription.Text = value?.Replace("\\n", "\n");
            }
        }

        //[Category("Appearance"), Browsable(true)]
        //public Image TitleLogo { get; set; }

        [Category("Appearance"), Browsable(true)]
        public Image Banner { get; set; }

        [Category("Appearance"), Browsable(true)]
        public bool ShowMenuButton { get => imgbxMenu.Visible; set => imgbxMenu.Visible = value; }

        [Category("Appearance"), Browsable(true)]
        public bool ShowMinimiseButton { get => imgbxMinimise.Visible; set => imgbxMinimise.Visible = value; }

        [Category("Appearance"), Browsable(true)]
        public bool ShowMaximiseButton { get => imgbxMaximise.Visible; set => imgbxMaximise.Visible = value; }

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

        private void pictureBox4_Click(object sender, System.EventArgs e)
        {
            //this.WindowState = FormWindowState.Minimized;
        }

        private void pictureBox1_Click(object sender, System.EventArgs e)
        {
            MouseEventArgs mouseEvent = (MouseEventArgs)e;
            if (mouseEvent != null)
            {
                if (mouseEvent.Button != MouseButtons.Left)
                {
                    return;
                }
            }

            this.WindowState = FormWindowState.Minimized;
        }

        private void pictureBox2_Click(object sender, System.EventArgs e)
        {
            MouseEventArgs mouseEvent = (MouseEventArgs)e;
            if (mouseEvent != null)
            {
                if (mouseEvent.Button != MouseButtons.Left)
                {
                    return;
                }
            }

            if (this.WindowState == FormWindowState.Maximized)
            {
                this.WindowState = FormWindowState.Normal;
                imgbxMaximise.NormalImage = Resources.form16_maximise;
                imgbxMaximise.HighlightImage = Resources.form16_maximise2;
            }
            else
            {
                this.WindowState = FormWindowState.Maximized;
                imgbxMaximise.NormalImage = Resources.form16_restore;
                imgbxMaximise.HighlightImage = Resources.form16_restore2;
            }
        }

        private void pictureBox3_Click(object sender, System.EventArgs e)
        {
            MouseEventArgs mouseEvent = (MouseEventArgs)e;
            if (mouseEvent != null)
            {
                if (mouseEvent.Button != MouseButtons.Left)
                {
                    return;
                }
            }

            this.Close();
        }

        public void SetValue(Label sender, string value)
        {
            if (sender.InvokeRequired)
            {
                sender.Invoke(new MethodInvoker(() => { sender.Text = value; }));
            }
            else
            {
                sender.Text = value;
            }
        }

        public void SetValue(GroupBox sender, string value)
        {
            if (sender.InvokeRequired)
            {
                sender.Invoke(new MethodInvoker(() => { sender.Text = value; }));
            }
            else
            {
                sender.Text = value;
            }
        }

        public void AddValue(ListBox sender, string value)
        {
            if (sender.InvokeRequired)
            {
                sender.Invoke(new MethodInvoker(() => { sender.Items.Add(value); }));
            }
            else
            {
                sender.Items.Add(value);
            }
        }

        public void AddControl(FlowLayoutPanel sender, Control value)
        {
            if (sender.InvokeRequired)
            {
                sender.Invoke(new MethodInvoker(() =>
                {
                    sender.Controls.Add(value);
                }));
            }
            else
            {
                sender.Controls.Add(value);
            }
        }

        public void ClearValues(ListBox sender)
        {
            if (sender.InvokeRequired)
            {
                sender.Invoke(new MethodInvoker(() => { sender.Items.Clear(); }));
            }
            else
            {
                sender.Items.Clear();
            }
        }

        public string GetValue(ListBox sender)
        {
            string rv = string.Empty;

            if (sender.InvokeRequired)
            {
                sender.Invoke(new MethodInvoker(() => { rv = (sender.SelectedItem == null) ? string.Empty : sender.SelectedItem.ToString(); }));
            }
            else
            {
                rv = (sender.SelectedItem == null) ? string.Empty : sender.SelectedItem.ToString();
            }

            return rv;
        }

        public string GetValue(TTextBox sender)
        {
            string rv = string.Empty;

            if (sender.InvokeRequired)
            {
                sender.Invoke(new MethodInvoker(() => { rv = sender.Text.Trim(); }));
            }
            else
            {
                rv = sender.Text.Trim();
            }

            return rv;
        }

        public int GetValue(NumericUpDown sender)
        {
            int rv = 0;

            if (sender.InvokeRequired)
            {
                sender.Invoke(new MethodInvoker(() => { rv = (int)sender.Value; }));
            }
            else
            {
                rv = (int)sender.Value;
            }

            return rv;
        }

        protected void updatePictureBox2Image()
        {
            if (this.WindowState == FormWindowState.Maximized)
            {
                imgbxMaximise.NormalImage = Resources.form16_restore;
                imgbxMaximise.HighlightImage = Resources.form16_restore2;
            }
            else
            {
                imgbxMaximise.NormalImage = Resources.form16_maximise;
                imgbxMaximise.HighlightImage = Resources.form16_maximise2;
            }
        }

        private void label1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
            {
                return;
            }

            windowDragging = true;
            windowOffset = e.Location;
        }

        private void label1_MouseUp(object sender, MouseEventArgs e)
        {
            windowDragging = false;
        }

        private void label1_MouseMove(object sender, MouseEventArgs e)
        {
            if (windowDragging)
            {
                Point currentScreenPos = PointToScreen(e.Location);
                Location = new Point(currentScreenPos.X - windowOffset.X, currentScreenPos.Y - windowOffset.Y);
            }
        }

        private void label1_DoubleClick(object sender, EventArgs e) => pictureBox2_Click(sender, e);

        private void label1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Middle)
            {
                this.TopMost = !this.TopMost;
            }
        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
            {
                return;
            }

            windowDragging = true;
            windowOffset = e.Location;
            windowSize = new Point(this.Width, this.Height);
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            windowDragging = false;
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (windowDragging)
            {
                this.Size = new Size(e.X - windowOffset.X + this.Width, e.Y - windowOffset.Y + this.Height);
            }
        }

        private void panel2_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
            {
                return;
            }

            windowDragging = true;
            windowOffset = e.Location;
            windowSize = new Point(this.Width, this.Height);
        }

        private void panel2_MouseUp(object sender, MouseEventArgs e)
        {
            windowDragging = false;

        }

        private void panel2_MouseMove(object sender, MouseEventArgs e)
        {
            if (windowDragging)
            {
                this.Size = new Size(windowSize.X, e.Y - windowOffset.Y + this.Height);
            }
        }
    }
}