package com.forgeessentials.util.questioner;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import com.forgeessentials.core.misc.FECommandManager;
import com.forgeessentials.core.misc.Translator;
import com.forgeessentials.util.events.ServerEventHandler;
import com.forgeessentials.util.output.ChatOutputHandler;

import net.minecraft.command.ICommandSender;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;

public class Questioner extends ServerEventHandler {

	public static final String MSG_STILL_ACTIVE = "Error. There is still an unanswered question left";

	private static Map<ICommandSender, QuestionData> questions = new HashMap<>();

	public static int DEFAULT_TIMEOUT = 120;

	public static void add(ICommandSender target, String question, QuestionerCallback callback)
			throws QuestionerStillActiveException {
		add(target, question, callback, DEFAULT_TIMEOUT);
	}

	public static void add(ICommandSender target, String question, QuestionerCallback callback, int timeout)
			throws QuestionerStillActiveException {
		add(target, question, callback, timeout, null);
	}

	public static void add(ICommandSender target, String question, QuestionerCallback callback, int timeout,
			ICommandSender source) throws QuestionerStillActiveException {
		add(new QuestionData(target, question, callback, timeout, source));
	}

	public static synchronized void add(QuestionData question) throws QuestionerStillActiveException {
		if (questions.containsKey(question.getTarget())) {
			throw new QuestionerStillActiveException();
		}
		questions.put(question.getTarget(), question);
		question.sendQuestion();
	}

	public static void addChecked(ICommandSender target, String question, QuestionerCallback callback)
			throws QuestionerStillActiveException.CommandException {
		try {
			add(target, question, callback, DEFAULT_TIMEOUT);
		} catch (QuestionerStillActiveException e) {
			throw new QuestionerStillActiveException.CommandException();
		}
	}

	public static void addChecked(ICommandSender target, String question, QuestionerCallback callback, int timeout)
			throws QuestionerStillActiveException.CommandException {
		try {
			add(target, question, callback, timeout, null);
		} catch (QuestionerStillActiveException e) {
			throw new QuestionerStillActiveException.CommandException();
		}
	}

	public static void addChecked(ICommandSender target, String question, QuestionerCallback callback, int timeout,
			ICommandSender source) throws QuestionerStillActiveException.CommandException {
		try {
			add(new QuestionData(target, question, callback, timeout, source));
		} catch (QuestionerStillActiveException e) {
			throw new QuestionerStillActiveException.CommandException();
		}
	}

	public static synchronized void answer(ICommandSender target, Boolean answer) {
		QuestionData question = questions.remove(target);
		if (question != null) {
			question.doAnswer(answer);
		} else {
			ChatOutputHandler.chatError(target, Translator.translate("There is no question to answer!"));
		}
	}

	public static void cancel(ICommandSender target) {
		answer(target, null);
	}

	public static void confirm(ICommandSender target) {
		answer(target, true);
	}

	public static void deny(ICommandSender target) {
		answer(target, false);
	}

	public static synchronized void tick() {
		Iterator<Entry<ICommandSender, QuestionData>> it = questions.entrySet().iterator();
		while (it.hasNext()) {
			Entry<ICommandSender, QuestionData> question = it.next();
			if (question.getValue().isTimeout()) {
				it.remove();
				question.getValue().doAnswer(null);
			}
		}
	}

	public Questioner() {
		super();
		FECommandManager.registerCommand(new CommandQuestioner(true));
		FECommandManager.registerCommand(new CommandQuestioner(false));
	}

	@SubscribeEvent
	public void tickStart(TickEvent.ServerTickEvent event) {
		if (event.phase == Phase.START) {
			tick();
		}
	}

}

@@ -361,24 +361,71 @@
 utHandler;%0A%0A
+import net.minecraft.command.CommandException;%0A
 import net.m
@@ -580,16 +580,80 @@
 ckEvent;
+%0Aimport net.minecraftforge.fml.common.gameevent.TickEvent.Phase;
 %0A%0Apublic
@@ -3012,16 +3012,40 @@
  answer)
+ throws CommandException
  %7B%0A%09%09Que
@@ -3304,32 +3304,56 @@
 ndSender target)
+ throws CommandException
  %7B%0A%09%09answer(targ
@@ -3409,32 +3409,56 @@
 ndSender target)
+ throws CommandException
  %7B%0A%09%09answer(targ
@@ -3519,16 +3519,40 @@
  target)
+ throws CommandException
  %7B%0A%09%09ans
@@ -3614,16 +3614,40 @@
 d tick()
+ throws CommandException
  %7B%0A%09%09Ite
@@ -4166,16 +4166,40 @@
 t event)
+ throws CommandException
  %7B%0A%09%09if 

fix questioner