using System;
using KellysMarvelousAdventure.Scenes;
using KellysMarvelousAdventure.Utilities;
using Otter;

namespace KellysMarvelousAdventure.entities
{
    public 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 = 100;

        public Player(float x, float y)
        {
            X = x; Y = y;
            SetHitbox(10, 30, (int)Global.Type.PLAYER);
            Collider.X = -7;
            Collider.Y = -13;
            Axis axis = Axis.CreateWASD();
            movement.Axis = axis;
            movement.Collider = Collider;
            movement.AddCollision((int)Global.Type.SOLID);//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();
            #region override edges
            if (X < 4)
                X = 4;
            if (X > Global.MW-4)
                X = Global.MW-4;
            if (Y < 4)
                Y = 4;
            if (Y > Global.MH-4)
                Y = Global.MH-4;
            #endregion
            var cn = Global.PlayerSession.Controller;
            Global.PlayerX = X;
            Global.PlayerY = Y;
            if (isSpritemapChanged)
                LoadCorrectSpritemap();
            //Console.WriteLine("currentAnim: {0}", _spriteMap.CurrentAnim);
            //Console.WriteLine("currentFrame: {0}", _spriteMap.CurrentFrame);
            //Console.WriteLine("currentFrameIndex: {0}", _spriteMap.CurrentFrameIndex);
            if (cn.Button("R").Down)//testing!
            {
                //Console.WriteLine("x: {0} y: {1}", X, Y);
            }
            if (cn.Button("E").Pressed)//testing!
            {
                //Global.PlayerHealth = 0;
                //Global.NumberOfShips = 0;
            }

            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();
            #region collisions
            var stair = Collider.Collide((int)X, (int)Y, (int)Global.Type.STAIRS);
            if (stair != null)
            {
                var isInsideFarmHouse = Global.GAME.GetScene<InsideFarmHouse>();
                if (cn.Button("LeftMouseClick").Pressed && isInsideFarmHouse != null)//i'm in the farmhouse
                {
                    Global.GAME.RemoveScene();
                    Global.GAME.AddScene(new Bedroom("InsideFarmhouse"));
                }
                else if (cn.Button("LeftMouseClick").Pressed)//i am in the farmhouse
                {
                    Global.GAME.RemoveScene();
                    Global.GAME.AddScene(new InsideFarmHouse("Bedroom"));
                }
            }
            var door = Collider.Collide((int)X, (int)Y, (int)Global.Type.DOOR);
            if (door != null)
            {
                if (cn.Button("LeftMouseClick").Pressed)
                {
                    SoundManager.PlayRequestedSound("_doorOpen");
                    Global.GAME.RemoveScene();
                    Global.GAME.AddScene(new InsideFarmHouse("Outside"));
                }
            }
            var insideDoor = Collider.Collide((int)X, (int)Y, (int)Global.Type.INSIDEDOOR);
            if (insideDoor != null)
            {
                if (cn.Button("LeftMouseClick").Pressed)
                {
                    SoundManager.PlayRequestedSound("_doorOpen");
                    Global.GAME.RemoveScene();
                    Global.GAME.AddScene(new Outside());
                }
            }
            var oldMan = Collider.Collide((int)X, (int)Y, (int)Global.Type.OLDMAN);
            if (oldMan != null)
            {
                var isInsideFarmHouse = Global.GAME.GetScene<InsideFarmHouse>();
                if (cn.Button("LeftMouseClick").Pressed && isInsideFarmHouse != null && !Global.doesPlayerHaveWagon)
                {
                    SoundManager.PlayRequestedSound("_girlHowIsThisGoinaHelpMe");
                    Global.doesPlayerHaveWagon = true;
                    isSpritemapChanged = true;
                }
            }
            #endregion
            if (Global.PlayerHealth <= 0)
            {
                SoundManager.PlayRequestedSound("_girlDeath");
                //load the level
                Global.GAME.RemoveScene();
                Global.GAME.AddScene(new LoseScreen());
                RemoveSelf();
            }
        }//end update

        public void StopWalkingAnimations()
        {
            if (!_hMove && !_vMove)
            {
                switch (_spriteMap.CurrentAnim)
                {
                    case ("walkLeft"):
                        _spriteMap.Play("standLeft");
                        break;
                    case ("walkRight"):
                        _spriteMap.Play("standRight");
                        break;
                    case ("walkUp"):
                        _spriteMap.Play("standUp");
                        break;
                    case ("walkDown"):
                        _spriteMap.Play("standDown");
                        break;
                    default:
                        break;
                }
            }
        }
        public void ChangeAnimTo(string desiredAnimation)
        {
            if (_spriteMap.CurrentAnim != desiredAnimation)
                _spriteMap.Play(desiredAnimation);
        }
        public void LoadCorrectSpritemap()
        {
            isSpritemapChanged = false;
            if (_spriteMap != null)
                _spriteMap.Clear();
            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");
            Graphic = _spriteMap;
        }

        #region AddSprites
        public void AddNewSprites()
        {
            var hMs = 5f;//horizontal animation speed
            var vMs = 5f;//vertical animation speed
            _spriteMap.Add("standRight", new int[] { 1 }, 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[] { 1 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkRight", new int[] { 12, 11, 10, 19, 18, 17, 16, 15 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkLeft", new int[] { 2, 3, 4, 5, 6, 7, 8, 9 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkUp", new int[] { 2, 3, 4, 5, 6, 7, 8, 9 }, new float[] { vMs, vMs });
            _spriteMap.Add("walkDown", new int[] { 12, 11, 10, 19, 18, 17, 16, 15 }, new float[] { vMs, vMs });

            _spriteMap.Add("pickup", new int[] { 16, 16, 16 }, new float[] { vMs, vMs });
            _spriteMap.Add("dropoff", new int[] { 16, 16, 16 }, new float[] { vMs, vMs });
            _spriteMap.Add("hit", new int[] { 1, 2, 6, 5 }, new float[] { vMs, vMs });
        }
        public void AddPlayerWagonSprites()
        {
            var hMs = 5f;//horizontal animation speed
            var vMs = 5f;//vertical animation speed
            _spriteMap.Add("standRight", new int[] { 1 }, 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[] { 1 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkRight", new int[] { 12, 11, 10, 19, 18, 17, 16, 15 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkLeft", new int[] { 2, 3, 4, 5, 6, 7, 8, 9 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkUp", new int[] { 2, 3, 4, 5, 6, 7, 8, 9 }, new float[] { vMs, vMs });
            _spriteMap.Add("walkDown", new int[] { 12, 11, 10, 19, 18, 17, 16, 15 }, new float[] { vMs, vMs });
            _spriteMap.Add("defendRight", new int[] { 14 }, new float[] { vMs, vMs });
            _spriteMap.Add("defendLeft", new int[] { 13 }, new float[] { vMs, vMs });

            _spriteMap.Add("pickup", new int[] { 16, 16, 16 }, new float[] { vMs, vMs });
            _spriteMap.Add("dropoff", new int[] { 16, 16, 16 }, new float[] { vMs, vMs });
            _spriteMap.Add("hit", new int[] { 1, 2, 6, 5 }, new float[] { vMs, vMs });
        }
        #endregion
        public void PressKeysForAnimation(Controller cn, string l, string r, string u, string d)
        {
            #region pressed Keys for animation
            if (cn.Button("RightMouseClick").Pressed && Global.doesPlayerHaveWagon)
                SoundManager.PlayRequestedSound("_wagonHoldUp", .5f);
            if (cn.Button("RightMouseClick").Down && Global.doesPlayerHaveWagon)
            {//change collider to be smaller, and freeze movement. heheheheh
                movement.Freeze = true;
                Collider.X = -3;
                Collider.Y = -7;
                Collider.Width = 10;
                Collider.Height = 20;
            }
            else
            {
                Collider.X = -7;
                Collider.Y = -13;
                Collider.Width = 10;
                Collider.Height = 30;
                movement.Freeze = false;
            }
            if (cn.Button("RightMouseClick").Down && Global.doesPlayerHaveWagon)
            {
                if (_spriteMap.CurrentAnim == "standRight" || _spriteMap.CurrentAnim == "walkRight" ||
                    _spriteMap.CurrentAnim == "standUp" || _spriteMap.CurrentAnim == "walkUp")
                    ChangeAnimTo("defendRight");
                else if (_spriteMap.CurrentAnim == "standLeft" || _spriteMap.CurrentAnim == "walkLeft" ||
                    _spriteMap.CurrentAnim == "standDown" || _spriteMap.CurrentAnim == "walkDown")
                    ChangeAnimTo("defendLeft");
            }
            else if (cn.Button("A").Pressed)//LEFT
                ChangeAnimTo(l);
            else if (cn.Button("D").Pressed)//RIGHT
                ChangeAnimTo(r);
            else if (cn.Button("W").Pressed)//UP
                ChangeAnimTo(u);
            else if (cn.Button("S").Pressed)//DOWN
                ChangeAnimTo(d);
            #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
                    ChangeAnimTo(u);
                else if (cn.Button("S").Down)//and i'm holding down
                    ChangeAnimTo(d);
                else if (cn.Button("D").Down)//and i'm holding right
                    ChangeAnimTo(r);
            }
            else if (cn.Button("D").Released)//if i release right, updownleft
            {
                if (cn.Button("W").Down)//and i'm holding up
                    ChangeAnimTo(u);
                else if (cn.Button("S").Down)//and i'm holding down
                    ChangeAnimTo(d);
                else if (cn.Button("A").Down)//and i'm holding left
                    ChangeAnimTo(l);
            }
            else if (cn.Button("W").Released)//if i release up, rightleftdown
            {
                if (cn.Button("D").Down)//and i'm holding right
                    ChangeAnimTo(r);
                else if (cn.Button("A").Down)//and i'm holding left
                    ChangeAnimTo(l);
                else if (cn.Button("S").Down)//and i'm holding down
                    ChangeAnimTo(d);
            }
            else if (cn.Button("S").Released)//if i release down, rightleftup
            {
                if (cn.Button("D").Down)//and i'm holding right
                    ChangeAnimTo(r);
                else if (cn.Button("A").Down)//and i'm holding left
                    ChangeAnimTo(l);
                else if (cn.Button("W").Down)//and i'm holding up
                    ChangeAnimTo(u);
            }
            else if (cn.Button("RightMouseClick").Released)
            {
                if (cn.Button("D").Down)//and i'm holding right
                    ChangeAnimTo(r);
                else if (cn.Button("A").Down)//and i'm holding left
                    ChangeAnimTo(l);
                else if (cn.Button("W").Down)//and i'm holding up
                    ChangeAnimTo(u);
                else if (cn.Button("S").Down)//and i'm holding down
                    ChangeAnimTo(d);
            }
            #endregion
        }

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

        public void Destroy()
        {
            RemoveSelf();
        }

    }
}
