package FIT;

import java.lang.reflect.Constructor;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;

import edu.wpi.cetask.*;
import edu.wpi.cetask.guide.*;

public class Agent {
	
	private AgentGUI gui;
	private Guide guide;
	private Composite menu;
	private Plan goal;
	
	public static void main(String[] args) throws Throwable {
		
		if (args.length < 2) {
			System.out.println("Required arguments: project and top-level task");
			return;
		}
		
		Agent agt = new Agent();
		agt.gui = AgentGUI.getInstance(agt);
		agt.gui.showGUI();
		
		agt.guide = new Guide(null);
		
		agt.guide.load("FIT/" + args[0] + ".xml");
		agt.guide.processCommand("task " + args[1]);
		String welc = agt.prop("Welcome");
		welc += "\nLet's begin to " + agt.format(agt.guide.getEngine().getFocus()) + ".";
		agt.gui.showResponse(welc);
		agt.setDisplay();
		agt.gui.loop();
	}
	
	private void getToLeaf () {
		if (guide.getEngine().getFocus() == null) {
			taskDone("");
		} else {
			String task = guide.getEngine().getFocus().toString();
			String display = prop(task + "@display");
			if (display == null) {
				System.out.println("Moving down");
				guide.next("");
				getToLeaf();
			} else {
				System.out.println(task);
			}
		}
	}
	
	private void taskDone(String t) {
		gui.showResponse("Congratulations! You successfully learned how to " + t);
		gui.loop();
	}

	private void setDisplay () {
		if (menu != null) menu.dispose();
		getToLeaf();
		String task = guide.getEngine().getFocus().toString();
		String display = prop(task + "@display");
		String form = prop(display + "@form");
		if (form != null) {
			try {
				Class newMenu = Class.forName("FIT.Menus." + form);
				Constructor[] c = newMenu.getConstructors();
				int num = 0, rows = 0;
				if (prop(display + "@num") != null) num = Integer.parseInt(prop(display + "@num"));
				if (prop(display + "@rows") != null) rows = Integer.parseInt(prop(display + "@rows"));
				String[] labels = new String[num], tasks = new String[num];
				for (int i = 0; i < labels.length; i++) {
					labels[i] = prop(display + "@label" + (i+1));
					tasks[i] = prop(display + "@task" + (i+1));
				}
				menu = (Composite)c[0].newInstance(gui, SWT.NONE, num, rows, labels, tasks);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			System.out.println("Couldn't find a display");
		}
	}
	

	
	private void showResponse () {
		String response = guide.response;
		gui.showResponse(response);
	}
	
	public void next () {
		guide.next("");
		showResponse();
	}
	
	private Plan whyfocus;
	
	public void why () {
		String resp;
		if (whyfocus == null || whyfocus.toString().equals("#")) whyfocus = guide.getEngine().getFocus();
		if (whyfocus.getParent() == null || whyfocus.getParent().toString().equals("#")) {
			resp = "Our primary goal is to learn how to " + format(whyfocus) + ".";
		} else {
			resp = "We need to " + format(whyfocus) + " in order to " + format(whyfocus.getParent()) + ".";
		}
		gui.showResponse(resp);
		whyfocus = whyfocus.getParent();
	}

	public void handleText(String text) {
		if (text == null || text.equals("")) {
			gui.showResponse("Please enter your input in the text field.");
		} else {
			guide.done("/ \"" + text + "\"");
			whyfocus = null;
			gui.showResponse("Good. Let's continue.");
			setDisplay();
		}
	}

	public void handleButton(String task) {
		String p = prop(guide.getEngine().getFocus() + "@type");
		if (p != null && p.equals("decomposition")) {
			guide.by(task);
			whyfocus = null;
			gui.showResponse("Good. Let's continue.");
			setDisplay();
		} else if (p != null && p.equals("input")) {
			handleText(task);
		} else {
			guide.done(task);
			if (guide.response.contains("Ok")) {
				whyfocus = null;
				gui.showResponse("Good. Let's continue.");
				setDisplay();
			} else if (guide.response.contains("Completed")) {
				menu.dispose();
				String t = guide.response.substring("Completed ".length());
				taskDone(t);
			} else {
				gui.showResponse("That won't help us " + format(guide.getEngine().getFocus().getParent()) + ".");
			}
		}
	}
	
	private String prop (String key) {
		return guide.getEngine().getProperty(key);
	}
	
	private String format(Plan p) {
		String f;
		if (p.toString().contains(" ")) {
			String a = p.toString().substring(0, p.toString().indexOf(" "));
			String b = p.toString().substring(p.toString().indexOf(" "));
			f = prop(a + "@format") + b;
		} else {
			f = prop(p.toString() + "@format");
		}
		if (f != null) { return f; }
		else { return p.toString(); }
	}

}
