using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SFML.Window;
using SFML.Graphics;
using System.Reflection;
using YourBeatingHeart.Main.States.Play.Entities;
using YourBeatingHeart.Main.States;

namespace YourBeatingHeart.Main.Managers
{
    public class LiveTweakingManager
    {
        const Keyboard.Key ENABLE_KEY = Keyboard.Key.F1;

        delegate void AttributeChanger();
        public delegate object VariableGetter();
        
        
        Dictionary<Keyboard.Key, AttributeChanger> AttributeMapping;
        Dictionary<string, VariableGetter> VariableWatches;
        GameState state;
        Text txt;

        bool isEnabled = true;

        public LiveTweakingManager(GameState _state)
        {
            state = _state;
            state.Window.KeyPressed += OnKeyDown;
            txt = new Text("", Constants.DEFAULT_FONT);

            //WARNING: Enable/Disable key is F1
            AttributeMapping = new Dictionary<Keyboard.Key,AttributeChanger>()
            {
                {Keyboard.Key.Num4, ()=>{Constants.GRAVITY += 10;}},
                {Keyboard.Key.R, ()=>{Constants.GRAVITY -= 10;}},
                {Keyboard.Key.Num5, ()=>{Constants.PLAYER_WALK_SPEED += 5;}},
                {Keyboard.Key.T, ()=>{Constants.PLAYER_WALK_SPEED -= 5;}},
                {Keyboard.Key.Num6, ()=>{Constants.PLAYER_JUMP_IMPULSE += 5;}},
                {Keyboard.Key.Z, ()=>{Constants.PLAYER_JUMP_IMPULSE -= 5;}}
            };

            VariableWatches = new Dictionary<string, VariableGetter>()
            {
                {"Gravity", ()=>{return Constants.GRAVITY;}},
                {"Walk Speed", ()=>{return Constants.PLAYER_WALK_SPEED;}},
                {"Jump Impulse", ()=>{return Constants.PLAYER_JUMP_IMPULSE;}}
            };
        }

        public void AddWatch(string _name, VariableGetter _getter)
        {
            VariableWatches[_name] = _getter;
        }

        public void RemoveWatch(string _name)
        {
            VariableWatches.Remove(_name);
        }


        public void Draw(RenderTarget _renderTarget)
        {
            if (!Constants.DEBUG)
                return;

            if (!isEnabled)
                return;

            txt.Position = new Vector2f(20, 20);
            foreach (var watch in VariableWatches)
            {
                txt.DisplayedString = watch.Key + ": " + watch.Value().ToString();
                txt.Position += new Vector2f(0, 30);
                _renderTarget.Draw(txt);
            }
        }

        public void Destroy()
        {
            state.Window.KeyPressed -= OnKeyDown;
            state = null;
        }

        public void OnKeyDown(object _sender, KeyEventArgs _args)
        {
            if (_args.Code == ENABLE_KEY)
                isEnabled = !isEnabled;

            if (isEnabled && AttributeMapping.ContainsKey(_args.Code))
                AttributeMapping[_args.Code]();
        }     
    }
}
