using Otter;
using PpbbffttMiningHa.Utility;
using System;

namespace PpbbffttMiningHa.entities.MapEntities
{
    class Dirt : Entity
    {
        private Entity _destiny;
        private Spritemap<string> _spriteMap;
        //ai follow me code
        private bool isSeekingTarget = true;
        private float closestDistanceItem = 3650f;
        private Entity closestItem;
        private double angleInRadians = 1;//this is about 57 degrees. ;-)
        private const int ScanTimerMax = 50;//50 is fine for slower speeds
        private int scanAgain = ScanTimerMax;
        private readonly int hitTimerMax = Rand.Int(100, 150);
        private bool _isCloseEnoughToPlayer;
        private bool rocketShot;
        //public Image titleImage = new Image(Assets.TILES);

        public Dirt(float x, float y/*, Entity destiny*/)
        {
            X = x; Y = y;
            //_destiny = destiny;
            _spriteMap = new Spritemap<string>(Assets.TILES, 32, 32);
            _spriteMap.Add("walkLeft", new int[] { 0 }, new float[] { 7f, 7f });
            _spriteMap.Add("hit", new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, new float[] { 7f, 7f });
            _spriteMap.Add("walkRight", new int[] { 0 }, new float[] { 7f, 7f });
            SetHitbox(32, 32, Global.Type.SOLID);
            Collider.X = 0;//was -2
            Collider.Y = 0;//was -2
            //_spriteMap.CenterOrigin();
            //Rectangle tileSize = new Rectangle(0, 0, 32, 32);
            //titleImage.ClippingRegion = tileSize;
            //AddGraphic(titleImage);
            _spriteMap.Play("walkLeft");
            Graphic = _spriteMap;
            //GetDirection();
        }

        public override void Update()
        {
            base.Update();
            if (!rocketShot)
            {
                rocketShot = true;
                SoundManager.PlayRequestedSound(RandomRocket());
            }
            //X -= Global.rocketSpeed * (float)Math.Cos(angleInRadians);
            //Y -= Global.rocketSpeed * (float)Math.Sin(angleInRadians);
            HandleCollisions();
            //SeekPlayerMovement();
        }//end of update
        private string RandomRocket()
        {
            switch (Rand.Int(1, 17))//one more than the last case number (so counting the default would be an additional one)
            {
                case 1:
                    return "_rocketShot";
                case 2:
                    return "_rocketShot2";
                case 3:
                    return "_rocketShot3";
                case 4:
                    return "_rocketShot4";
                case 5:
                    return "_rocketShot5";
                case 6:
                    return "_rocketShot6";
                case 7:
                    return "_rocketShot7";
                case 8:
                    return "_rocketShot8";
                case 9:
                    return "_rocketShot9";
                case 10:
                    return "_rocketShot10";
                case 11:
                    return "_rocketShot11";
                case 12:
                    return "_rocketShot12";
                case 13:
                    return "_rocketShot13";
                case 14:
                    return "_rocketShot14";
                case 15:
                    return "_rocketShot15";
                case 16:
                    return "_rocketShot16";
                default:
                    return "_rocketShot";
            }
        }
        public void SeekPlayerMovement()
        {
            if (isSeekingTarget)
            {
                ScanAllTargets();
            }
            else if (!AmICloseEnoughToPlayer())//travel to target
            {
                X -= Global.dirtSpeed * (float)Math.Cos(angleInRadians);
                Y -= Global.dirtSpeed * (float)Math.Sin(angleInRadians);

                if (X >= Global.PlayerX)//this needs to be a range of values for where the player is actually left of. so, there should be a dead zone where the animal doesn't move!
                {
                    Shared.ChangeAnimTo("walkLeft", _spriteMap);
                    _spriteMap.FlippedX = true;
                }
                else
                {
                    Shared.ChangeAnimTo("walkRight", _spriteMap);
                    _spriteMap.FlippedX = false;
                }
            }
            else if (_isCloseEnoughToPlayer)
            {
                if (X >= Global.PlayerX)//this needs to be a range of values for where the player is actually left of. so, there should be a dead zone where the animal doesn't move!
                {
                    Shared.ChangeAnimTo("walkLeft", _spriteMap);
                    _spriteMap.FlippedX = true;
                }
                else
                {
                    Shared.ChangeAnimTo("walkRight", _spriteMap);
                    _spriteMap.FlippedX = false;
                }
            }
            if (scanAgain <= 0)
            {
                isSeekingTarget = true;
                closestItem = null;
                closestDistanceItem = 1670;
                scanAgain = ScanTimerMax;
            }
            if (scanAgain > 0)
                scanAgain--;
        }

        private void ScanAllTargets()
        {
            var anyPlayer = GetEntities<Player>();
            foreach (var item in anyPlayer)
            {
                var dist = Util.Distance(this, item);
                if (dist <= closestDistanceItem)
                {
                    closestDistanceItem = dist;
                    closestItem = item;
                }
            }
            if (closestItem != null)
            {
                isSeekingTarget = false;
                GetDirection();
            }
        }

        public bool AmICloseEnoughToPlayer()
        {
            //get the distance to closest item. if close shoot at it!
            var dist = Util.Distance(this, closestItem);
            if (dist <= 1)//hmm
            {
                _isCloseEnoughToPlayer = true;
                return true;
            }
            else
            {
                _isCloseEnoughToPlayer = false;
                return false;
            }
        }

        public void HandleCollisions()//lets try this. I hope this works. It isn't. :O
        {
            var explosion = Collider.Collide((int)X, (int)Y, Global.Type.EXPLOSION);
            if (explosion != null)
                Destroy(true);
            var alligator = Collider.Collide((int)X, (int)Y, Global.Type.ALLIGATOR);
            if (alligator != null)
            {
                if (Timer % 6 == 0)
                    SoundManager.PlayRequestedSound(RandomDirtSound(), .5f);
                Shared.ChangeAnimTo("hit", _spriteMap);
            }
            else
                Shared.ChangeAnimTo("walkRight", _spriteMap);
        }
        private string RandomDirtSound()
        {
            switch (Rand.Int(1, 6))//one more than the last
            {
                case 1:
                    return "_alligatorCreep";
                case 2:
                    return "_moveThroughDirt";
                case 3:
                    return "_moveThroughDirt2";
                case 4:
                    return "_moveThroughDirt3";
                case 5:
                    return "_moveThroughDirt4";

                default:
                    return "_alligatorCreep";
            }
        }

        public void GetDirection()
        {
            var vector1 = new Point((int)_destiny.X + 20, (int)_destiny.Y + 40);
            var vector2 = new Point((int)X, (int)Y);
            angleInRadians = Math.Atan2(vector2.Y - vector1.Y, vector2.X - vector1.X);
            var angleInFrisbees = MathHelper.ToDegrees((float)angleInRadians);
            if (angleInFrisbees < 0)
            {
                angleInFrisbees += 360;
                angleInRadians = MathHelper.ToRadians(angleInFrisbees);
            }
        }

        public void Destroy(bool launch = false)
        {
            if (launch)
            {
                var rand = Rand.Int(1, 5);
                if (rand == 4)
                    Scene.Add(new FlyingDirt(X, Y, Y + 12));
                Scene.Add(new DeadDirt(X, Y));
            }
            RemoveSelf();
        }

        public override void Render()
        {
            base.Render();
            //Collider.Render(Color.Green);
        }
    }
}
