using System;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MaterialSkin.Controls
{
    /// <summary>
    /// Material design-like progress bar
    /// </summary>
    public class MaterialProgressBar : ProgressBar, IMaterialControl
    {
        private int _animation;

        /// <summary>
        /// Initializes a new instance of the <see cref="MaterialProgressBar"/> class.
        /// </summary>
        public MaterialProgressBar()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            Timer timer = new Timer();
            timer.Interval = 33;
            timer.Tick += Timer_Tick;
            timer.Enabled = true;
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            Invalidate();
        }

        /// <summary>
        /// Gets or sets the depth.
        /// </summary>
        /// <value>
        /// The depth.
        /// </value>
        [Browsable(false)]
        public int Depth { get; set; }

        /// <summary>
        /// Gets the skin manager.
        /// </summary>
        /// <value>
        /// The skin manager.
        /// </value>
        [Browsable(false)]
        public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;

        /// <summary>
        /// Gets or sets the state of the mouse.
        /// </summary>
        /// <value>
        /// The state of the mouse.
        /// </value>
        [Browsable(false)]
        public MouseState MouseState { get; set; }

        /// <summary>
        /// Performs the work of setting the specified bounds of this control.
        /// </summary>
        /// <param name="x">The new <see cref="P:System.Windows.Forms.Control.Left" /> property value of the control.</param>
        /// <param name="y">The new <see cref="P:System.Windows.Forms.Control.Top" /> property value of the control.</param>
        /// <param name="width">The new <see cref="P:System.Windows.Forms.Control.Width" /> property value of the control.</param>
        /// <param name="height">The new <see cref="P:System.Windows.Forms.Control.Height" /> property value of the control.</param>
        /// <param name="specified">A bitwise combination of the <see cref="T:System.Windows.Forms.BoundsSpecified" /> values.</param>
        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
        {
            base.SetBoundsCore(x, y, width, 5, specified);
        }

        protected override void CreateHandle()
        {
            base.CreateHandle();
            if (Style == ProgressBarStyle.Marquee)
                StartAnimation();
        }

        private void StartAnimation()
        {
            _animation = 0;
        }

        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Control.Paint" /> event.
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs" /> that contains the event data.</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            if (Style == ProgressBarStyle.Marquee)
            {
                try
                {

                
                
                var animationProgress = (int)(e.ClipRectangle.Width * ((double)_animation / Maximum));
                var doneProgress = (int)(e.ClipRectangle.Width * ((double)Value / Maximum));
                if (doneProgress + animationProgress > e.ClipRectangle.Width)
                    doneProgress = e.ClipRectangle.Width - animationProgress;

                _animation+=Step;
                if (_animation >= 100) _animation = -Value;
                e.Graphics.FillRectangle(SkinManager.GetDisabledOrHintBrush(), 0, 0, e.ClipRectangle.Width, e.ClipRectangle.Height);
                e.Graphics.FillRectangle(SkinManager.ColorScheme.PrimaryBrush, animationProgress, 0, doneProgress, e.ClipRectangle.Height);
                //Task.Delay(33).ContinueWith((x) =>
                //{
                //    try
                //    {
                //        System.Action a = () => {  };
                //        if (InvokeRequired)
                //            Invoke(a);
                //        else
                //            a();
                //    }catch{}

                //});
                }
                catch (Exception exception)
                {

                }
            }
            else
            {
                var doneProgress = (int)(e.ClipRectangle.Width * ((double)Value / Maximum));
                e.Graphics.FillRectangle(SkinManager.ColorScheme.PrimaryBrush, 0, 0, doneProgress, e.ClipRectangle.Height);
                e.Graphics.FillRectangle(SkinManager.GetDisabledOrHintBrush(), doneProgress, 0, e.ClipRectangle.Width, e.ClipRectangle.Height);
            }
            
        }
    }
}
