using System;
using System.Collections.Generic;
using ActionGame.GameResources.Models;
using ActionGame.RawResources.Manager;
using ActionGame.UserInterface.Core;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Media;
using ActionGame.UserInterface.Screen;
using ActionGame.GameArtifacts.Models.Game;
using ActionGame.GameArtifacts.Models.Characters;
using ActionGame.GameArtifacts.Models.WeaponSprites;
using ActionGame.GameArtifacts.Models.Items;
using ActionGame.UserInterface.Helper;

namespace ActionGame.UserInterface.Control
{
    public class GameViewer : IControl
    {
        public IList<IControl> Controls { get; set; }
        public Rectangle Location { get; set; }
        public bool IsSelected { get; set; }
        public bool IsSelectable { get; }

        private readonly IResolution resolution;
        private readonly IRawContentManager rawContentManager;
        private readonly IScreenController screenController;
        private GameData gameData;
        private PlayerHud playerHud;


        public GameViewer(IResolution resolution, IRawContentManager rawContentManager, IScreenController screenController)
        {
            this.Controls = new List<IControl>();
            IsSelectable = false;
            IsSelected = false;

            this.screenController = screenController;
            this.resolution = resolution;
            this.rawContentManager = rawContentManager;

            Init();
        }


        public GameData GameData
        {
            get
            {
                return gameData;
            }
            set
            {
                this.gameData = value;

                this.playerHud.Player = gameData?.GameState.Player;
            }
        }


        public void Draw(SpriteBatch spriteBatch, GameTime gameTime)
        {
            Player player = GameData.GameState.Player;
            WorldMapCell worldMapCell = GameData.GetWorldMapCell(player.WorldPosition);

            DrawScreen(spriteBatch, worldMapCell, GameData.GameState);

            foreach (IControl control in this.Controls)
            {
                control.Draw(spriteBatch, gameTime);
            }

            DrawPlotText(spriteBatch, gameTime);
        }


        private void DrawScreen(SpriteBatch spriteBatch, WorldMapCell worldMapCell, GameState gameState)
        {
            Int32 maxX = worldMapCell.GetMaxTileX();
            Int32 maxY = worldMapCell.GetMaxTileY();

            //NPC & Player Prep
            List<IMoveableObject> objects = new List<IMoveableObject>();
            objects.Add(gameState.Player);

            foreach (NonPlayerCharacter npc in gameState.ActiveNonPlayerCharacters)
            {
                objects.Add(npc);
            }

            //foreach(IWeaponSprite weaponSprite in gameState.ActiveWeaponSprites)
            //{
            //    objects.Add(weaponSprite);
            //}

            foreach(Enemy enemy in gameState.ActiveEnemies)
            {
                objects.Add(enemy);
            }

            foreach (ItemSprite itemSprite in gameState.ActiveItemSprites)
            {
                objects.Add(itemSprite);
            }

            objects.Sort(new MoveableObjectComparer());

            //draw
            for (Int32 x = 0; x < maxX; x++)
            {
                for (Int32 y = 0; y < maxY; y++)
                {
                    //layer 1
                    if (worldMapCell.TilesLayer1[x][y] != null)
                    {
                        Rectangle screenDrawRect = new Rectangle(x * TileSet.DRAW_WIDTH, y * TileSet.DRAW_HEIGHT, TileSet.DRAW_WIDTH, TileSet.DRAW_HEIGHT);

                        spriteBatch.Draw(worldMapCell.TilesLayer1[x][y].GetActiveTexture(), screenDrawRect, Color.White);
                    }

                    //layer 2 - not passable
                    if (worldMapCell.TilesLayer2[x][y] != null)
                    {
                        if (worldMapCell.TilesLayer2[x][y].Passable == false)
                        {
                            Rectangle screenDrawRect = new Rectangle(x * TileSet.DRAW_WIDTH, y * TileSet.DRAW_HEIGHT, TileSet.DRAW_WIDTH, TileSet.DRAW_HEIGHT);
                            spriteBatch.Draw(worldMapCell.TilesLayer2[x][y].GetActiveTexture(), screenDrawRect, Color.White);
                        }
                    }
                }
            }

            for (Int32 y = 0; y < maxY; y++)
            {
                for (Int32 x = 0; x < maxX; x++)
                {
                    

                    //objects
                    for (int i = 0; i < objects.Count; i++)
                    {
                        IMoveableObject obj = objects[i];

                        Rectangle tileRect = new Rectangle(x * TileSet.DRAW_WIDTH, y * TileSet.DRAW_HEIGHT, TileSet.DRAW_WIDTH, TileSet.DRAW_HEIGHT);

                        if (obj.GetDrawArea().Intersects(tileRect))
                        {
                            obj.Draw(spriteBatch);

                            Boolean remove = true;
                            foreach(IMoveableObject o in objects)
                            {
                                if ((o != obj) && (obj.WorldPosition.PositionY > o.WorldPosition.PositionY))
                                {
                                    if (o.GetDrawArea().Intersects(obj.GetDrawArea())) remove = false;
                                }
                            }
                            if (remove)
                            {
                                objects.Remove(obj);
                                i--;
                            }
                        }
                    }

                    //layer 2 - passable
                    if (worldMapCell.TilesLayer2[x][y] != null)
                    {
                        if (worldMapCell.TilesLayer2[x][y].Passable)
                        {
                            Rectangle screenDrawRect = new Rectangle(x * TileSet.DRAW_WIDTH, y * TileSet.DRAW_HEIGHT, TileSet.DRAW_WIDTH, TileSet.DRAW_HEIGHT);
                            spriteBatch.Draw(worldMapCell.TilesLayer2[x][y].GetActiveTexture(), screenDrawRect, Color.White);
                        }
                    }
                }
            }

            foreach (IWeaponSprite weaponSprite in gameState.ActiveWeaponSprites)
            {
                weaponSprite.Draw(spriteBatch);
            }

            foreach (IWeaponSprite displaySprite in gameState.ActiveDisplaySprites)
            {
                displaySprite.Draw(spriteBatch);
            }
        }


        private void DrawPlotText(SpriteBatch spriteBatch, GameTime gameTime)
        {
            PlotItem plotItem = this.gameData.GameState.ActivatedPlotItem;

            if ((plotItem != null) && (plotItem.Type == PlotItem.Types.Text))
            {
                Texture2D dialog = rawContentManager.TextureRepository.GetContent(@"textures\ui\dialog-event");
                Rectangle dialogRect = new Rectangle(105,200,494,148);
                
                spriteBatch.Draw(dialog, dialogRect, Color.White);

                SpriteFont textFont = rawContentManager.FontRepository.GetContent(@"fonts\Normal");
                String text = plotItem.Value;

                Vector2 textPosition = new Vector2(126, 220);
                spriteBatch.DrawString(textFont, TextHelper.GetCroppedText(text, textFont, 460), textPosition, Color.White);   
            }
        }


        public void Press(GameTime gameTime)
        {
            
        }


        public void Update(GameTime gameTime)
        {
            gameData.Update(gameTime);

            playerHud.Update(gameTime);

            CheckForMusicChange();
        }


        private void CheckForMusicChange() 
        {
            WorldPosition p = this.GameData.GameState.Player.WorldPosition;
            Int32 songKey = this.GameData.GetWorldMapCell(p).SongKey;
            Song song = this.rawContentManager.SongRepository.GetContent(songKey);

            if(song != this.screenController.BackgroundMusic) 
            {
                MediaPlayer.Stop();
                MediaPlayer.IsRepeating = true;
                MediaPlayer.Play(song);

                this.screenController.BackgroundMusic = song;
            }
        }


        private void Init()
        {
            playerHud = new PlayerHud(this.rawContentManager, 0, this.screenController.Resolution.GameHeight - TileSet.DRAW_HEIGHT, resolution.GameWidth, TileSet.DRAW_HEIGHT);
            Controls.Add(playerHud);
        }

    }
}
