using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Threading.Tasks;
using System.Windows.Forms;
using MaterialSkin.Animations;


namespace MaterialSkin.Controls
{
    public class MaterialIcon:Control
    {
        private Image _image;
        private Bitmap _bmp;
        private AnimationManager _animationManager;
        private Point _lastLocation;
        private Bitmap _backBuffer = null;
        private bool _primary;

        public MaterialIcon()
        {
            Cursor = Cursors.Hand;
            Clickable = true;
            _animationManager = new AnimationManager(false)
            {
                Increment = 0.02,
                AnimationType = AnimationType.EaseOut
            };
            
            _animationManager.OnAnimationProgress += sender => Invalidate();
            _animationManager.OnAnimationFinished += AnimationManagerOnOnAnimationFinished;
        }

        private void AnimationManagerOnOnAnimationFinished(object sender)
        {
            
        }



        [Browsable(false)]
        public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;

        public Image Image
        {
            get { return _image; }
            set
            {
                _image = value;
                RebuildIcon();
            }
        }

        public bool Primary
        {
            get { return _primary; }
            set
            {
                _primary = value;
                if (_image == null) return;
                RebuildIcon();
            }
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            base.OnEnabledChanged(e);
            RebuildIcon();
        }

        protected override void OnResize(EventArgs e)
        {
            _backBuffer=new Bitmap(Width,Height);
            if (_image == null) return;
            RebuildIcon();
            base.OnResize(e);
        }

        private void RebuildIcon()
        {
            
            Task.Run(() =>
            {
                lock (_lockObject)
                {
                    var tmp = new Bitmap(_image);
                    ReplaceColor(tmp, Color.Black,
                        Enabled
                            ? (_primary
                                ? SkinManager.GetApplicationBackgroundColor()
                                : SkinManager.ColorScheme.PrimaryColor)
                            : Color.FromArgb(0xAA, 0xAA, 0xAA));
                    _bmp = tmp;
                    Invalidate();
                }
            });
            
        }

        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
            //base.OnPaintBackground(pevent);
        }
        protected override void OnMouseDown(MouseEventArgs mevent)
        {
            base.OnMouseDown(mevent);
            if (!Enabled) return;
            _lastLocation = mevent.Location;
            _animationManager.StartNewAnimation(AnimationDirection.In, _lastLocation);
        }
        
        public bool Clickable { get; set; }
        protected override void OnClick(EventArgs e)
        {
            if (!Clickable) return;
            
            base.OnClick(e);
        }
        protected override void OnPaint(PaintEventArgs pe)
        {
            if (Image == null) return;
            if(_bmp == null)return;
            if(_backBuffer==null)return;
            using (Graphics g=Graphics.FromImage(_backBuffer))
            {
                g.InterpolationMode = InterpolationMode.Bicubic;
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.Clear(_primary? SkinManager.ColorScheme.PrimaryColor : SkinManager.GetApplicationBackgroundColor());
                if (_animationManager.IsAnimating())
                {
                    for (int i = 0; i < _animationManager.GetAnimationCount(); i++)
                    {
                        var animationValue = _animationManager.GetProgress(i);
                        var animationSource = _animationManager.GetSource(i);
                        var rippleBrush = new SolidBrush(Color.FromArgb((int)(51 - (animationValue * 50)), _primary ? SkinManager.GetApplicationBackgroundColor() : SkinManager.ColorScheme.PrimaryColor));
                        var rippleSize = (int)(animationValue * Width * 2);
                        g.FillEllipse(rippleBrush, new Rectangle(animationSource.X - rippleSize / 2, animationSource.Y - rippleSize / 2, rippleSize, rippleSize));
                    }
                }
                g.DrawImage(_bmp,1,1,Width-2,Height-2);
            }
            

            pe.Graphics.DrawImage(_backBuffer, 0,0);


        }
        object _lockObject = new object();
        private void ReplaceColor(Bitmap bmp, Color oldColor, Color newColor)
        {
            
            {
                var lockedBitmap = bmp;

                for (int y = 0; y < lockedBitmap.Height; y++)
                {
                    for (int x = 0; x < lockedBitmap.Width; x++)
                    {
                        if (lockedBitmap.GetPixel(x, y).A > 0)
                        {
                            lockedBitmap.SetPixel(x, y, newColor);
                        }
                    }
                }
            }
        }
       
    }
}