using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Otter;
using Puppyups.entities;
using Puppyups.objects;
using Puppyups.UI;
using Puppyups.Utilities;
using TiledSharp;

namespace Puppyups.scenes
{
    class InHall : Scene
    {
        public const int _w = Global.MW;
        public const int _h = Global.MH;

        public TmxMap tmxMap = new TmxMap(Assets.INHALL);
        public GridCollider grid = null;

        public Tilemap layerOne = new Tilemap(Assets.TILES, _w, _h, Global.GRID_WIDTH, Global.GRID_HEIGHT);
        public Tilemap layerTwo = new Tilemap(Assets.TILES, _w, _h, Global.GRID_WIDTH, Global.GRID_HEIGHT);
        public Tilemap layerThree = new Tilemap(Assets.TILES, _w, _h, Global.GRID_WIDTH, Global.GRID_HEIGHT);
        public Tilemap layerFour = new Tilemap(Assets.TILES, _w, _h, Global.GRID_WIDTH, Global.GRID_HEIGHT);
        private bool one = true;
        private bool two = true;
        private bool three = true;
        private bool hasPlayerClickTheButton;
        private bool hasPlayer2ClickTheButton;

        public InHall()
        {
            #region Create the Map
            grid = new GridCollider(_w, _h, 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 if (layer.Name == "Layer 4")
                    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);

            Add(new PA(300, 50));
            Add(new SpinningLight(200, 180));
            Add(new SpinningLight(400, 180));
            Add(new SpinningLight(600, 140));
            Add(new LabGun(320, 130));
            if (Global.IsTwoPlayerActive)
                Add(new LabGun2(320, 340));

            Add(new Player(32, Global.MH / 2 + 50));

            Add(new Player2(32, Global.MH / 2 + 70));

            WriteWord(14, 2, "P1 Score:", Color.Gold, 1f, -2);
            Add(new Score(104, 4));
            if (Global.IsTwoPlayerActive)
            {
                WriteWord(470, 2, "P2 Score:", Color.Magenta, 1f, -2);
                Add(new Score2(570, 4));
            }
        }

        public override void Update()
        {
            base.Update();
            //this is where we start our story. We have nothing so we need to tell theplayer how to move around. 
            if (Timer > 50 && one)//HA a scene has a built in timer. YES.
            {
                one = false;
                Global.GAME.Coroutine.Start(FirstSound());
                WriteWord(400, 8, "INTERCOM:", Color.Gold, 1f, 1, 7);
                WriteWord(401, 8, "INTERCOM:", Color.White, 1f, 1, 7);
                WriteWord(400, 21, "Hey, I see you there.", Color.Red, 1f, 1, 7);
                WriteWord(401, 21, "Hey, I see you there.", Color.White, 1f, 1, 7);
                WriteWord(400, 31, "GET YOUR GUN!", Color.Orange, 1f, 1, 7);
                WriteWord(401, 31, "GET YOUR GUN!", Color.White, 1f, 1, 7);
                WriteWord(400, 41, "TAKE WHAT YOU CAN, BUT SACRIFICES MUST BE MADE!", Color.Black, 1f, 1, 6);
                WriteWord(401, 41, "TAKE WHAT YOU CAN, BUT SACRIFICES MUST BE MADE!", Color.White, 1f, 1, 6);
            }
            if (Global.IsPlayer1GunCollected && Global.IsPlayer2GunCollected && two)
            {
                var entities = GetEntities<Numbers>(); //remove intercom previous message.
                foreach (var item in entities)
                {
                    item.Destroy();
                }
                WriteWord(14, 2, "P1 Score:", Color.Gold, 1f, -2);
                Add(new Score(104, 4));
                if (Global.IsTwoPlayerActive)
                {
                    WriteWord(470, 2, "P2 Score:", Color.Magenta, 1f, -2);
                    Add(new Score2(570, 4));
                }
                two = false;
                Global.GAME.Coroutine.Start(RegularSound());
                WriteWord(400, 8, "INTERCOM:", Color.Gold, 1f, 1, 7);
                WriteWord(401, 8, "INTERCOM:", Color.White, 1f, 1, 7);
                WriteWord(400, 21, "Controls:", Color.Orange, 1f, 1, 7);
                WriteWord(401, 21, "Controls:", Color.White, 1f, 1, 7);
                WriteWord(400, 31, "PlayerOne!", Color.Blue, 1f, 1, 7);
                WriteWord(401, 31, "PlayerOne!", Color.White, 1f, 1, 7);
                WriteWord(400, 41, "Press J to shoot! Try it!", Color.Black, 1f, 1, 7);
                WriteWord(401, 41, "Press J to shoot! Try it!", Color.White, 1f, 1, 7);
                if (Global.IsTwoPlayerActive)
                {
                    WriteWord(400, 51, "PlayerTwo!", Color.Magenta, 1f, 1, 7);
                    WriteWord(401, 51, "PlayerTwo!", Color.White, 1f, 1, 7);
                    WriteWord(400, 61, "press NUMZERO to shoot! Try it!", Color.Black, 1f, 1, 7);
                    WriteWord(401, 61, "press NUMZERO to shoot! Try it!", Color.White, 1f, 1, 7);
                }
            }
            if (hasPlayerClickTheButton && hasPlayer2ClickTheButton && three)
            {
                var entities = GetEntities<Numbers>(); //remove intercom previous message.
                foreach (var item in entities)
                {
                    item.Destroy();
                }
                WriteWord(14, 2, "P1 Score:", Color.Gold, 1f, -2);
                Add(new Score(104, 4));
                if (Global.IsTwoPlayerActive)
                {
                    WriteWord(470, 2, "P2 Score:", Color.Magenta, 1f, -2);
                    Add(new Score2(570, 4));
                }
                three = false;
                Add(new Dog(32, 220));
                Add(new Dog(632, 220));
                Global.GAME.Coroutine.Start(RegularSound());
                WriteWord(400, 8, "INTERCOM:", Color.Gold, 1f, 1, 7);
                WriteWord(401, 8, "INTERCOM:", Color.White, 1f, 1, 7);
                WriteWord(400, 21, "A Couple of Dogs have gotten in. Catch them!", Color.Orange, 1f, 1, 7);
                WriteWord(401, 21, "A Couple of Dogs have gotten in. Catch them!", Color.White, 1f, 1, 7);
                WriteWord(400, 31, "After that Go Save All Of Them!", Color.Blue, 1f, 1, 7);
                WriteWord(401, 31, "After that Go Save All Of Them!", Color.White, 1f, 1, 7);
                WriteWord(400, 41, "------------------>>>>>>>", Color.Black, 1f, 1, 7);
                WriteWord(401, 41, "------------------>>>>>>>", Color.White, 1f, 1, 7);
            }
            if (Global.PlayerSession.Controller.Button("J").Pressed && !two)
            {
                hasPlayerClickTheButton = true;
                if (!Global.IsTwoPlayerActive)
                    hasPlayer2ClickTheButton = true;
            }
            if (Global.Player2Session.Controller.Button("NumZero").Pressed)
                hasPlayer2ClickTheButton = true;

        }

        public static IEnumerator RegularSound()
        {
            SoundManager.PlayRequestedSound("_pabeep");
            yield return Coroutine.Instance.WaitForFrames(50);
            SoundManager.PlayRequestedSound("_paattention");
        }
        public static IEnumerator FirstSound()
        {
            SoundManager.PlayRequestedSound("_pabeep");
            yield return Coroutine.Instance.WaitForFrames(50);
            SoundManager.PlayRequestedSound("_paheyisee");
            yield return Coroutine.Instance.WaitForFrames(120);
            SoundManager.PlayRequestedSound("_paguns");
            yield return Coroutine.Instance.WaitForFrames(120);
            SoundManager.PlayRequestedSound("_patake");
        }

        public void WriteWord(float x, float y, string word, Color color, float scale, int layer, int spacer = 10)
        {
            var a = 0;
            for (var i = 0; i < word.Length; i++)
            {
                Add(new Numbers(x + a, y, word[i].ToString(), color, scale, layer));
                a += spacer;
            }
        }

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