using Igdc.Extensions;
using Igdc.Fonts;
using Igdc.Scenes;
using Igdc.State;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;

namespace Igdc
{
    public class IgdcGame : Game
    {
        public static IgdcGame Current { get; private set; }

        public Texture2D FlatTexture { get; private set; }
        public FontBase BasicFont { get; private set; }

        public GameState State { get; private set; }

        public int Transition;

        public int ButtonTimeout => _scene.ButtonTimeout;

        private GraphicsDeviceManager _manager;
        private SceneBase _scene;
        private SceneBase _next;
        private bool _withHistory;

        private MapDto _debugMap;

        public IgdcGame()
        {
            Current = this;
            IsMouseVisible = true;
            _manager = new GraphicsDeviceManager(this);
        }

        public IgdcGame(MapDto map)
        {
            _debugMap = map;
            Current = this;
            IsMouseVisible = true;
            _manager = new GraphicsDeviceManager(this);
        }

        public void Load() => Initialize();
        public void Navigate<T1>(object package, bool withHistory = true, bool withTransition = true) where T1 : SceneBase
        {
            _next = (SceneBase)Activator.CreateInstance(typeof(T1), _manager, GraphicsDevice, package);
            Transition = withTransition ? 160 : 10;
            _withHistory = withHistory;
        }

        public void NavigateBack()
        {
            if (_scene.Parent == null) return;
            _next = _scene.Parent;
            Transition = 160;
        }
        
        protected override void Initialize()
        {
            State = new GameState();
            State.Player.Good = 10;
            State.Player.Evil = 12;

            base.Initialize();
            FlatTexture = GraphicsDevice.ReadTexture2D("dot");
            BasicFont = new Candara10(GraphicsDevice);
            TargetElapsedTime = TimeSpan.FromMilliseconds(1000 / 30); // Set 30 FPS
            if (_debugMap == null)
                Navigate<StartScene>(null);
            else
                Navigate<MapScene>(new MapPackage
                {
                    Background = 1,
                    Map = _debugMap.ToMap()
                });
        }

        protected override void UnloadContent()
        {
            FlatTexture.Dispose();
            BasicFont.Dispose();
            base.UnloadContent();
        }

        protected override void Update(GameTime gameTime)
        {
            if (Transition <= 0) _scene?.Update(gameTime);
            else
            {
                Transition -= 10;
                if (Transition <= 0)
                {
                    var scene = _scene;
                    _scene = _next;
                    _scene.Parent = _withHistory ? scene : scene?.Parent;
                }
            }
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            _scene?.Draw(gameTime);
            base.Draw(gameTime);
        }
    }
}