using Android.Animation;
using Android.Graphics;
using Android.Graphics.Drawables;
using System;
using AColor = Android.Graphics.Color;

namespace Pixiview.Droid.Renderers.AppShellSection
{
    public class AppColorChangeRevealDrawable : AnimationDrawable
    {
        readonly Point _center;
        float _progress;
        bool _disposed;
        ValueAnimator _animator;

        internal AColor StartColor { get; }
        internal AColor EndColor { get; }

        public AppColorChangeRevealDrawable(AColor startColor, AColor endColor, Point center) : base()
        {
            StartColor = startColor;
            EndColor = endColor;

            if (StartColor != EndColor)
            {
                _animator = ValueAnimator.OfFloat(0, 1);
                _animator.SetInterpolator(new Android.Views.Animations.DecelerateInterpolator());
                _animator.SetDuration(500);
                _animator.Update += OnUpdate;
                _animator.Start();
                _center = center;
            }
            else
            {
                _progress = 1;
            }
        }

        public override void Draw(Canvas canvas)
        {
            if (_disposed)
                return;

            if (_progress == 1)
            {
                canvas.DrawColor(EndColor);
                return;
            }

            canvas.DrawColor(StartColor);
            var bounds = Bounds;
            float centerX = _center.X;
            float centerY = _center.Y;

            float width = bounds.Width();
            float distanceFromCenter = Math.Abs(width / 2 - _center.X);
            float radius = (width / 2 + distanceFromCenter) * 1.1f;

            var paint = new Paint
            {
                Color = EndColor
            };

            canvas.DrawCircle(centerX, centerY, radius * _progress, paint);
        }

        void OnUpdate(object sender, ValueAnimator.AnimatorUpdateEventArgs e)
        {
            _progress = (float)e.Animation.AnimatedValue;

            InvalidateSelf();
        }

        protected override void Dispose(bool disposing)
        {
            if (_disposed)
                return;

            _disposed = true;

            if (disposing)
            {
                if (_animator != null)
                {
                    _animator.Update -= OnUpdate;

                    _animator.Cancel();

                    _animator.Dispose();

                    _animator = null;
                }
            }

            base.Dispose(disposing);
        }
    }
}
