/*
	Copyright 2009 Robin Vobruba <hoijui.quaero@gmail.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

	@author Robin Vobruba <hoijui.quaero@gmail.com>
*/

#include "AIExport.h"

#include "ExternalAI/Interface/AISEvents.h"
// generated by the C++ Wrapper scripts
#include "AI/Wrappers/Cpp/src-generated/OOAICallback.h"
#include "AI/Wrappers/Cpp/src-generated/WrappOOAICallback.h"

#include "CppTestAI.h"

#include <stdexcept>
#include <map>

static std::map<int, cpptestai::CCppTestAI*> myAIs;
static std::map<int, springai::OOAICallback*>  myAICallbacks;

const static int ERROR_SHIFT = 100;

#define CATCH_CPP_AI_EXCEPTION(RETURN_VAR)					\
	catch (int err) {										\
		RETURN_VAR = err;									\
	} catch (const std::exception& e) {						\
		RETURN_VAR = ERROR_SHIFT + 2;						\
	} catch (const std::string& s) {						\
		RETURN_VAR = ERROR_SHIFT + 3;						\
	} catch (const char* s) {								\
		RETURN_VAR = ERROR_SHIFT + 4;						\
	} catch (...) {											\
		RETURN_VAR = ERROR_SHIFT + 5;						\
	}

EXPORT(int) init(int skirmishAIId, const struct SSkirmishAICallback* innerCallback) {

	int ret = ERROR_SHIFT + 1;

	try {
		springai::OOAICallback* clb = springai::WrappOOAICallback::GetInstance(innerCallback, skirmishAIId);
		cpptestai::CCppTestAI* ai = new cpptestai::CCppTestAI(clb);

		myAIs[skirmishAIId] = ai;
		myAICallbacks[skirmishAIId] = clb;

		ret = 0;
	} CATCH_CPP_AI_EXCEPTION(ret);

	return ret; // (ret != 0) => error
}

EXPORT(int) release(int skirmishAIId) {

	int ret = ERROR_SHIFT + 1;

	try {
		springai::OOAICallback* clb = myAICallbacks[skirmishAIId];
		myAICallbacks.erase(skirmishAIId);

		cpptestai::CCppTestAI* ai = myAIs[skirmishAIId];
		myAIs.erase(skirmishAIId);

		delete ai;
		delete clb;

		ret = 0;
	} CATCH_CPP_AI_EXCEPTION(ret);

	return ret; // (ret != 0) => error
}

EXPORT(int) handleEvent(int skirmishAIId, int topic, const void* data) {

	int ret = ERROR_SHIFT + 1;

	try {
		ret = myAIs[skirmishAIId]->HandleEvent(topic, data);
	} CATCH_CPP_AI_EXCEPTION(ret);

	return ret; // (ret != 0) => error
}
