package mezz.jei.input;

import java.awt.Color;
import java.awt.Rectangle;
import java.util.LinkedList;
import java.util.List;

import mezz.jei.config.Config;
import mezz.jei.gui.ingredients.IIngredientListElement;
import mezz.jei.ingredients.IngredientFilter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiTextField;
import net.minecraftforge.fml.client.config.HoverChecker;
import org.lwjgl.input.Keyboard;

public class GuiTextFieldFilter extends GuiTextField {
	private static final int MAX_HISTORY = 100;
	private static final int maxSearchLength = 128;
	private static final List<String> history = new LinkedList<String>();

	private final HoverChecker hoverChecker;
	private final IngredientFilter ingredientFilter;
	private boolean previousKeyboardRepeatEnabled;

	public GuiTextFieldFilter(int componentId, IngredientFilter ingredientFilter) {
		super(componentId, Minecraft.getMinecraft().fontRenderer, 0, 0, 0, 0);
		setMaxStringLength(maxSearchLength);
		this.hoverChecker = new HoverChecker(0, 0, 0, 0, 0);
		this.ingredientFilter = ingredientFilter;
	}

	public void updateBounds(Rectangle area) {
		this.xPosition = area.x;
		this.yPosition = area.y;
		this.width = area.width;
		this.height = area.height;
		this.hoverChecker.updateBounds(area.y, area.y + area.height, area.x, area.x + area.width);
	}

	public void update() {
		setText(Config.getFilterText());
		List<IIngredientListElement> ingredientList = ingredientFilter.getIngredientList();
		if (ingredientList.size() == 0) {
			setTextColor(Color.red.getRGB());
		} else {
			setTextColor(Color.white.getRGB());
		}
	}

	@Override
	public boolean textboxKeyTyped(char typedChar, int keyCode) {
		boolean handled = super.textboxKeyTyped(typedChar, keyCode);
		if (!handled && !history.isEmpty()) {
			if (keyCode == Keyboard.KEY_UP) {
				String currentText = getText();
				int historyIndex = history.indexOf(currentText);
				if (historyIndex < 0) {
					if (saveHistory()) {
						historyIndex = history.size() - 1;
					} else {
						historyIndex = history.size();
					}
				}
				if (historyIndex > 0) {
					String historyString = history.get(historyIndex - 1);
					setText(historyString);
					handled = true;
				}
			} else if (keyCode == Keyboard.KEY_DOWN) {
				String currentText = getText();
				int historyIndex = history.indexOf(currentText);
				if (historyIndex >= 0) {
					String historyString;
					if (historyIndex + 1 < history.size()) {
						historyString = history.get(historyIndex + 1);
					} else {
						historyString = "";
					}
					setText(historyString);
					handled = true;
				}
			} else if (keyCode == Keyboard.KEY_RETURN) {
				saveHistory();
			}
		}
		return handled;
	}

	public boolean isMouseOver(int mouseX, int mouseY) {
		return hoverChecker.checkHover(mouseX, mouseY);
	}

	public boolean handleMouseClicked(int mouseX, int mouseY, int mouseButton) {
		if (mouseButton == 1) {
			setText("");
			return Config.setFilterText("");
		} else {
			super.mouseClicked(mouseX, mouseY, mouseButton);
		}
		return false;
	}

	@Override
	public void setFocused(boolean keyboardFocus) {
		final boolean previousFocus = isFocused();
		super.setFocused(keyboardFocus);

		if (previousFocus != keyboardFocus) {
			if (keyboardFocus) {
				previousKeyboardRepeatEnabled = Keyboard.areRepeatEventsEnabled();
				Keyboard.enableRepeatEvents(true);
			} else {
				Keyboard.enableRepeatEvents(previousKeyboardRepeatEnabled);
			}

			saveHistory();
		}
	}

	private boolean saveHistory() {
		String text = getText();
		if (text.length() > 0) {
			history.remove(text);
			history.add(text);
			if (history.size() > MAX_HISTORY) {
				history.remove(0);
			}
			return true;
		}
		return false;
	}
}

@@ -1406,24 +1406,36 @@
 () %7B%0D%0A%09%09
-set
+String filter
 Text
-(
+ = 
 Config.g
@@ -1448,18 +1448,87 @@
 erText()
-)
 ;
+%0D%0A%09%09if (!filterText.equals(getText())) %7B%0D%0A%09%09%09setText(filterText);%0D%0A%09%09%7D
 %0D%0A%09%09List

Fix #963 Filter curser always jumps to the end when you type