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

namespace LOoSE_sLOTS.entities
{
    class IntroCharacter : Entity
    {
        private bool isSpritemapChanged = true;
        private BasicMovement movement = new BasicMovement(400, 400, 400);//was 400,400,400
        private float _forcedSpeed = .5f;//this is the decend rate to position. was 1
        private float _forcedDodgeSpeed = 2f;//this is the decend rate to position. was 1
        private bool isLetsChat = true;
        private bool one;

        private static Spritemap<string> _spriteMap;
        private static bool isTalking = true;
        private static int _yo = 35;
        private static int _xo = 50;

        public static float IntroX = 0;
        public static float IntroY = 0;
        public static bool IsDodging;
        private float closestDistanceItem = 150f;//only if close do they come to you. it's a small space, i guess 100.
        private Entity closestItem;
        private int rand = 0;
        private bool sayHey;
        private bool canonlywritethisstupidthinginanupdate;

        public IntroCharacter(float x, float y)
        {
            X = x; Y = y;
            SetHitbox(9, 20, (int)Global.Type.INTROCHARACTER);
            Collider.X = -5;
            Collider.Y = -16;
            Axis axis = Axis.CreateWASD();
            movement.Axis = axis;
            movement.Collider = Collider;
            movement.AddCollision((int)Global.Type.SOLID);//walls
            AddComponents(axis, movement);
            LoadCorrectSpritemap();
            _spriteMap.CenterOrigin();
        }

        public override void Update()
        {
            base.Update();
            IntroX = X;
            IntroY = Y;
            if (!canonlywritethisstupidthinginanupdate)
            {
                canonlywritethisstupidthinginanupdate = true;
                Global.WriteWord(20, Global.I_MH - 16, "To Skip Intro Press X", Color.Blue, 1f, 1, Global.GAME.Scene, 0, 6);//shadow first
                Global.WriteWord(19, Global.I_MH - 15, "To Skip Intro Press X", Color.Grey, 1f, 1, Global.GAME.Scene, 0, 6);//regular text on top(second)
            }
            var cn = Global.PlayerSession.Controller;
            if (cn.Button("R").Down)
            {
               // Console.WriteLine("r button testing");
                //Global.GAME.Scene.Add(new Coin(Global.GAME.Scene.MouseX, Global.GAME.Scene.MouseY, Global.GAME.Scene.MouseY + 30));
            }
            if (cn.Button("E").Pressed)//testing!
            {
                //Console.WriteLine("e button testing");
            }
            if (cn.Button("X").Pressed && !Global.SkipIntro)
            {
                //Console.WriteLine("x button pressed");
                Global.SkipIntro = true;
            }
            if (isSpritemapChanged)
                LoadCorrectSpritemap();
            if (Global.GaveHimHisMoney)
            {
                movement.Freeze = true;
            }
            else
            { 
                #region talking
                if (!isTalking)
                {
                    movement.Freeze = false;
                    movement.Axis.ForceState(-_forcedSpeed, 0);
                }
                else
                {
                    movement.Freeze = true;
                }
                if (Timer > 100 && isLetsChat)
                {
                    isLetsChat = false;
                    Global.GAME.Coroutine.Start(LetsChat(Global.GAME.Scene));
                }
                if (Global.SkipIntro && !one)
                {
                    one = true;
                    X = 350;
                    Y = 380;
                    isTalking = true;
                    IsDodging = true;
                    var entities = GetEntities<Numbers>(); //remove intercom previous message.
                    foreach (var item in entities)
                    {
                        item.Destroy();
                    }
                    Global.WriteWord(300, 10, "Give him the money!", Color.Gold, 2f, 1, Global.GAME.Scene, 0);//shadow first
                    Global.WriteWord(300 - 2, 10 - 2, "Give him the money!", Color.White, 2f, 1, Global.GAME.Scene, 0);//regular text on top(second)
                }
                #endregion
                #region dodging
                if (IsDodging)
                {
                    //Console.WriteLine("Dodging!");
                    if (AmICollidingWithDetection(Collider))
                    {
                        if (!AmICollidingWithSlotMachines(Collider))
                        {
                            movement.Freeze = false;
                            if (!sayHey)
                            {
                                sayHey = true;
                                SoundManager.PlayRequestedSound(RandomHey());
                            }
                            if (rand == 0)
                            {
                                Shared.ChangeAnimTo("walkLeft", _spriteMap);
                                _spriteMap.FlippedX = false;
                                movement.Axis.ForceState(-_forcedDodgeSpeed * 8, 0);
                            }
                            else
                            {
                                Shared.ChangeAnimTo("walkLeft", _spriteMap);
                                _spriteMap.FlippedX = true;
                                movement.Axis.ForceState(_forcedDodgeSpeed * 8, 0);
                            }
                        }
                    }
                    else
                    {
                        GetClosestEntity();
                        if (closestItem == null)
                        {
                            movement.Freeze = true;
                            Shared.ChangeAnimTo("standFront", _spriteMap);
                            _spriteMap.FlippedX = false;
                            rand = GetNewEscapePath();
                            sayHey = false;
                        }
                    }
                    //map edges
                    var offset = 4;
                    if (X < -offset)
                        X = Global.I_MW - 9;
                    else if (X > Global.I_MW - 9)
                        X = -offset;
                    if (Y < -offset)
                        Y = Global.I_MH - 9;
                    else if (Y > Global.I_MH - 9)
                        Y = -offset;
                }
                #endregion
            }
        }//end of update
        public int GetNewEscapePath()
        {
            return Rand.Int(0, 2); // 50\50 shot.
        }
        public bool AmICollidingWithDetection(Collider c)
        {
            var d = c.Collide(X, Y, (int)Global.Type.SLOTMACHINEDETECTOR);
            if ( d != null)
                return true;
            else
                return false;
        }
        public bool AmICollidingWithSlotMachines(Collider c)
        {
            var slot = c.Collide(X, Y, (int)Global.Type.SLOTMACHINE);
            if ( slot != null)
                return true;
            else
                return false;
        }
        public void GetClosestEntity()
        {
            //ok here's what i'm envisioning. Use the same distance detection for moving that i used previously. It's different, i know, but
            //it should be easier than then becaue it's 2d space. Platforming. yes, but maybe it'll work. really.
            //okay so get distance to nearest, if it's under the distance, start moving to the right. Maybe move faster based on how far
            //away it is from you?
            var machines = GetEntities<SlotMachine>();//get all machines.
            foreach (var item in machines)
            {
                var diff = item.X - X;
                if (item.Y < 100)//only keep those that are actually falling.
                {
                    if (Math.Abs(diff) <= 150)//this starts at 150. woof.
                    {
                        closestDistanceItem = Math.Abs(diff);//this is the distance to it
                        closestItem = item;//this is the one itself.
                        if (!AmICollidingWithSlotMachines(Collider))
                        {
                            movement.Freeze = false;
                            if (rand == 0)
                                movement.Axis.ForceState(-_forcedDodgeSpeed * 12, 0);
                            else
                                movement.Axis.ForceState(_forcedDodgeSpeed * 12, 0);
                        }
                    }
                    else
                        closestItem = null;
                }
            }
        }

        public static IEnumerator LetsChat(Scene scene)
        {
            if (!Global.SkipIntro)
            {
                isTalking = true;
                Shared.ChangeAnimTo("talk", _spriteMap);
                Global.WriteWord(IntroX - _xo, IntroY - _yo, "Hey", Color.Gold, 2f, 1, scene, 50);//shadow first
                Global.WriteWord(IntroX - _xo - 2, IntroY - _yo - 2, "Hey", Color.White, 2f, 1, scene, 50);//regular text on top(second)
                SoundManager.PlayRequestedSound("_hey");
                yield return Coroutine.Instance.WaitForFrames(50);
            }
            if (!Global.SkipIntro)
            {
                isTalking = false;
                Shared.ChangeAnimTo("walkLeft", _spriteMap);
                yield return Coroutine.Instance.WaitForFrames(60);
            }
            if (!Global.SkipIntro)
            {
                isTalking = true;
                Shared.ChangeAnimTo("talk", _spriteMap);
                Global.WriteWord(IntroX - _xo, IntroY - _yo, "Hey", Color.Gold, 2f, 1, scene, 50);//shadow first
                Global.WriteWord(IntroX - _xo - 2, IntroY - _yo - 2, "Hey", Color.White, 2f, 1, scene, 50);//regular text on top(second)
                SoundManager.PlayRequestedSound("_hey2");
                yield return Coroutine.Instance.WaitForFrames(50);
            }
            if (!Global.SkipIntro)
            {
                isTalking = false;
                Shared.ChangeAnimTo("walkLeft", _spriteMap);
                yield return Coroutine.Instance.WaitForFrames(50);
            }
            if (!Global.SkipIntro)
            {
                isTalking = true;
                Shared.ChangeAnimTo("talk", _spriteMap);
                Global.WriteWord(IntroX - _xo - 50, IntroY - _yo, "Where's the game?", Color.Gold, 2f, 1, scene, 80);//shadow first
                Global.WriteWord(IntroX - _xo - 50 - 2, IntroY - _yo - 2, "Where's the game?", Color.White, 2f, 1, scene, 80);//regular text on top(second)
                SoundManager.PlayRequestedSound("_wheresTheGame");
                yield return Coroutine.Instance.WaitForFrames(80);
            }
            if (!Global.SkipIntro)
            {
                isTalking = false;
                Shared.ChangeAnimTo("walkLeft", _spriteMap);
                yield return Coroutine.Instance.WaitForFrames(40);
            }
            if (!Global.SkipIntro)
            {
                isTalking = true;
                Shared.ChangeAnimTo("talk", _spriteMap);
                Global.WriteWord(IntroX - _xo, IntroY - _yo, "Hey", Color.Gold, 2f, 1, scene, 40);//shadow first
                Global.WriteWord(IntroX - _xo - 2, IntroY - _yo - 2, "Hey", Color.White, 2f, 1, scene, 40);//regular text on top(second)
                SoundManager.PlayRequestedSound("_hey3");
                yield return Coroutine.Instance.WaitForFrames(40);
            }
            if (!Global.SkipIntro)
            {
                isTalking = false;
                Shared.ChangeAnimTo("walkLeft", _spriteMap);
                yield return Coroutine.Instance.WaitForFrames(60);
            }
            if (!Global.SkipIntro)
            {
                isTalking = true;
                Shared.ChangeAnimTo("talk", _spriteMap);
                Global.WriteWord(IntroX - _xo, IntroY - _yo, "oh", Color.Gold, 2f, 1, scene, 30);//shadow first
                Global.WriteWord(IntroX - _xo - 2, IntroY - _yo - 2, "oh", Color.White, 2f, 1, scene, 30);//regular text on top(second)
                SoundManager.PlayRequestedSound("_oh");
                yield return Coroutine.Instance.WaitForFrames(30);
            }
            if (!Global.SkipIntro)
            {
                isTalking = false;
                Shared.ChangeAnimTo("walkLeft", _spriteMap);
                yield return Coroutine.Instance.WaitForFrames(50);
            }
            if (!Global.SkipIntro)
            {
                isTalking = true;
                Shared.ChangeAnimTo("talk", _spriteMap);
                Global.WriteWord(IntroX - _xo, IntroY - _yo, "Hi", Color.Gold, 2f, 1, scene, 30);//shadow first
                Global.WriteWord(IntroX - _xo - 2, IntroY - _yo - 2, "Hi", Color.White, 2f, 1, scene, 30);//regular text on top(second)
                SoundManager.PlayRequestedSound("_hi");
                yield return Coroutine.Instance.WaitForFrames(30);
            }
            if (!Global.SkipIntro)
            {
                Shared.ChangeAnimTo("standFront", _spriteMap);
                yield return Coroutine.Instance.WaitForFrames(70);
            }
            if (!Global.SkipIntro)
            {
                Shared.ChangeAnimTo("talk", _spriteMap);
                Global.WriteWord(IntroX - _xo, IntroY - _yo, "Well, I did this...", Color.Gold, 2f, 1, scene, 100);//shadow first
                Global.WriteWord(IntroX - _xo - 2, IntroY - _yo - 2, "Well, I did this...", Color.White, 2f, 1, scene, 100);//regular text on top(second)
                SoundManager.PlayRequestedSound("_wellIDidThis");
                yield return Coroutine.Instance.WaitForFrames(100);
            }
            if (!Global.SkipIntro)
            {
                Shared.ChangeAnimTo("standFront", _spriteMap);
                yield return Coroutine.Instance.WaitForFrames(80);
            }
            if (!Global.SkipIntro)
            {
                Shared.ChangeAnimTo("talk", _spriteMap);
                Global.WriteWord(IntroX - _xo, IntroY - _yo, "and, and do you know what I want?", Color.Gold, 2f, 1, scene, 130);//shadow first
                Global.WriteWord(IntroX - _xo - 2, IntroY - _yo - 2, "and, and do you know what I want?", Color.White, 2f, 1, scene, 130);//regular text on top(second)
                SoundManager.PlayRequestedSound("_andAndDoYouKnowWhatIWant");
                yield return Coroutine.Instance.WaitForFrames(130);
            }
            if (!Global.SkipIntro)
            {
                Shared.ChangeAnimTo("standFront", _spriteMap);
                yield return Coroutine.Instance.WaitForFrames(100);
            }
            if (!Global.SkipIntro)
            {
                Shared.ChangeAnimTo("talk", _spriteMap);
                Global.WriteWord(IntroX - _xo, IntroY - _yo, "to get paid.", Color.Gold, 2f, 1, scene, 150);//shadow first
                Global.WriteWord(IntroX - _xo - 2, IntroY - _yo - 2, "to get paid.", Color.White, 2f, 1, scene, 150);//regular text on top(second)
                SoundManager.PlayRequestedSound("_toGetPaid");
                yield return Coroutine.Instance.WaitForFrames(100);
            }
            if (!Global.SkipIntro)
            {
                Shared.ChangeAnimTo("standFront", _spriteMap);
                yield return Coroutine.Instance.WaitForFrames(100);
            }
            if (!Global.SkipIntro)
            {
                Shared.ChangeAnimTo("talk", _spriteMap);
                Global.WriteWord(IntroX - _xo, IntroY - _yo, "give ME money", Color.Gold, 2f, 1, scene, 150);//shadow first
                Global.WriteWord(IntroX - _xo - 2, IntroY - _yo - 2, "give ME money", Color.White, 2f, 1, scene, 150);//regular text on top(second)
                SoundManager.PlayRequestedSound("_giveMeMoney");
                yield return Coroutine.Instance.WaitForFrames(80);
            }
            if (!Global.SkipIntro)
            {
                Shared.ChangeAnimTo("standFront", _spriteMap);
                yield return Coroutine.Instance.WaitForFrames(80);
            }
            if (!Global.SkipIntro)
            {
                Shared.ChangeAnimTo("standFrontOpen", _spriteMap);
                Global.WriteWord(IntroX - _xo - 30, IntroY - _yo, "NOWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW!!!!!!!!!", Color.Gold, 2f, 1, scene, 200);//shadow first
                Global.WriteWord(IntroX - _xo - 30 - 2, IntroY - _yo - 2, "NOWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW!!!!!!!!!", Color.White, 2f, 1, scene, 200);//regular text on top(second)
                SoundManager.PlayRequestedSound("_now");
                yield return Coroutine.Instance.WaitForFrames(200);
            }
            if (!Global.SkipIntro)
            {
                Shared.ChangeAnimTo("standFront", _spriteMap);
                yield return Coroutine.Instance.WaitForFrames(100);
                Global.WriteWord(300, 10, "Give him the money!", Color.Gold, 2f, 1, scene, 0);//shadow first
                Global.WriteWord(300 - 2, 10 - 2, "Give him the money!", Color.White, 2f, 1, scene, 0);//regular text on top(second)
            }
            Global.GiveHimTheMoney = true;
            IsDodging = true;
        }
        private string RandomHey()
        {
            switch (Rand.Int(1, 5))//one more than the last
            {
                case 1:
                    return "_hey";
                case 2:
                    return "_hey2";
                case 3:
                    return "_hey3";
                case 4:
                    return "_hey4";
                default:
                    return "_hey";
            }
        }

        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.INTROCHARACTER, 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("walkLeft");
            _spriteMap.FlippedX = false;
            Graphic = _spriteMap;
        }

        #region AddSprites
        public void AddNewSprites()
        {
            var hMs = 6f;//horizontal animation speed
            _spriteMap.Add("standLeft", new int[] { 0 }, new float[] { hMs, hMs });
            _spriteMap.Add("walkLeft", new int[] { 0, 1 }, new float[] { 9, 9 });
            _spriteMap.Add("talk", new int[] { 2, 3 }, new float[] { 12, 12 });
            _spriteMap.Add("standFront", new int[] { 2 }, new float[] { 12, 12 });
            _spriteMap.Add("standFrontOpen", new int[] { 3 }, new float[] { 12, 12 });

            _spriteMap.Add("death", new int[] { 1, 5, 1, 7, 2, 0, 3, 5, 1, 6, 7 }, new float[] { 16, 16 });
        }
        /*public void AddPlayerWagonSprites()
        {
            var hMs = 1f;//horizontal animation speed
            var vMs = 1f;//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 override void Render()//mainly for testing colliders :D
        {
            base.Render();
            //Collider.Render();
        }

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

