using LOoSE_sLOTS.objects;
using LOoSE_sLOTS.Utilities;
using Otter;
using System;

namespace LOoSE_sLOTS.entities
{
    class Player : Entity
    {
        private Spritemap<string> _spriteMap;
        private bool _hMove = true;
        private bool _vMove = true;
        public static bool canPlayerCollide = true;
        public static bool isSpritemapChanged = true;
        private BasicMovement movement = new BasicMovement(400, 400, 400);//was 400,400,400
        //private float xoffset = 0;
        //private float yoffset = 20;
        private static int StuckTimerMax = 3;//was 30
        private int _stuckTimer = StuckTimerMax;
        private int speedScale = 100;//normally 100 TESTING
        private bool IsL;
        private bool IsR;
        private bool IsU;
        private bool IsD;
        private bool _isShooting;
        private double angleInRadians;
        private float _X;
        private float _Y;
        private float xoffset = 10;
        private bool CanDie = false;
        private int DeathTimer = 200;//this is set below as well...

        public Player(float x, float y)
        {
            X = x; Y = y;
            SetHitbox(20, 40, (int)Global.Type.PLAYER);
            Collider.X = -10;
            Collider.Y = -20;
            Axis axis = Axis.CreateWASD();
            movement.Axis = axis;
            movement.Collider = Collider;
            movement.AddCollision((int)Global.Type.SOLID/*, (int)Global.Type.SLOTMACHINE*/);//walls
            AddComponents(axis, movement);
            LoadCorrectSpritemap();
            _spriteMap.CenterOrigin();
            movement.Speed = Global.PlayerSpeed;
        }
        public override void UpdateFirst()//this is so that when the player moves the camera, the UI will update after it moves. (but the player will still appear below the elements. (it's an update thing)
        {
            base.UpdateFirst();
            #region Camera follows player
            if (X > Scene.HalfWidth - xoffset && X < Global.MW - Scene.HalfWidth - xoffset)//this is now universal. haha!
                Scene.CameraX = X - Scene.HalfWidth + xoffset;//this does follow the player!
            else if (X <= Scene.HalfWidth - xoffset)
                Scene.CameraX = 0;
            else if (X >= Global.MW - (Scene.HalfWidth * 2))
                Scene.CameraX = Global.MW - (Scene.HalfWidth * 2);
            if (Y > Scene.HalfHeight && Y < Global.MH - Scene.HalfHeight)
                Scene.CameraY = Y - Scene.HalfHeight;//this does follow the player!
            else if (Y <= Scene.HalfHeight)
                Scene.CameraY = 0;
            else if (Y >= Global.MH - Scene.HalfHeight * 2)
                Scene.CameraY = Global.MH - Scene.HalfHeight * 2;
            #endregion
        }
        public override void Update()
        {
            base.Update();
            var cn = Global.PlayerSession.Controller;
            Global.PlayerX = X;
            Global.PlayerY = Y;
            //Console.WriteLine("Playerhealth: {0}", Global.PlayerHealth);
            if (cn.Button("R").Pressed)
            {
                //Console.WriteLine("X: {0} Y: {1}", Scene.MouseX, Scene.MouseY);
                //Scene.Add(new Boss(Global.MW / 2, Global.MH / 2));
            }
            if (cn.Button("E").Pressed)//testing!
            {
               // Global.PlayerHealth = 0;
            }
            if (Global.PlayerSession.Controller.Button("LeftMouseClick").Pressed)
            {
                if (Global.PlayerHealth > 0)
                {
                    SoundManager.PlayRequestedSound("_click");
                    Scene.Add(new FiredCoin(X, Y, GetDirection((int)X, (int)Y, (int)Scene.MouseX, (int)Scene.MouseY)));
                    Global.PlayerHealth--;
                }
            }
            if (Global.PlayerHealth <= 0 && !CanDie)
            {
                Shared.ChangeAnimTo("death", _spriteMap);
                for (var i = 0; i < 1000; i++)
                {
                    Scene.Add(new GameCoin(X, Y + 30, Y + 40));
                }
                DeathTimer = 200;
                CanDie = true;
            }
            if (CanDie)
            {
                if (DeathTimer > 0)
                    DeathTimer--;
                if (DeathTimer <= 0)
                    Destroy();
            }
            if (isSpritemapChanged)
                LoadCorrectSpritemap();
            movement.SpeedScale = speedScale;//this is the speed? lower the faster.
            if (Global.PlayerHealth > 0)
            {
                movement.Freeze = false;
                PressKeysForAnimation(cn, "walkLeft", "walkRight", "walkUp", "walkDown");

                #region Hmovement or Vmovement
                if (cn.Button("A").Down)//LEFT
                    _hMove = true;
                else if (cn.Button("D").Down)//RIGHT
                    _hMove = true;
                else
                    _hMove = false;
                if (cn.Button("W").Down)//UP
                    _vMove = true;
                else if (cn.Button("S").Down)//DOWN
                    _vMove = true;
                else
                    _vMove = false;
                #endregion

                StopWalkingAnimations();
                //collisions:
                var coin = Collider.Collide(X, Y, (int)Global.Type.COIN);
                if (coin != null)
                {
                    GameCoin gc = (GameCoin)coin.Entity;
                    Global.PlayerHealth++;
                    gc.Destroy();
                }
            }
            else
                movement.Freeze = true;
        }//end of update
        /*public static IEnumerator GotGun()
        {
            SoundManager.PlayRequestedSound("_aaaa");
            yield return Coroutine.Instance.WaitForFrames(170);
            SoundManager.PlayRequestedSound("_manwhatwas");
        }*/

        public void LoadCorrectSpritemap()
        {
            isSpritemapChanged = false;
            if (_spriteMap != null)
                _spriteMap.Clear();
            //if no other spritemaps are needed, this will work fine.
            _spriteMap = null;
            _spriteMap = new Spritemap<string>(Assets.PLAYER, 50, 50);
            AddNewSprites();
            /* if (!Global.doesPlayerHaveWagon)
             {
                 _spriteMap = null;
                 _spriteMap = new Spritemap<string>(Assets.PLAYER, 45, 50);
                 AddNewSprites();
             }
             else if (Global.doesPlayerHaveWagon)
             {
                 _spriteMap = null;
                 _spriteMap = new Spritemap<string>(Assets.PLAYERPULLSWAGON, 45, 50);
                 AddPlayerWagonSprites();
             }*/
            _spriteMap.Update();
            _spriteMap.CenterOrigin();
            _spriteMap.Play("standDown");
            _spriteMap.FlippedX = false;
            Graphic = _spriteMap;
        }

        #region AddSprites
        public void AddNewSprites()
        {
            var hMs = 6f;//horizontal animation speed
            var vMs = 6f;//vertical animation speed
            _spriteMap.Add("standRight", new int[] { 0 }, new float[] { hMs, hMs });
            _spriteMap.Add("standLeft", new int[] { 0 }, new float[] { hMs, hMs });
            _spriteMap.Add("standUp", new int[] { 0 }, new float[] { hMs, hMs });
            _spriteMap.Add("standDown", new int[] { 0 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkRight", new int[] { 1, 2, 3, 4 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkLeft", new int[] { 1, 2, 3, 4 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkUp", new int[] { 1, 2, 3, 4 }, new float[] { vMs, vMs });
            _spriteMap.Add("walkDown", new int[] { 1, 2, 3, 4 }, new float[] { vMs, vMs });
            _spriteMap.Add("shootRight", new int[] { 5 }, new float[] { hMs, hMs });
            _spriteMap.Add("shootLeft", new int[] { 5 }, new float[] { hMs, hMs });
            _spriteMap.Add("shootUp", new int[] { 7 }, new float[] { hMs, hMs });
            _spriteMap.Add("shootDown", new int[] { 9 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkShootRight", new int[] { 5, 6 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkShootLeft", new int[] { 5, 6 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkShootUp", new int[] { 7, 8 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkShootDown", new int[] { 9, 10 }, new float[] { hMs, hMs });

            _spriteMap.Add("death", new int[] { 5 }, new float[] { 16, 16 });
        }
        #endregion

        public void PressKeysForAnimation(Controller cn, string l, string r, string u, string d)
        {
            if (_isShooting)
                movement.Freeze = true;
            else
                movement.Freeze = false;
            #region pressed Keys for animation
            if (cn.Button("A").Pressed)//LEFT
            {
                Shared.ChangeAnimTo(l, _spriteMap);
                _spriteMap.FlippedX = true;
                IsL = true; IsR = false; IsU = false; IsD = false;
            }
            else if (cn.Button("D").Pressed)//RIGHT
            {
                Shared.ChangeAnimTo(r, _spriteMap);
                _spriteMap.FlippedX = false;
                IsL = false; IsR = true; IsU = false; IsD = false;
            }
            else if (cn.Button("W").Pressed)//UP
            {
                Shared.ChangeAnimTo(u, _spriteMap);
                _spriteMap.FlippedX = true;
                IsL = false; IsR = false; IsU = true; IsD = false;
            }
            else if (cn.Button("S").Pressed)//DOWN
            {
                Shared.ChangeAnimTo(d, _spriteMap);
                _spriteMap.FlippedX = false;
                IsL = false; IsR = false; IsU = false; IsD = true;
            }

            #endregion
            #region released keys for animation
            if (cn.Button("A").Released)//if i release left, updownright
            {
                if (cn.Button("W").Down)//and i'm holding up
                {
                    Shared.ChangeAnimTo(u, _spriteMap);
                    _spriteMap.FlippedX = true;
                }
                else if (cn.Button("S").Down)//and i'm holding down
                {
                    Shared.ChangeAnimTo(d, _spriteMap);
                    _spriteMap.FlippedX = false;
                }
                else if (cn.Button("D").Down)//and i'm holding right
                {
                    Shared.ChangeAnimTo(r, _spriteMap);
                    _spriteMap.FlippedX = false;
                }
            }
            else if (cn.Button("D").Released)//if i release right, updownleft
            {
                if (cn.Button("W").Down)//and i'm holding up
                {
                    Shared.ChangeAnimTo(u, _spriteMap);
                    _spriteMap.FlippedX = true;
                }
                else if (cn.Button("S").Down)//and i'm holding down
                {
                    Shared.ChangeAnimTo(d, _spriteMap);
                    _spriteMap.FlippedX = false;
                }
                else if (cn.Button("A").Down)//and i'm holding left
                {
                    Shared.ChangeAnimTo(l, _spriteMap);
                    _spriteMap.FlippedX = true;
                }
            }
            else if (cn.Button("W").Released)//if i release up, rightleftdown
            {
                if (cn.Button("D").Down)//and i'm holding right
                {
                    Shared.ChangeAnimTo(r, _spriteMap);
                    _spriteMap.FlippedX = false;
                }
                else if (cn.Button("A").Down)//and i'm holding left
                {
                    Shared.ChangeAnimTo(l, _spriteMap);
                    _spriteMap.FlippedX = true;
                }
                else if (cn.Button("S").Down)//and i'm holding down
                {
                    Shared.ChangeAnimTo(d, _spriteMap);
                    _spriteMap.FlippedX = false;
                }
            }
            else if (cn.Button("S").Released)//if i release down, rightleftup
            {
                if (cn.Button("D").Down)//and i'm holding right
                {
                    Shared.ChangeAnimTo(r, _spriteMap);
                    _spriteMap.FlippedX = false;
                }
                else if (cn.Button("A").Down)//and i'm holding left
                {
                    Shared.ChangeAnimTo(l, _spriteMap);
                    _spriteMap.FlippedX = true;
                }
                else if (cn.Button("W").Down)//and i'm holding up
                {
                    Shared.ChangeAnimTo(u, _spriteMap);
                    _spriteMap.FlippedX = true;
                }
            }
            #endregion
        }

        public void StopWalkingAnimations()
        {
            if (!_hMove && !_vMove)
            {
                switch (_spriteMap.CurrentAnim)
                {
                    case ("walkLeft"):
                        _spriteMap.Play("standLeft");
                        _spriteMap.FlippedX = true;
                        break;
                    case ("walkRight"):
                        _spriteMap.Play("standRight");
                        _spriteMap.FlippedX = false;
                        break;
                    case ("walkUp"):
                        _spriteMap.Play("standUp");
                        _spriteMap.FlippedX = true;
                        break;
                    case ("walkDown"):
                        _spriteMap.Play("standDown");
                        _spriteMap.FlippedX = false;
                        break;
                    case ("walkShootLeft"):
                        _spriteMap.Play("shootLeft");
                        _spriteMap.FlippedX = true;
                        break;
                    case ("walkShootRight"):
                        _spriteMap.Play("shootRight");
                        _spriteMap.FlippedX = false;
                        break;
                    case ("walkShootUp"):
                        _spriteMap.Play("shootUp");
                        _spriteMap.FlippedX = false;
                        break;
                    case ("walkShootDown"):
                        _spriteMap.Play("shootDown");
                        _spriteMap.FlippedX = false;
                        break;
                    default:
                        break;
                }
            }
        }

        public double GetDirection(int destX, int destY, int sourceX, int sourceY)
        {
            var vector1 = new Point(sourceX, sourceY);
            var vector2 = new Point(destX, destY);
            var angleInFrisbees = MathHelper.ToDegrees((float)angleInRadians);
            angleInRadians = Math.Atan2(vector2.Y - vector1.Y, vector2.X - vector1.X);
            if (angleInFrisbees < 0)
            {
                angleInFrisbees += 360;
                angleInRadians = MathHelper.ToRadians(angleInFrisbees);
            }
            return angleInRadians;
        }

        /*private void GetVelocity(double originalAngle)//these speeds are not variable enough. :/
        {
            var angle = (int)MathHelper.ToDegrees((float)originalAngle);
            //Console.WriteLine("angle: {0}", angle);
            _X = _grappleDragSpeed * (float)Math.Cos(originalAngle);
            _Y = _grappleDragSpeed * (float)Math.Sin(originalAngle);
            velocity = new Vector2(_X, _Y);
        }*/

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

        public void Destroy()
        {
            CanDie = false;
            RemoveSelf();
            Global.GAME.RemoveScene();
            Global.GAME.AddScene(new LoseScreen());
        }
    }
}

