using Otter;
using System;

namespace SuperRefluxPowergridDefense_.entities
{
    public class Player : Entity
    {
        private Spritemap<string> _spriteMap;
        //private sound death = new Sound(Assets.SFX_DEATH); //todo
        private bool _hMove = true;
        private bool _vMove = true;
        private float _playerOffsetX = 20;
        private float _playerOffsetY = 40;
        private int personalStorage = 0;
        public static bool canPlayerCollide = true;
        public static bool isSpritemapChanged = true;
        private bool isOn = true;//for shooting and stuff.
        private bool animDone = true;//for shooting and stuff.
        private BasicMovement movement = new BasicMovement(400, 400, 400);//was 400,400,400

        public Player(float x, float y)
        {
            X = x; Y = y;
            SetHitbox(20, 30, (int)Global.Type.PLAYER);
            Collider.X = -9;
            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();
            Global.PlayerSpeed = movement.Speed;
        }

        public override void Update()
        {
            base.Update();
            #region override edges
            if (X < -8)
                X = -8;
            if (X > 1400)
                X = 1400;
            if (Y < -4)
                Y = -4;
            if (Y > 910)
                Y = 910;
            #endregion
            #region Camera
            //if player is greater than the edge, greater than the other edge, less than the other edge, and less than the other edge, camera follows him.
            //Console.WriteLine("camerax {0}", Scene.CameraX);
            //Console.WriteLine("cameray {0}", Scene.CameraY);
            if (X > 360 - _playerOffsetX && X < 1080 - _playerOffsetX)//was 220 and 1180
                Scene.CameraX = X + _playerOffsetX - Scene.HalfWidth;//add x offset if needed here. (this follows the player)
            else if (X <= 360 - _playerOffsetX)//was 220
                Scene.CameraX = 0;//was -480
            else if (X >= 1080 - _playerOffsetX)//was 1180
                Scene.CameraX = 720;//was 480
            if (Y > 240 - _playerOffsetY && Y < 720 - _playerOffsetY)
                Scene.CameraY = Y + _playerOffsetY - Scene.HalfHeight;//add y offset if needed here. (this follows the player)
            else if (Y <= 240 - _playerOffsetY)
                Scene.CameraY = 0;
            else if (Y >= 720 - _playerOffsetY)
                Scene.CameraY = 480;
            #endregion
            var cn = Global.PlayerSession.Controller;
            Global.PlayerX = this.X;
            Global.PlayerY = this.Y;
            Global.PlayerCurrentAnim = _spriteMap.CurrentAnim;
            if (cn.Button("R").Pressed)//testing!
            {
                Console.WriteLine("x: {0} y: {1}", X, Y);
                //Scene.Add(new Fuel(Global.MW + 150, Global.MH + 200));
                Console.WriteLine("testing! R was pressed.");
                //Scene.Add(new ScaryGirl(Scene.MouseX, Scene.MouseY));
            }
            //if (cn.Button("Up").Pressed)
            //Scene.Add(new RedLaser(X + 23, Y + 29, "Up", this));//was 10, 22
            //if (cn.Button("Right").Pressed)
            //Scene.Add(new RedLaser(X + 27, Y + 26, "Right", this));//was 10, 22
            //if (cn.Button("Left").Pressed)
            //Scene.Add(new RedLaser(X + 19, Y + 26, "Left", this));//was 10, 22
            //if (cn.Button("Down").Pressed)
            //Scene.Add(new RedLaser(X + 23, Y + 33, "Down", this));//was 10, 22
            if (_spriteMap.CurrentAnim == "pickup" && !animDone)
            {
                if (_spriteMap.CurrentAnim == "pickup" && _spriteMap.CurrentFrameIndex == 2)//this is 0-based.
                {
                    animDone = true;
                    _spriteMap.Play("carrystandLeft");
                }
            }
            else if (_spriteMap.CurrentAnim == "dropoff" && !animDone)
            {
                SoundManager.PlayRequestedSound("_pickup");
                if (_spriteMap.CurrentAnim == "dropoff" && _spriteMap.CurrentFrameIndex == 2)//this is 0-based.
                {
                    animDone = true;
                    _spriteMap.Play("standLeft");
                }
            }
            else if (personalStorage > 0 && animDone && isOn)//animation for collecting is done, you are carrying something, and you are powered.
                PressKeysForAnimation(cn, "carrywalkLeft", "carrywalkRight", "carrywalkUp", "carrywalkDown");
            else if (!isOn && animDone && personalStorage > 0 )//animation for collecting is done, you are unpowered and carrying something.
                PressKeysForAnimation(cn, "carryoffstandRight", "carryoffwalkLeft", "carryoffwalkLeft", "carryoffwalkLeft");
            else if (isOn && personalStorage <= 0)//you are powered, you are not carrying something
                PressKeysForAnimation(cn, "walkLeft", "walkRight", "walkUp", "walkDown");
            else//you are unpowered. and not carrying anything
                PressKeysForAnimation(cn, "offwalkLeft", "offwalkLeft", "offwalkLeft", "offwalkLeft");

            #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
            #region CollideWithBlueLaser
            var collFuel = Collider.Collide(X, Y, (int)Global.Type.FUEL);
            if (collFuel != null)
            {
                if (Global.PlayerCarryingCapacity > personalStorage)
                {
                    Fuel f = (Fuel)collFuel.Entity;
                    f.RemoveSelf();
                    personalStorage++;
                    _spriteMap.Play("pickup");
                    SoundManager.PlayRequestedSound("_pickup");
                    SoundManager.PlayRequestedSound("_pickupFUEL");
                    animDone = false;
                }
            }
            var collGenerator = Collider.Collide(X, Y, (int)Global.Type.GENERATOR);
            if (collGenerator != null)
            {
                if (personalStorage > 0)
                {
                    Generator g = (Generator)collGenerator.Entity;
                    g._fuel++;
                    personalStorage--;
                    _spriteMap.Play("dropoff");
                    SoundManager.PlayRequestedSound("_pickup");
                    animDone = false;
                }
            }
            if (Global.PlayerHealth <= 0)
            {
                Destroy();
                Scene.Add(new PlayerDeath(X, Y));
            }
            #endregion
            #endregion
            #region Death... is there death?
            #endregion
        }//END OF UPDATE
        public void LoadCorrectSpritemap()
        {
            isSpritemapChanged = false;
            _spriteMap = null;
            _spriteMap = new Spritemap<string>(Assets.PLAYER, 46, 56);
            AddNewSprites();
            _spriteMap.Update();
            _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[] { 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[] { 0, 1, 2, 3 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkLeft", new int[] { 0, 1, 2, 3 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkUp", new int[] { 0, 1, 2, 3 }, new float[] { vMs, vMs });
            _spriteMap.Add("walkDown", new int[] { 0, 1, 2, 3 }, new float[] { vMs, vMs });

            _spriteMap.Add("offstandRight", new int[] { 4 }, new float[] { hMs, hMs });
            _spriteMap.Add("offstandLeft", new int[] { 4 }, new float[] { hMs, hMs });
            _spriteMap.Add("offstandUp", new int[] { 4 }, new float[] { hMs, hMs });
            _spriteMap.Add("offstandDown", new int[] { 4 }, new float[] { hMs, hMs });
            _spriteMap.Add("offwalkRight", new int[] { 4, 5, 6, 7 }, new float[] { hMs, hMs });
            _spriteMap.Add("offwalkLeft", new int[] { 4, 5, 6, 7 }, new float[] { hMs, hMs });
            _spriteMap.Add("offwalkUp", new int[] { 4, 5, 6, 7 }, new float[] { vMs, vMs });
            _spriteMap.Add("offwalkDown", new int[] { 4, 5, 6, 7 }, new float[] { vMs, vMs });

            _spriteMap.Add("carrystandRight", new int[] { 8 }, new float[] { hMs, hMs });
            _spriteMap.Add("carrystandLeft", new int[] { 8 }, new float[] { hMs, hMs });
            _spriteMap.Add("carrystandUp", new int[] { 8 }, new float[] { hMs, hMs });
            _spriteMap.Add("carrystandDown", new int[] { 8 }, new float[] { hMs, hMs });
            _spriteMap.Add("carrywalkRight", new int[] { 8, 9, 10, 11 }, new float[] { hMs, hMs });
            _spriteMap.Add("carrywalkLeft", new int[] { 8, 9, 10, 11 }, new float[] { hMs, hMs });
            _spriteMap.Add("carrywalkUp", new int[] { 8, 9, 10, 11 }, new float[] { vMs, vMs });
            _spriteMap.Add("carrywalkDown", new int[] { 8, 9, 10, 11 }, new float[] { vMs, vMs });

            _spriteMap.Add("carryoffstandRight", new int[] { 12 }, new float[] { hMs, hMs });
            _spriteMap.Add("carryoffstandLeft", new int[] { 12 }, new float[] { hMs, hMs });
            _spriteMap.Add("carryoffstandUp", new int[] { 12 }, new float[] { hMs, hMs });
            _spriteMap.Add("carryoffstandDown", new int[] { 12 }, new float[] { hMs, hMs });
            _spriteMap.Add("carryoffwalkRight", new int[] { 12, 13, 14, 15 }, new float[] { hMs, hMs });
            _spriteMap.Add("carryoffwalkLeft", new int[] { 12, 13, 14, 15 }, new float[] { hMs, hMs });
            _spriteMap.Add("carryoffwalkUp", new int[] { 12, 13, 14, 15 }, new float[] { vMs, vMs });
            _spriteMap.Add("carryoffwalkDown", new int[] { 12, 13, 14, 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 });
        }
        #endregion
        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;
                    case ("carrywalkLeft"):
                        _spriteMap.Play("carrystandLeft");
                        break;
                    case ("carrywalkRight"):
                        _spriteMap.Play("carrystandRight");
                        break;
                    case ("carrywalkUp"):
                        _spriteMap.Play("carrystandUp");
                        break;
                    case ("carrywalkDown"):
                        _spriteMap.Play("carrystandDown");
                        break;
                    case ("offwalkLeft"):
                        _spriteMap.Play("offstandLeft");
                        break;
                    case ("offwalkRight"):
                        _spriteMap.Play("offstandRight");
                        break;
                    case ("offwalkUp"):
                        _spriteMap.Play("offstandUp");
                        break;
                    case ("offwalkDown"):
                        _spriteMap.Play("offstandDown");
                        break;
                    case ("carryoffwalkLeft"):
                        _spriteMap.Play("carryoffstandLeft");
                        break;
                    case ("carryoffwalkRight"):
                        _spriteMap.Play("carryoffstandRight");
                        break;
                    case ("carryoffwalkUp"):
                        _spriteMap.Play("carryoffstandUp");
                        break;
                    case ("carryoffwalkDown"):
                        _spriteMap.Play("carryoffstandDown");
                        break;
                    default:
                        break;
                }
            }
        }

        public void PressKeysForAnimation(Otter.Controller cn, string l, string r, string u, string d)
        {
            #region pressed Keys for animation
            if (cn.Button("A").Pressed || cn.Button("Left").Pressed)//LEFT
                _spriteMap.Play(l);
            else if (cn.Button("D").Pressed || cn.Button("Right").Pressed)//RIGHT
                _spriteMap.Play(r);
            else if (cn.Button("W").Pressed || cn.Button("Up").Pressed)//UP
                _spriteMap.Play(u);
            else if (cn.Button("S").Pressed || cn.Button("Down").Pressed)//DOWN
                _spriteMap.Play(d);
            #endregion

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

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

        public void Destroy()
        {
            RemoveSelf();
        }
    }
}
