package speiger.src.coreengine.rendering.inputOld.bindings;

import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;

import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.inputOld.bindings.utils.BindingRegistry;
import speiger.src.coreengine.rendering.inputOld.bindings.utils.BindingType;
import speiger.src.coreengine.rendering.inputOld.bindings.utils.ModType;

public class InputBinding
{
	public static final BindingRegistry BINDINGS = new BindingRegistry();
//	public static final InputBinding SCREEN_SHOT = new InputBinding("misc", "Screenshot", GLFW.GLFW_KEY_F12, ModType.NONE);
//	public static final InputBinding GIF_RECORDING = new InputBinding("misc", "GifRecording", GLFW.GLFW_KEY_F12, ModType.SHIFT);
//	public static final InputBinding RELOAD_RENDERING = new InputBinding("misc", "Reload Rendering", GLFW.GLFW_KEY_F8);
//	public static final InputBinding TOGGLE_UI = new InputBinding("UI", "ToggleUI", GLFW.GLFW_KEY_F11);
//	public static final InputBinding TOGGLE_DEBUG = new InputBinding("UI", "ToggleDebug", GLFW.GLFW_KEY_F10, ModType.NONE);
//	public static final InputBinding TOGGLE_RELOAD = new InputBinding("UI", "ToggleUIReload", GLFW.GLFW_KEY_F10, ModType.SHIFT);
//	public static final InputBinding LAST_UI = new InputBinding("UI", "OpenLastUI", GLFW.GLFW_KEY_F9);
	public static final InputBinding MOUSE_ROTATION = new InputBinding("Camera", "Mouse Rotation", 2, BindingType.MOUSE, ModType.IGNORE);
	public static final InputBinding MOUSE_MOVEMENT = new InputBinding("Camera", "Mouse Movement", 1, BindingType.MOUSE, ModType.IGNORE);
//	public static final InputBinding TOGGLE_GRID = new InputBinding("misc", "Toggle Terrain Grid", GLFW.GLFW_KEY_F2, ModType.NONE);
//	public static final InputBinding TOGGLE_LOG_RAYCAST = new InputBinding("misc", "Toggle Log Raycast", GLFW.GLFW_KEY_SCROLL_LOCK);
//	public static final InputBinding TOGGLE_FRUSTUM = new InputBinding("debug", "Toggle Frustum", GLFW.GLFW_KEY_PAUSE);
	
	String category;
	String bindingName;
	BindingType binding;
	int mod;
	int currentKey;
	
	BindingType defaultBinding;
	int defaultMod;
	int defaultKey;
	
	boolean pressed;
	int timePressed;
	List<Consumer<InputBinding>> listeners = new ObjectArrayList<>();
	
	public InputBinding(String category, String name, int key)
	{
		this(category, name, key, BindingType.KEYBOARD, ModType.IGNORE);
	}
	
	public InputBinding(String category, String name, int key, BindingType type)
	{
		this(category, name, key, type, ModType.IGNORE);
	}
	
	public InputBinding(String category, String name, int key, int mod)
	{
		this(category, name, key, BindingType.KEYBOARD, mod);
	}
	
	public InputBinding(String theCategory, String name, int key, BindingType type, int modType)
	{
		category = theCategory;
		bindingName = name;
		defaultKey = key;
		currentKey = key;
		defaultBinding = type;
		binding = type;
		defaultMod = modType;
		mod = modType;
		BINDINGS.registerBinding(this);
	}
	
	public String getBindingName()
	{
		return bindingName;
	}
	
	public int getKey()
	{
		return currentKey;
	}
	
	public BindingType getInputType()
	{
		return binding;
	}
	
	public int getMod()
	{
		return mod;
	}
	
	public void setKey(int id)
	{
		BINDINGS.removeBinding(this);
		currentKey = id;
		BINDINGS.registerBinding(this);
	}
	
	public void setMod(int type)
	{
		mod = type;
	}
	
	public void setBinding(BindingType type)
	{
		BINDINGS.removeBinding(this);
		binding = type;
		BINDINGS.registerBinding(this);
	}
	
	public void addListener(Consumer<InputBinding> listener)
	{
		listeners.add(listener);
	}
	
	public void reset()
	{
		BINDINGS.removeBinding(this);
		currentKey = defaultKey;
		mod = defaultMod;
		binding = defaultBinding;
		BINDINGS.registerBinding(this);
	}
	
	public void setPressed(boolean newPressed)
	{
		pressed = newPressed && ModType.isActive(mod);
		timePressed = pressed ? timePressed + 1 : 0;
		if(pressed && listeners.size() > 0)
		{
			for(int i = 0,m=listeners.size();i<m;i++)
			{
				listeners.get(i).accept(this);
			}
		}
	}
	
	public boolean isPressed()
	{
		return pressed;
	}
	
	public boolean isStillPressed()
	{
		if(timePressed == 0) return false;
		timePressed--;
		return true;
	}
	
	public void unPressBinding()
	{
		timePressed = 0;
		pressed = false;
	}
	
	@Override
	public int hashCode()
	{
		return Objects.hash(bindingName, defaultKey);
	}
	
	@Override
	public boolean equals(Object obj)
	{
		if(obj instanceof InputBinding)
		{
			InputBinding bind = (InputBinding)obj;
			return bind.bindingName.equals(bindingName) && bind.defaultKey == defaultKey;
		}
		return false;
	}
}
