using GiraffeRoller.entities;
using GiraffeRoller.entities.enemies;
using GiraffeRoller.ui;
using GiraffeRoller.Utility;
using Otter;
using TiledSharp;

namespace GiraffeRoller.scenes.Levels
{
    class Base : Scene
    {
        public const int _width = Global.MW * 3;
        public const int _height = Global.MH * 2;
        private bool _addGlobalUI = true;
        private int _timer = 100;

        #region level 01
        public TmxMap tmxMap = new TmxMap(Assets.BASE);
        public GridCollider grid = null;

        public Tilemap layerOne = new Tilemap(Assets.TILES, _width, _height, Global.GRID_WIDTH, Global.GRID_HEIGHT);
        public Tilemap layerTwo = new Tilemap(Assets.TILES, _width, _height, Global.GRID_WIDTH, Global.GRID_HEIGHT);
        public Tilemap layerThree = new Tilemap(Assets.TILES, _width, _height, Global.GRID_WIDTH, Global.GRID_HEIGHT);
        public Tilemap layerFour = new Tilemap(Assets.TILES, _width, _height, Global.GRID_WIDTH, Global.GRID_HEIGHT);
        private bool _addGiraffesScoreMissing;
        private bool isPowerMessageAdded;
        private bool isWarehouseMessageAdded;
        private bool isBossMessageAdded;
        #endregion


        public Base(float playerX, float playerY)
        {
            #region MapCreation 01
            grid = new GridCollider(_width, _height, Global.GRID_WIDTH, Global.GRID_HEIGHT, (int)Global.Type.SOLID);
            Entity gridEntity = new Entity(0, 0, null, grid);
            Add(gridEntity);

            layerOne.DefaultLayerName = tmxMap.Layers[3].Name;
            layerTwo.DefaultLayerName = tmxMap.Layers[2].Name;
            layerThree.DefaultLayerName = tmxMap.Layers[1].Name;
            layerFour.DefaultLayerName = tmxMap.Layers[0].Name;

            for (int z = 0; z < tmxMap.Layers.Count; z++)
            {
                TmxLayer layer = tmxMap.Layers[z];

                if (layer.Name == "Layer 1")
                    layerOne.AddLayer(layer.Name, tmxMap.Layers.Count - z);
                else if (layer.Name == "Layer 2")
                    layerTwo.AddLayer(layer.Name, tmxMap.Layers.Count - z);
                else if (layer.Name == "Layer 3")
                    layerThree.AddLayer(layer.Name, tmxMap.Layers.Count - z);
                else
                    layerFour.AddLayer(layer.Name, tmxMap.Layers.Count - z);

                for (int x = 0; x < tmxMap.Width; x++)
                {
                    for (int y = 0; y < tmxMap.Height; y++)
                    {
                        int i = y * tmxMap.Width + x;
                        if (layer.Name == "Layer 1")//walls
                        {
                            if (layer.Tiles[i].Gid != 0)
                                layerOne.SetTile(x, y, layer.Tiles[i].Gid - 1, layer.Name);
                            if (layer.Tiles[i].Gid != 0)
                                grid.SetTile(x, y, true);
                        }
                        else if (layer.Name == "Layer 2")//main tiles
                        {
                            if (layer.Tiles[i].Gid != 0)
                                layerTwo.SetTile(x, y, layer.Tiles[i].Gid - 1, layer.Name);
                        }
                        else if (layer.Name == "Layer 3")//light blue water
                        {
                            if (layer.Tiles[i].Gid != 0)
                                layerThree.SetTile(x, y, layer.Tiles[i].Gid - 1, layer.Name);
                        }
                        else//dark blue water
                            layerFour.SetTile(x, y, layer.Tiles[i].Gid - 1, layer.Name);
                    }
                }
            }
            #endregion
            AddGraphic(layerFour);
            AddGraphic(layerThree);
            AddGraphic(layerTwo);
            AddGraphic(layerOne);

            Global.cam = new Camera(100, 100);
            //base objects
            Add(new Boss(Global.MW - 32, Global.MH / 2));
            SoundManager.PlayRequestedSound("_carEntrance", .6f);
            if (Global.PowerHealth > 0)
                Add(new Power(Global.MW - 350, 500));
            if (Global.WaterHealth > 0)
                Add(new WaterTower(250, 200));
            if (Global.WarehouseHealth > 0)
                Add(new Warehouse(Global.MW / 2, 100));
            #region Add Players and UI
            Global.player = new Player(playerX, playerY);
            Add(Global.player);
            Add(new Score(10, 10));
            //Add(new Lives(106));
            Add(new GiraffesStolenDisplay(450, 10));
            Add(new PlayerHealthDisplay(240, 10));
            #endregion
            if (Global.music == null)
                Global.music = new Music(Assets.CRICKETAMBIENCE);
            if (!Global.music.IsPlaying)
            {
                Global.music.Play();
                Global.music.Volume = 3f;
                Global.music.Loop = true;
            }
            Add(Global.cam);

            //backgroundstuff
            for (var i = 0; i < 50; i++)
            {
                Add(new WildGiraffe(Rand.Int(-50, Global.MW + 25), Rand.Int(-50, 80)));
                Add(new WildGiraffe(Rand.Int(-50, Global.MW + 25), Rand.Int(Global.MH - 200, Global.MH + 25)));
            }
            for (var i = 0; i < 70; i++)
            {
                Add(new YGrass(Rand.Int(-50, Global.MW + 25), Rand.Int(-50, 100), Color.White, Rand.Float(.5f, 2.5f), Rand.Int(-1, 6)));
                Add(new YGrass(Rand.Int(-50, Global.MW + 25), Rand.Int(Global.MH - 200, Global.MH + 25), Color.White, Rand.Float(.5f, 2.5f), Rand.Int(-1, 6)));
            }
            for (var i = 0; i < 1000; i++)
            {
                Add(new YGrass(Rand.Int(-25, Global.MW + 25), Rand.Int(90, Global.MH - 200), Color.White, Rand.Float(.4f, .6f), Rand.Int(5, 6)));
            }
            for (var i = 0; i < 50; i++)
                Add(new STree(Rand.Int(-50, Global.MW + 25), Rand.Int(-50, 80), Color.White, Rand.Float(.5f, 2.5f), Rand.Int(-1, 6)));
            for (var i = 0; i < 50; i++)
                Add(new STree(Rand.Int(-50, Global.MW + 25), Rand.Int(Global.MH - 200, Global.MH + 25), Color.White, Rand.Float(.5f, 2.5f), Rand.Int(-1, 6)));
            //always add this guy so we can pause the game:
            Add(new PausePerson());
        }

        public override void Begin()
        {
            base.Begin();
            Global.cam.adjustToPlayer(Global.MW, Global.MH, Global.PlayerX, Global.PlayerY);
        }
        public override void Update()
        {
            base.Update();
            if (!IsGroupPaused(0))
            {
                if (_addGlobalUI)
                {
                    _addGlobalUI = false;
                    //Global.AddAllLevelUI(Global.GAME.Scene);//so i don't have to add the same ui every level if all levels have it.
                }
                Shared.LevelUpdate(Global.GAME.Scene);
                //all other unique level updates go here:
                if (!Global.EventFourCanKillBoss && Timer > _timer)
                {
                    _timer += 1000;
                    for (var i = 0; i < 10; i++)
                    {
                        Add(new WildGiraffe(Rand.Int(-50, Global.MW + 25), Rand.Int(-50, 80)));
                        Add(new WildGiraffe(Rand.Int(-50, Global.MW + 25), Rand.Int(Global.MH - 200, Global.MH + 25)));
                    }
                }
                if (!_addGiraffesScoreMissing)
                {
                    _addGiraffesScoreMissing = true;
                    Global.WriteWord(380 - 1, 10 - 1, "Giraffes Stolen:", Color.FromBytes(221, 25, 29, 255), 1f, -101, this, 0, 10);//regular text  
                    Global.WriteWord(380, 10, "Giraffes Stolen:", Color.FromBytes(182, 0, 3, 255), 1f, -100, this, 0, 10);//shadow (layers sort this)
                    Global.WriteWord(20 - 1, 10 - 1, "Score:", Color.FromBytes(255, 143, 0, 255), 1f, -101, this, 0, 10);//regular text  
                    Global.WriteWord(20, 10, "Score:", Color.FromBytes(216, 121, 0, 255), 1f, -100, this, 0, 10);//shadow (layers sort this)
                    Global.WriteWord(220 - 1, 10 - 1, "Health:", Color.FromBytes(235, 177, 36, 255), 1f, -101, this, 0, 10);//regular text  
                    Global.WriteWord(220, 10, "Health:", Color.FromBytes(196, 139, 0, 255), 1f, -100, this, 0, 10);//shadow (layers sort this)
                    //first event:
                    Global.WriteWordUI(20 - 1, 460 - 1, "Ram The Water!", Color.FromBytes(0, 64, 255, 255), 1f, -101, this, 0, 10);//regular text  
                    Global.WriteWordUI(20, 460, "Ram The Water!", Color.FromBytes(0, 0, 0, 255), 1f, -100, this, 0, 10);//shadow (layers sort this)

                }
                if (Global.EventTwoCanKillPower && !isPowerMessageAdded)
                {
                    isPowerMessageAdded = true;
                    RemoveText();
                    Global.WriteWordUI(20 - 1, 460 - 1, "Ram The Power!", Color.FromBytes(0, 222, 222, 255), 1f, -101, this, 0, 10);//regular text  
                    Global.WriteWordUI(20, 460, "Ram The Power!", Color.FromBytes(0, 0, 0, 255), 1f, -100, this, 0, 10);//shadow (layers sort this)
                }
                if (Global.EventThreeCanKillWarehouse && !isWarehouseMessageAdded)
                {
                    isWarehouseMessageAdded = true;
                    RemoveText();
                    Global.WriteWordUI(20 - 1, 460 - 1, "Ram The Warehouse!", Color.FromBytes(54, 57, 63, 255), 1f, -101, this, 0, 10);//regular text  
                    Global.WriteWordUI(20, 460, "Ram The Warehouse!", Color.FromBytes(0, 0, 0, 255), 1f, -100, this, 0, 10);//shadow (layers sort this)
                }
                if (Global.EventFourCanKillBoss && !isBossMessageAdded)
                {
                    isBossMessageAdded = true;
                    RemoveText();
                    Global.WriteWordUI(20 - 1, 460 - 1, "Ram The Boss!", Color.FromBytes(0, 101, 25, 255), 1f, -101, this, 0, 10);//regular text  
                    Global.WriteWordUI(20, 460, "Ram The Boss!", Color.FromBytes(0, 0, 0, 255), 1f, -100, this, 0, 10);//shadow (layers sort this)
                }
                if (Global.PlayerSession.Controller.Button("P1Start").Pressed)
                {
                    Global.GAME.RemoveScene();
                    Global.GAME.AddScene(new LoseScreen());// Add next level here or, where you want to go
                }
            }
        }//end of UPDATE

        public void RemoveText()
        {
            var anyNumbersUI = GetEntities<NumbersUI>();
            foreach (var item in anyNumbersUI)
            {
                item.RemoveSelf();
            }
        }

        public override void Render()
        {
            base.Render();
            //grid.Render();
        }
    }
}
