﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using System.Reflection;
using Gaazar;

namespace Gaazar
{
    public interface INettedInputReceriver
    {
        void ButtonDown(string buttonName);
        void ButtonUp(string buttonName);
        void AxisChange(string buttonName,Vector2 daxis);
        Vector2 axis { get; set; }
    }

    public class NettedInput
    {
        public void PostButtonDown(string buttonName)
        {

        }
        public void PostButtonUp(string buttonName)
        {

        }
        public void PostAxis(string buttonName, Vector2 daxis)
        {

        }
        public void PostAxisChange(string buttonName, Vector2 axis)
        {

        }
    }

}
struct Vector2Mapper
{
    public string x, y;
    static public Vector2Mapper NewV2M(string x_,string y_)
    {
        Vector2Mapper v = new Vector2Mapper();
        v.x = x_;
        v.y = y_;
        return v;
    }
}
public class NettedInputManager : MonoBehaviour
{
    public static NettedInputManager current;
    Stack<InputHandler> inputeReceiver = new Stack<InputHandler>();
    Type[] handledTypes;
    Dictionary<string, Vector2Mapper> v2Map = new Dictionary<string, Vector2Mapper>() {
        { "LeftAxis",Vector2Mapper.NewV2M("LeftXAxis","LeftYAxis")},
        { "RightAxis",Vector2Mapper.NewV2M("RightXAxis","RightYAxis") }
    };
    public void Push(InputHandler ih)
    {
        inputeReceiver.Push(ih);
    }
    private void Start()
    {
        current = this;
        Type iHtype = typeof(InputHandler);
        List<Type> types = new List<Type>();

        //foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            foreach (var type in Assembly.GetExecutingAssembly().GetTypes()) // assembly.GetTypes()
            {
                if (type.IsSubclassOf(iHtype))
                {
                    //Debug.Log(type.Name);

                    //if (type.IsClass && !type.IsAbstract)
                    {
                        types.Add(type);
                    }
                }
            }
        }
        handledTypes = types.ToArray();
        types.ForEach((t)=> {
            var mfs = t.GetFields(BindingFlags.Instance|BindingFlags.NonPublic);  
            foreach (var i in mfs)
            {
                //Debug.Log(i.Name);

                if (i.GetCustomAttribute<InputAttribute>() != null)
                {
                    
                }
            }
        });

    }
    private void Update()
    {
        
        InputHandler icurrent = inputeReceiver.Peek();
        foreach (var i in icurrent.keyName)
        {
            if (i.Key == "LeftAxis")
            {
                icurrent.PostInput(i.Value,new Vector2(Input.GetAxis("LeftXAxis"), Input.GetAxis("LeftYAxis")));
            }
            if (i.Key == "RightAxis")
            {
                icurrent.PostInput(i.Value, new Vector2(Input.GetAxis("RightXAxis"), Input.GetAxis("RightYAxis")));
            }

        }
    }

}

namespace Gaazar
{
    [AttributeUsage(AttributeTargets.Method|AttributeTargets.Field, AllowMultiple = true, Inherited = true)]
    public class InputAttribute:Attribute
    {
        public string _name;
        public InputType _type;
        public string _key;
        

        public InputAttribute(string name="none", InputType type=InputType.Button,string defaultKey_ = "")
        {
            _name = name;
            _type = type;
            _key = defaultKey_;
        }
    }
    public class InputHandlerAttribute : Attribute
    {
        public string _name;
        public InputMode _type;

        public InputHandlerAttribute(string name)
        {
            _name = name;
            _type = InputMode.Override ;
        }
        public InputHandlerAttribute(string name, InputMode type)
        {
            _name = name;
            _type = type;
        }
    }

    public enum InputType
    {
        Button,Axis
    }
    public enum InputMode
    {
        Override, Additive
    }
    public enum ButtonEvent
    {
        Down,Up,Hold
    }
}


