using Otter;
using System;
using System.Collections.Generic;

namespace SuperRefluxPowergridDefense_.entities
{
    class ScaryGirl : 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;

        public ScaryGirl(float x, float y)
        {
            X = x; Y = y;
            SetHitbox(10, 20, (int)Global.Type.SCARYGIRL);
            Collider.X = -5;
            Collider.Y = -13;
            _spriteMap = new Spritemap<string>(Assets.SCARYGIRL, 46, 56);
            _spriteMap.Add("walk", new int[] { 0, 1, 2, 3 }, new float[] { 5f, 5f });
            _spriteMap.Add("attack", new int[] { 4, 5 }, new float[] { 15f, 15f });
            _spriteMap.Play("walk");
            _spriteMap.CenterOrigin();
            Graphic = _spriteMap;
        }

        public override void Update()
        {
            base.Update();
            scaryGirlX = X; scaryGirlY = Y;
            //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 * (float)Math.Sin(angleInRadians);
                    ChangeAnimTo("walk");
                    one = true;
                }
            }
            else if (!AmCollidingWithAnything())//travel to target
            {
                X -= Global.scaryGirlSpeed * (float)Math.Cos(angleInRadians);
                Y -= Global.scaryGirlSpeed * (float)Math.Sin(angleInRadians);
                ChangeAnimTo("walk");
                one = true;
            }
            else if (isHittingTarget)
            {
                if (one || hitTimer <= 0)
                {
                    hitTimer = 50;
                    one = false;
                    SoundManager.PlayRequestedSound("_scaryGirlHit", .5f);
                }
                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(Otter.Rand.Float(0f, 359f));
                    firstTimer = 100;
                }
            }
        }

        public void ScanAllTargets()
        {
            var anyTeslas = GetEntities<Tesla>();
            foreach (var item in anyTeslas)
            {
                var dist = Util.Distance(this, item);
                if (dist <= closestDistanceItem)
                {
                    closestDistanceItem = dist;
                    closestItem = item;
                }
            }

            var anyPlayer = GetEntities<Player>();
            foreach (var item in anyPlayer)
            {
                var dist = Util.Distance(this, item);
                if (dist <= closestDistanceItem)
                {
                    closestDistanceItem = dist;
                    closestItem = item;
                }
            }

            var anyGenerator = GetEntities<Generator>();
            foreach (var item in anyGenerator)
            {
                var dist = Util.Distance(this, item);
                if (dist <= closestDistanceItem)
                {
                    closestDistanceItem = dist;
                    closestItem = item;
                }
            }
            var anyFuel = GetEntities<Fuel>();
            foreach (var item in anyFuel)
            {
                var dist = Util.Distance(this, item);
                if (dist <= closestDistanceItem)
                {
                    closestDistanceItem = dist;
                    closestItem = item;
                }
            }
            var anyGrid = GetEntities<Grid>();
            foreach (var item in anyGrid)
            {
                var dist = Util.Distance(this, item);
                if (dist <= closestDistanceItem)
                {
                    closestDistanceItem = dist;
                    closestItem = item;
                }
            }
            if (closestItem != null)
            {
                isSeekingTarget = false;
                GetDirection();
            }
            var anyWallDown = GetEntities<WallDown>();
            foreach (var item in anyWallDown)
            {
                var dist = Util.Distance(this, item);
                if (dist <= closestDistanceItem)
                {
                    closestDistanceItem = dist;
                    closestItem = item;
                }
            }
            if (closestItem != null)
            {
                isSeekingTarget = false;
                GetDirection();
            }
            var anyWallUp = GetEntities<WallUp>();
            foreach (var item in anyWallUp)
            {
                var dist = Util.Distance(this, item);
                if (dist <= closestDistanceItem)
                {
                    closestDistanceItem = dist;
                    closestItem = item;
                }
            }
            if (closestItem != null)
            {
                isSeekingTarget = false;
                GetDirection();
            }
            var anyWallLeft = GetEntities<WallLeft>();
            foreach (var item in anyWallLeft)
            {
                var dist = Util.Distance(this, item);
                if (dist <= closestDistanceItem)
                {
                    closestDistanceItem = dist;
                    closestItem = item;
                }
            }
            if (closestItem != null)
            {
                isSeekingTarget = false;
                GetDirection();
            }
            var anyWallRight = GetEntities<WallRight>();
            foreach (var item in anyWallRight)
            {
                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.SCARYGIRL);
            if (scaryGirl != null)
                return true;
            else
                return false;
        }

        public bool AmICollidingWithWalls()
        {
            var wallup = Collider.Collide(X, Y, (int)Global.Type.WALLUP);
            var wallright = Collider.Collide(X, Y, (int)Global.Type.WALLRIGHT);
            var wallleft = Collider.Collide(X, Y, (int)Global.Type.WALLLEFT);
            var walldown = Collider.Collide(X, Y, (int)Global.Type.WALLDOWN);
            if (wallup != null || wallright != null || wallup != null || wallright != null)
                return true;
            else
                return false;
        }

        public bool AmCollidingWithAnything()
        {
            var colt = Collider.Collide((int)X, (int)Y, Global.Type.TESLA);
            var colp = Collider.Collide((int)X, (int)Y, Global.Type.PLAYER);
            var colg = Collider.Collide((int)X, (int)Y, Global.Type.GENERATOR);
            var colf = Collider.Collide((int)X, (int)Y, Global.Type.FUEL);
            var colgr = Collider.Collide((int)X, (int)Y, Global.Type.GRID);
            var colsm = Collider.Collide((int)X, (int)Y, Global.Type.TESLASPEEDMACHINE);
            var coldown = Collider.Collide((int)X, (int)Y, Global.Type.WALLDOWN);
            var colup = Collider.Collide((int)X, (int)Y, Global.Type.WALLUP);
            var colleft = Collider.Collide((int)X, (int)Y, Global.Type.WALLLEFT);
            var colright = Collider.Collide((int)X, (int)Y, Global.Type.WALLRIGHT);
            if (colt != null || colp != null || colg != null || colf != null || colgr != null
                || colsm != null || coldown != null || colup != null || colleft != null
                 || colright != null)
            {
                isHittingTarget = true;
                return true;
            }
            else
            {
                isHittingTarget = false;
                return false;
            }
        }

        public void HandleCollisions()//lets try this. I hope this works.
        {
            var colt = Collider.Collide((int)X, (int)Y, Global.Type.TESLA);
            if (colt != null)
            {
                Tesla t = (Tesla)colt.Entity;
                t.TeslaHealth--;
                if (t.TeslaHealth <= 0)
                    t.Destroy();
                //play destruction sound here;
            }

            var colp = Collider.Collide((int)X, (int)Y, Global.Type.PLAYER);
            if (colp != null)
            {
                Global.PlayerHealth--;
                SoundManager.PlayRequestedSound("_playerHurt");
            }

            var colg = Collider.Collide((int)X, (int)Y, Global.Type.GENERATOR);
            if (colg != null)
            {
                Generator t = (Generator)colg.Entity;
                t.GeneratorHealth--;
                if (t.GeneratorHealth <= 0)
                    t.Destroy();
                //play destruction sound here;
            }

            var colf = Collider.Collide((int)X, (int)Y, Global.Type.FUEL);
            if (colf != null)
            {
                Fuel t = (Fuel)colf.Entity;
                t.FuelHealth--;
                if (t.FuelHealth <= 0)
                    t.Destroy();
                //play destruction sound here;
            }

            var colgr = Collider.Collide((int)X, (int)Y, Global.Type.GRID);
            if (colgr != null)
            {
                Grid t = (Grid)colgr.Entity;
                t.GridHealth--;
                if (t.GridHealth <= 0)
                    t.Destroy();
                //play destruction sound here;
            }

            var colsm = Collider.Collide((int)X, (int)Y, Global.Type.TESLASPEEDMACHINE);
            if (colsm != null)
            {
                TeslaSpeedMachine t = (TeslaSpeedMachine)colsm.Entity;
                t.TeslaSpeedMachineHealth--;
                if (t.TeslaSpeedMachineHealth <= 0)
                    t.Destroy();
                //play destruction sound here;
            }

            var colwd = Collider.Collide((int)X, (int)Y, Global.Type.WALLDOWN);
            if (colwd != null)
            {
                WallDown t = (WallDown)colwd.Entity;
                t.WallHealth--;
                if (t.WallHealth <= 0)
                    t.Destroy();
                //play destruction sound here;
            }

            var colup = Collider.Collide((int)X, (int)Y, Global.Type.WALLUP);
            if (colup != null)
            {
                WallUp t = (WallUp)colup.Entity;
                t.WallHealth--;
                if (t.WallHealth <= 0)
                    t.Destroy();
                //play destruction sound here;
            }

            var colleft = Collider.Collide((int)X, (int)Y, Global.Type.WALLLEFT);
            if (colleft != null)
            {
                WallLeft t = (WallLeft)colleft.Entity;
                t.WallHealth--;
                if (t.WallHealth <= 0)
                    t.Destroy();
                //play destruction sound here;
            }

            var colright = Collider.Collide((int)X, (int)Y, Global.Type.WALLRIGHT);
            if (colright != null)
            {
                WallRight t = (WallRight)colright.Entity;
                t.WallHealth--;
                if (t.WallHealth <= 0)
                    t.Destroy();
                //play destruction sound here;
            }
        }

        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()
        {//either that or randomly teleport it to a crazy distance. <-- probably this one for this game mode.
            Scene.Add(new Fuel(X, Y));
            Scene.Add(new PlayerDeath(X, Y));
            RemoveSelf();
        }
    }
}

