using Otter;
using PpbbffttMiningHa.entities.Bosses;
using PpbbffttMiningHa.objects;
using PpbbffttMiningHa.Utility;
using System;

namespace PpbbffttMiningHa.entities
{
    class PrairieDog : Entity
    {
        private Spritemap<string> _spriteMap;
        private bool isSeekingTarget = true;
        private float closestDistanceItem = 1650f;
        private Entity closestItem;
        private double angleInRadians = 1;//this is about 57 degrees. ;-)
        private bool isHittingTarget = false;
        private int scanAgain = 100;
        private float scaryGirlX = 0;
        private float scaryGirlY = 0;
        private int firstTimer = 10;
        private int hitTimer = 50;
        private Collider scaryGirl;
        private bool one = true;
        private bool isDead;
        private bool isAllowedToDie = false;
        private int endGameTimer = 400;

        public PrairieDog(float x, float y)
        {
            X = x; Y = y;
            SetHitbox(50, 50, (int)Global.Type.PRAIRIEDOG);
            Collider.X = -20;
            Collider.Y = -20;
            _spriteMap = new Spritemap<string>(Assets.PRAIRIEDOG, 100, 100);
            _spriteMap.Add("walk", new int[] { 0 }, new float[] { 5f, 5f });
            _spriteMap.Add("attack", new int[] { 1, 0 }, new float[] { 15f, 15f });
            _spriteMap.Add("dead", new int[] { 2 }, new float[] { 15f, 15f });
            _spriteMap.Play("walk");
            _spriteMap.CenterOrigin();
            Graphic = _spriteMap;
        }

        public override void Update()
        {
            base.Update();
            scaryGirlX = X; scaryGirlY = Y;
            if (isAllowedToDie)
            {
                if (isDead && endGameTimer > 0)
                    endGameTimer--;
                if (isDead && endGameTimer <= 0)
                    Destroy();
            }
            else
            {
                //scan closest enemy entity (anything!)
                if (isSeekingTarget)
                {
                    ScanAllTargets();
                }
                else if (AmICollidingWithMyFriends())//if colliding with myself, move away.
                {
                    if (!AmICollidingWithWalls())
                    {
                        var speed = .5f;
                        X -= speed * (float)Math.Cos(angleInRadians);
                        Y -= speed / 2 * (float)Math.Sin(angleInRadians);
                        ChangeAnimTo("walk");
                        one = true;
                    }
                }
                else if (!AmCollidingWithAnything())//travel to target
                {
                    X -= Global.PrairieDogSpeed * (float)Math.Cos(angleInRadians);
                    Y -= Global.PrairieDogSpeed / 2 * (float)Math.Sin(angleInRadians);
                    ChangeAnimTo("walk");
                    one = true;
                }
                else if (isHittingTarget)
                {
                    if (one || hitTimer <= 0)
                    {
                        hitTimer = 50;
                        one = false;
                        //SoundManager.PlayRequestedSound("_bossHurt");Add later.
                    }
                    ChangeAnimTo("attack");
                    HandleCollisions();
                    hitTimer--;
                }
                if (scanAgain <= 0)
                {
                    isSeekingTarget = true;
                    closestItem = null;
                    closestDistanceItem = 1670;
                    scanAgain = 100;
                }
                if (scanAgain > 0)
                    scanAgain--;
                //collide with yourself technology
                if (firstTimer > 0)
                    firstTimer--;
                if (firstTimer <= 0)
                {
                    if (scaryGirl != null)//you are still colliding with another girl. get a new angle.
                    {
                        angleInRadians = GetAngle(Rand.Float(0f, 359f));
                        firstTimer = 100;
                    }
                }
                if (Global.PrairieDogHealth <= 0 && !isDead)
                {
                    isDead = true;
                    Global.Score += 2000;
                    SoundManager.PlayRequestedSound("_praireDogYip2");
                    Shared.ChangeAnimTo("dead", _spriteMap);
                    for (var j = 0; j < 40; j++)
                    {
                        Scene.Add(new DeadPrairieDog(X, Y, Y + 12));
                    }
                    for (var i = 0; i < 150; i++)
                    {
                        Scene.Add(new Gem(X, Y, Y + 12));
                    }
                    Scene.Add(new DoorKey(X, Y, Y + 12));
                    endGameTimer = 400;
                    isAllowedToDie = true;
                }
                if (!isHittingTarget)
                {
                    if (Global.PlayerX <= X)
                        _spriteMap.FlippedX = true;
                    else
                        _spriteMap.FlippedX = false;
                }
            }
        }//end of update

        public 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 void GetDirection()
        {
            var vector1 = new Point((int)closestItem.X, (int)closestItem.Y);
            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 double GetAngle(float angle)
        {
            return MathHelper.ToRadians(angle);
        }

        public bool AmICollidingWithMyFriends()
        {
            scaryGirl = Collider.Collide(X, Y, (int)Global.Type.PRAIRIEDOG);
            if (scaryGirl != null)
                return true;
            else
                return false;
        }

        public bool AmICollidingWithWalls()
        {
            var wallup = Collider.Collide(X, Y - 1, (int)Global.Type.SOLID);
            var wallright = Collider.Collide(X + 1, Y, (int)Global.Type.SOLID);
            var wallleft = Collider.Collide(X - 1, Y, (int)Global.Type.SOLID);
            var walldown = Collider.Collide(X, Y + 1, (int)Global.Type.SOLID);
            var Bdown = Collider.Collide(X, Y + 1, (int)Global.Type.BOTTOMROCK);
            if (wallup != null || wallright != null || wallup != null || wallright != null || Bdown != null)
                return true;
            else
                return false;
        }

        public bool AmCollidingWithAnything()
        {
            var colp = Collider.Collide((int)X, (int)Y, Global.Type.PLAYER);
            if (colp != null)
            {
                isHittingTarget = true;
                return true;
            }
            else
            {
                isHittingTarget = false;
                return false;
            }
        }

        public void HandleCollisions()//lets try this. I hope this works.
        {
            var colp = Collider.Collide((int)X, (int)Y, Global.Type.PLAYER);
            if (colp != null)
            {
                Global.PlayerHealth--;
                SoundManager.PlayRequestedSound(RandomOwSound());
            }
        }

        private string RandomOwSound()
        {
            switch (Rand.Int(1, 7))//one more than the last
            {
                case 1:
                    return "_ancientHurt";
                case 2:
                    return "_ancientHurt2";
                case 3:
                    return "_ancientHurt3";
                case 4:
                    return "_ancientHurt4";
                case 5:
                    return "_ancientHurt5";
                case 6:
                    return "_ancientHurt6";

                default:
                    return "_ancientHurt";
            }
        }

        public void ChangeAnimTo(string desiredAnimation)
        {
            if (_spriteMap.CurrentAnim != desiredAnimation)
                _spriteMap.Play(desiredAnimation);
        }

        public override void Render()//mainly for testing colliders :D
        {
            base.Render();
            //Collider.Render();
        }

        public void Destroy()
        {
            isAllowedToDie = false;
            RemoveSelf();
            //Global.GAME.RemoveScene();
            //Global.GAME.AddScene(new WinScreen());
            //add the key here. just pick it up and use it to unlock the door. :-)
        }
    }
}


