#include <spcf/core.hpp>
#include <spcf/engine-factory/EngineFactory.hpp>
#include <spcf/grammar/GrammarCommonImpl.hpp>
#include <spcf/grammar/NumeralGrammar.hpp>
#include <spcf/processor/DefaultProcessor.hpp>
#include <spcf/view/DefaultView.hpp>

#include <iostream>
#include <string>

using namespace spcf;
using namespace std;

class CalculatorGrammar : public GrammarCommonImpl {
public:
	CalculatorGrammar() : GrammarCommonImpl("calculator") {
		Grammar::State s1("s1");
		Grammar::State s2("s2");

		addGrammarTransition("いち", "number1", 1, Grammar::START_STATE_NAME, s1);
		addGrammarTransition("に", "number1", 2, Grammar::START_STATE_NAME, s1);
		addGrammarTransition("さん", "number1", 3, Grammar::START_STATE_NAME, s1);
		addGrammarTransition("よん", "number1", 4, Grammar::START_STATE_NAME, s1);
		addGrammarTransition("しー", "number1", 4, Grammar::START_STATE_NAME, s1);
		addGrammarTransition("ごー", "number1", 5, Grammar::START_STATE_NAME, s1);
		addGrammarTransition("ろく", "number1", 6, Grammar::START_STATE_NAME, s1);
		addGrammarTransition("なな", "number1", 7, Grammar::START_STATE_NAME, s1);
		addGrammarTransition("しち", "number1", 7, Grammar::START_STATE_NAME, s1);
		addGrammarTransition("はち", "number1", 8, Grammar::START_STATE_NAME, s1);
		addGrammarTransition("きゅう", "number1",9, Grammar::START_STATE_NAME, s1);

		addGrammarTransition("たす", "operator", "+", s1, s2);
		addGrammarTransition("ひく", "operator", "-", s1, s2);
		addGrammarTransition("かける", "operator", "*", s1, s2);
		addGrammarTransition("わる", "operator", "/", s1, s2);

		addGrammarTransition("いち", "number2", 1, s2, Grammar::FINISH_STATE_NAME);
		addGrammarTransition("に", "number2", 2, s2, Grammar::FINISH_STATE_NAME);
		addGrammarTransition("さん", "number2", 3, s2, Grammar::FINISH_STATE_NAME);
		addGrammarTransition("よん", "number2", 4, s2, Grammar::FINISH_STATE_NAME);
		addGrammarTransition("しー", "number2", 4, s2, Grammar::FINISH_STATE_NAME);
		addGrammarTransition("ごー", "number2", 5, s2, Grammar::FINISH_STATE_NAME);
		addGrammarTransition("ろく", "number2", 6, s2, Grammar::FINISH_STATE_NAME);
		addGrammarTransition("なな", "number2", 7, s2, Grammar::FINISH_STATE_NAME);
		addGrammarTransition("しち", "number2", 7, s2, Grammar::FINISH_STATE_NAME);
		addGrammarTransition("はち", "number2", 8, s2, Grammar::FINISH_STATE_NAME);
		addGrammarTransition("きゅう", "number2",9, s2, Grammar::FINISH_STATE_NAME);
	}
};

class CalculatorProcessor : public DefaultProcessor {
public:
	void start(Context& context) {
		getController().getEngine()->addGrammar(GrammarPtr(new CalculatorGrammar()));
	}

	void recognized(Context& context, Recognition& recognition) {
		getController().stop();
	}
};

class CalculatorView : public DefaultView {
	void start(Context& context) {
		cout << "start" << endl;
	}

	void soundStarted(Context& context) {
		cout << "soundStarted" << endl;
	}

	void soundStoped(Context& context) {
		cout << "soundStoped" << endl;
	}

	void recognized(Context& context, Recognition& recognition) {
		int number1 = recognition.getProperty("number1")->getInt();
		string op = recognition.getProperty("operator")->getString();
		int number2 = recognition.getProperty("number2")->getInt();

		cout << number1 << op << number2 << "=";
		if (op== "+") {
			cout << number1 + number2;
		} else if (op == "-") {
			cout << number1 - number2;
		} else if (op == "*") {
			cout << number1 * number2;
		} else if (op == "/") {
			cout << (double(number1) / double(number2));
		}
		cout << endl;
	}
};

int main() {
	Controller controller;
	controller.setEngine(EngineFactory::getEngine(EngineFactory::SAPI_ENGINE));
	controller.setProcessor(ProcessorPtr(new CalculatorProcessor()));
	controller.setView(ViewPtr(new CalculatorView()));
	controller.start();

	return 0;
}
