using Otter;
using Puppyups.entities;
using Puppyups.Utilities;
using System;

namespace Puppyups.objects
{
    class Grapple2 : Entity
    {
        private Spritemap<string> _spriteMap;
        private BasicMovement movement = new BasicMovement(1600, 1600, 1600);
        private Button button = new Button();
        private float _sourceX;
        private float _sourceY;
        private float speed = 3f;
        private double angleInRadians;
        private double reverseAngleInRadians;
        public bool SpawnChain = true;
        private bool onlyGetOne = true;
        private bool gotDog;
        private bool gotSmog;
        private bool gotWall;
        private bool first;
        private Vector2 velocity;

        public Grapple2(float x, float y, float sourceX, float sourceY)
        {
            X = x; Y = y; _sourceX = sourceX; _sourceY = sourceY;
            SetHitbox(8, 8, (int)Global.Type.GRAPPLE2);
            Collider.X = -4;
            Collider.Y = -4;
            _spriteMap = new Spritemap<string>(Assets.GRAPPLE, 10, 10);
            _spriteMap.Add("main", new int[] { 0, 1, 2, 3 }, new float[] { 10f, 10f });
            _spriteMap.Play("main");
            _spriteMap.CenterOrigin();
            Graphic = _spriteMap;

            //normal walk
            Axis axis = new Axis();
            movement.Axis = axis;
            movement.Axis.AddKeys(Key.P, Key.O, Key.I, Key.U);
            movement.Collider = Collider;
            movement.SpeedScale = 100;//100 is normal speed
            movement.AddCollision((int)Global.Type.SOLID, (int)Global.Type.DOG);
            movement.Axis.Locked = true;
            AddComponents(axis, movement, button);
            SoundManager.PlayRequestedSound("_grapple2");
            GetDirection();
        }
        public override void Update()
        {
            base.Update();
            if (first)
            {
                first = false;
                var wall = Collider.Collide(X, Y, (int)Global.Type.SOLID);
                if (wall != null)
                {
                    Destroy();
                    Player2Aimer.IsActive = false;
                }

            }
            if (!gotDog && !gotWall && !gotSmog)
            {
                GetVelocity(angleInRadians);
                movement.Axis.ForceState(velocity);
            }
            else if (gotDog || gotSmog)
            {
                GetRealDirection((int)Global.Player2X, (int)Global.Player2Y-10, (int)X, (int)Y);
                GetVelocity(angleInRadians);
                movement.Axis.ForceState(velocity);
                var pl = Collider.Collide(X, Y, Global.Type.PLAYER2);
                if (pl != null)
                {
                    Player2Aimer.IsActive = false;
                    Destroy();
                }
            }
            if (gotWall)
            {
                movement.Freeze = true;
            }
            if (SpawnChain)
            {
                SpawnChain = false;
                Scene.Add(new Chain(X, Y, null, this));
            }

            var wallu = Collider.Collide(X, Y - 1, (int)Global.Type.SOLID);
            var walll = Collider.Collide(X - 1, Y, (int)Global.Type.SOLID);
            var wallr = Collider.Collide(X + 1, Y, (int)Global.Type.SOLID);
            var walld = Collider.Collide(X, Y + 1, (int)Global.Type.SOLID);
            var dogu = Collider.Collide(X, Y - 1, (int)Global.Type.DOG);
            var dogd = Collider.Collide(X, Y + 1, (int)Global.Type.DOG);
            var dogl = Collider.Collide(X - 1, Y, (int)Global.Type.DOG);
            var dogr = Collider.Collide(X + 1, Y, (int)Global.Type.DOG);
            var smogu = Collider.Collide(X, Y - 1, (int)Global.Type.SMOGMONSTER);
            var smogd = Collider.Collide(X, Y + 1, (int)Global.Type.SMOGMONSTER);
            var smogl = Collider.Collide(X - 1, Y, (int)Global.Type.SMOGMONSTER);
            var smogr = Collider.Collide(X + 1, Y, (int)Global.Type.SMOGMONSTER);
            if ((wallu != null || walld != null || walll != null || wallr != null) && onlyGetOne)
            {
                onlyGetOne = false;
                gotWall = true;
                Player2.Pulled = true;
                Player2.OneTimeGrappleAngle = true;
                Global.Grapple2X = X;
                Global.Grapple2Y = Y;
                SoundManager.PlayRequestedSound("_pull2");
            }
            if ((dogu != null || dogd != null || dogl != null || dogr != null) && onlyGetOne)
            {
                onlyGetOne = false;
                gotDog = true;
                //hit the dog, reverse direction. Pull the dog with you back to the Player2, deleting each chain as you run into them.
                if (dogu != null)
                {
                    Dog d = (Dog)dogu.Entity;
                    d.Pulled = true;
                    d.friendlyGrapple2 = this;
                }
                else if (dogd != null)
                {
                    Dog d = (Dog)dogd.Entity;
                    d.Pulled = true;
                    d.friendlyGrapple2 = this;
                }
                else if (dogl != null)
                {
                    Dog d = (Dog)dogl.Entity;
                    d.Pulled = true;
                    d.friendlyGrapple2 = this;
                }
                else if (dogr != null)
                {
                    Dog d = (Dog)dogr.Entity;
                    d.Pulled = true;
                    d.friendlyGrapple2 = this;
                }
            }
            if ((smogu != null || smogd != null || smogl != null || smogr != null) && onlyGetOne)
            {
                onlyGetOne = false;
                gotSmog = true;
                //hit the dog, reverse direction. Pull the dog with you back to the player, deleting each chain as you run into them.
                if (smogu != null)
                {
                    SmogMonster d = (SmogMonster)smogu.Entity;
                    d.Pulled = true;
                    d.friendlyGrapple2 = this;
                }
                else if (smogd != null)
                {
                    SmogMonster d = (SmogMonster)smogd.Entity;
                    d.Pulled = true;
                    d.friendlyGrapple2 = this;
                }
                else if (smogl != null)
                {
                    SmogMonster d = (SmogMonster)smogl.Entity;
                    d.Pulled = true;
                    d.friendlyGrapple2 = this;
                }
                else if (smogr != null)
                {
                    SmogMonster d = (SmogMonster)smogr.Entity;
                    d.Pulled = true;
                    d.friendlyGrapple2 = this;
                }
            }
            if (X > Global.MW || X < 0)
                RemoveSelf();
        }//end of update
        public void GetDirection()
        {
            var vector1 = new Point((int)_sourceX, (int)_sourceY);
            var vector2 = new Point((int)X, (int)Y);
            angleInRadians = Math.Atan2(vector2.Y - vector1.Y, vector2.X - vector1.X);
            reverseAngleInRadians = angleInRadians + Math.PI;
            var angleInFrisbees = MathHelper.ToDegrees((float)angleInRadians);
            if (angleInFrisbees < 0)
            {
                angleInFrisbees += 360;
                angleInRadians = MathHelper.ToRadians(angleInFrisbees);
                reverseAngleInRadians = angleInRadians + Math.PI;
            }
        }

        public void GetRealDirection(int destX, int destY, int sourceX, int sourceY)
        {
            var vector1 = new Point(sourceX, sourceY);
            var vector2 = new Point(destX, destY);
            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);
            }
        }

        private void GetVelocity(double originalAngle)//these speeds are not variable enough. :/
        {
            float _X = 0; float _Y = 0;
            _X = speed * (float)Math.Cos(originalAngle);
            _Y = speed * (float)Math.Sin(originalAngle);
            velocity = new Vector2(_X, _Y);
        }

        public void Destroy()
        {
            RemoveSelf();
        }

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