#include "cocos2d.h"
#include "CCEGLView.h"
#include "AppDelegate.h"
#include "CCLuaEngine.h"
#include "SimpleAudioEngine.h"
#include "Lua_extensions_CCB.h"
#include "FuncellGameSdkProxy.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "Lua_web_socket.h"
#endif

using namespace CocosDenshion;

USING_NS_CC;

FuncellSession *mSession;

extern "C" {
	lua_State *Funcell_Lua_State;
	int doFuncellInit(lua_State *L);
	int doFuncellLogin(lua_State *L);
	int doFuncellLogout(lua_State *L);
	int doFuncellPay(lua_State *L);
	int doFuncellExit(lua_State *L);
	int doFuncellGetExitUI(lua_State *L);
	int setLoginEventCallback(lua_State *L);
	int setRoleLevelUpEventCallback(lua_State *L);
	int setCreatRoleEventCallback(lua_State *L);
	int setServer_RoleEventCallback(lua_State *L);
}

void registerFuncellLuaMethod(lua_State *L) {
	lua_register(L, "doFuncellInit", doFuncellInit);
	lua_register(L, "doFuncellLogin", doFuncellLogin);
	lua_register(L, "doFuncellLogout", doFuncellLogout);
	lua_register(L, "doFuncellPay", doFuncellPay);
	lua_register(L, "doFuncellExit", doFuncellExit);
	lua_register(L, "doFuncellGetExitUI", doFuncellGetExitUI);
	lua_register(L, "setLoginEventCallback", setLoginEventCallback);
	lua_register(L, "setRoleLevelUpEventCallback", setRoleLevelUpEventCallback);
	lua_register(L, "setCreatRoleEventCallback", setCreatRoleEventCallback);
	lua_register(L, "setServer_RoleEventCallback", setServer_RoleEventCallback);
}

void initFuncellLuaEnvironment(lua_State *L) {
	Funcell_Lua_State = L;
	registerFuncellLuaMethod(Funcell_Lua_State);
}


/***************SDK通知回调接口**********************/

class InitCallBackImpl : public IFuncellInitCallBack{
public:
	virtual void onInitSuccess(){
		CCLOG("SDK  onInitSuccess \n");

		lua_getglobal(Funcell_Lua_State, "onFuncellLuaInitSuccess");
		lua_call(Funcell_Lua_State, 0, 0);
		lua_settop(Funcell_Lua_State, 0);
	}
	virtual void onInitFailure(const char *msg){
		CCLOG("SDK  onInitFailure \n");

		lua_getglobal(Funcell_Lua_State, "onFuncellLuaInitFailed");
		lua_pushstring(Funcell_Lua_State, msg);
		lua_call(Funcell_Lua_State, 1, 0);
		lua_settop(Funcell_Lua_State, 0);
	}
};

class SessionCallBackImpl : public IFuncellSessionCallBack{
public:
	virtual void onLoginSuccess(FuncellSession *session){
		mSession = session;
		lua_getglobal(Funcell_Lua_State, "onFuncellLuaLoginSuccess");
		lua_pushstring(Funcell_Lua_State, session->getUserId());
		lua_pushstring(Funcell_Lua_State, session->getUsername());
		lua_pushstring(Funcell_Lua_State, session->getToken());
		lua_call(Funcell_Lua_State, 3, 0);
		lua_settop(Funcell_Lua_State, 0);
	}
	virtual void onLoginCancel(){
		lua_getglobal(Funcell_Lua_State, "onFuncellLuaLoginCancel");
		lua_call(Funcell_Lua_State, 0, 0);
		lua_settop(Funcell_Lua_State, 0);
	}
	virtual void onLoginFailed(char *paramString){
		lua_getglobal(Funcell_Lua_State, "onFuncellLuaLoginFailed");
		lua_pushstring(Funcell_Lua_State, paramString);
		lua_call(Funcell_Lua_State, 1, 0);
		lua_settop(Funcell_Lua_State, 0);
	}
	virtual void onLogout(){
		lua_getglobal(Funcell_Lua_State, "onFuncellLuaLogout");
		lua_call(Funcell_Lua_State, 0, 0);
		lua_settop(Funcell_Lua_State, 0);
	}
};

class PayCallBackImpl : public IFuncellPayCallBack{
	virtual void onSuccess(char *cpOrder, char *sdkOrder,char *extrasParams){
		lua_getglobal(Funcell_Lua_State, "onFuncellLuaPaySuccess");
		lua_pushstring(Funcell_Lua_State, cpOrder);
		lua_pushstring(Funcell_Lua_State, sdkOrder);
		lua_pushstring(Funcell_Lua_State, extrasParams);
		lua_call(Funcell_Lua_State, 3, 0);
		lua_settop(Funcell_Lua_State, 0);
	}
	virtual void onFail(char *paramString){
		lua_getglobal(Funcell_Lua_State, "onFuncellLuaPayFail");
		lua_pushstring(Funcell_Lua_State, paramString);
		lua_call(Funcell_Lua_State, 1, 0);
		lua_settop(Funcell_Lua_State, 0);
	}
	virtual void onCancel(char *paramString){
		lua_getglobal(Funcell_Lua_State, "onFuncellLuaPayCancel");
		lua_pushstring(Funcell_Lua_State, paramString);
		lua_call(Funcell_Lua_State, 1, 0);
		lua_settop(Funcell_Lua_State, 0);
	}
};

class ExitCallBackImpl : public IFuncellExitCallBack{
public:
	virtual void onChannelExit(){
		lua_getglobal(Funcell_Lua_State, "onFuncellLuaChannelExit");
		lua_call(Funcell_Lua_State, 0, 0);
		lua_settop(Funcell_Lua_State, 0);
	}
	virtual void onGameExit(){
		lua_getglobal(Funcell_Lua_State, "onFuncellLuaGameExit");
		lua_call(Funcell_Lua_State, 0, 0);
		lua_settop(Funcell_Lua_State, 0);
	}
};
/*************************************/


int doFuncellInit(lua_State *L) {
	CCLOG("doFuncellInit  ... \n");
	FuncellGameSdkProxy::Init(new InitCallBackImpl(),new SessionCallBackImpl(),new PayCallBackImpl());
	return 0;
}

int doFuncellLogin(lua_State *L) {
	CCLOG("doFuncellLogin  ... \n");
	FuncellGameSdkProxy::Login();
	return 0;
}

int doFuncellLogout(lua_State *L) {
	CCLOG("doFuncellLogout  ... \n");
	FuncellGameSdkProxy::Logout();
	return 0;
}

int doFuncellPay(lua_State *L) {
	CCLOG("doFuncellPay  ... \n");
	int num = lua_gettop(L);
	if (num != 16) {
		CCLOG("Funcell pay agrs num:IllegalArgumentException \n");
		return -1;
	}

	string RoleName = lua_tostring(L, 1); //角色名
	string RoleId = lua_tostring(L, 2); //角色ID
	string RoleLevel = lua_tostring(L, 3); //角色等级
	string ServerName = lua_tostring(L, 4);//服务器名
	string ServerId = lua_tostring(L, 5);//服务器ID
	string VipLevel = lua_tostring(L, 6);//vip等级
	string GameGoldBalance = lua_tostring(L, 7);//角色剩余金币
	string GameUnionName = lua_tostring(L, 8);//工会名

	RoleInfo *roleInfo = new RoleInfo();
	roleInfo->setRoleName((char*) RoleName.c_str());
	roleInfo->setRoleId((char*) RoleId.c_str());
	roleInfo->setRoleLevel((char*) RoleLevel.c_str());
	roleInfo->setServerName((char*) ServerName.c_str());
	roleInfo->setServerId((char*) ServerId.c_str());
	roleInfo->setVipLevel((char*) VipLevel.c_str());
	roleInfo->setGameGoldBalance((char*) GameGoldBalance.c_str());
	roleInfo->setGameUnionName((char*) GameUnionName.c_str());

	FuncellPayParams *PayParams = new FuncellPayParams();
	PayParams->setItemName(lua_tostring(L, 9));//商品名
	PayParams->setItemId(lua_tostring(L, 10));//商品ID
	PayParams->setItemCount(lua_tointeger(L, 11));//商品对应元宝个数
	PayParams->setItemDescription(lua_tostring(L, 12));//商品描述
	PayParams->setItemAmount(lua_tointeger(L, 13));//商品价格，单位：分
	PayParams->setExtrasParams(lua_tostring(L, 14));//透传参数
	PayParams->setItemType(lua_tostring(L, 15));//商品类型：元宝，钻石
	PayParams->setOrderId(lua_tostring(L, 16));//游戏订单号
	PayParams->setRoleInfo(roleInfo);

	FuncellGameSdkProxy::Pay(PayParams);
	return 0;
}

int doFuncellExit(lua_State *L) {
	CCLOG("doFuncellExit  ... \n");
	FuncellGameSdkProxy::Exit(new ExitCallBackImpl());
	return 0;
}

int doFuncellGetExitUI(lua_State *L) {
	CCLOG("doFuncellGetExitUI  ... \n");
	FuncellGameSdkProxy::GetExitUI();
	return 0;
}

int setLoginEventCallback(lua_State *L) {
	int num = lua_gettop(L);
	if (num > 0) {
		const char *json = lua_tostring(L, -1);
		char* p = const_cast<char*>(json);
		CCLOG("doFuncellSetDatas...%s \n", json);
		FuncellGameSdkProxy::SetDatas(DATA_LOGIN,p);
	}
	return 0;
}
int setRoleLevelUpEventCallback(lua_State *L) {
	int num = lua_gettop(L);
	if (num > 0) {
		const char *json = lua_tostring(L, -1);
		char* p = const_cast<char*>(json);
		CCLOG("doFuncellSetDatas...%s \n", json);
		FuncellGameSdkProxy::SetDatas(DATA_ROLE_LEVELUP,p);
	}
	return 0;
}
int setCreatRoleEventCallback(lua_State *L) {
	int num = lua_gettop(L);
	if (num > 0) {
		const char *json = lua_tostring(L, -1);
		char* p = const_cast<char*>(json);
		CCLOG("doFuncellSetDatas...%s \n", json);
		FuncellGameSdkProxy::SetDatas(DATA_CREATE_ROLE,p);
	}
	return 0;
}
int setServer_RoleEventCallback(lua_State *L) {
	int num = lua_gettop(L);
	if (num > 0) {
		const char *json = lua_tostring(L, -1);
		char* p = const_cast<char*>(json);
		CCLOG("doFuncellSetDatas...%s \n", json);
		FuncellGameSdkProxy::SetDatas(DATA_SERVER_ROLE_INFO,p);
	}
	return 0;
}

AppDelegate::AppDelegate()
{
}

AppDelegate::~AppDelegate()
{
    SimpleAudioEngine::end();
}

bool AppDelegate::applicationDidFinishLaunching()
{
    // initialize director
    CCDirector *pDirector = CCDirector::sharedDirector();
    pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());

    CCEGLView::sharedOpenGLView()->setDesignResolutionSize(480, 320, kResolutionNoBorder);

    // turn on display FPS
    pDirector->setDisplayStats(true);

    // set FPS. the default value is 1.0/60 if you don't call this
    pDirector->setAnimationInterval(1.0 / 60);

    // register lua engine
    CCLuaEngine* pEngine = CCLuaEngine::defaultEngine();
    CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);

    CCLuaStack *pStack = pEngine->getLuaStack();
    lua_State *tolua_s = pStack->getLuaState();
    tolua_extensions_ccb_open(tolua_s);
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
    pStack = pEngine->getLuaStack();
    tolua_s = pStack->getLuaState();
    tolua_web_socket_open(tolua_s);
#endif
    
#if (CC_TARGET_PLATFORM == CC_PLATFORM_BLACKBERRY)
    CCFileUtils::sharedFileUtils()->addSearchPath("script");
#endif

    initFuncellLuaEnvironment(tolua_s);

    std::string path = CCFileUtils::sharedFileUtils()->fullPathForFilename("hello.lua");
    pEngine->executeScriptFile(path.c_str());

    return true;
}

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{
    CCDirector::sharedDirector()->stopAnimation();

    SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
}

// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()
{
    CCDirector::sharedDirector()->startAnimation();

    SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}
