/// Thanks to agentdm
PLUGIN_API void Berkelium_Window_executeJavascript(int windowID, char* javaScript)
{
	cerr << "Javascript call made: " << javaScript << endl;
	UnityBerkeliumWindow *pWindow = getWindow(windowID);

	size_t scriptLength = ::strlen(javaScript);

    wchar_t *wctStrJScript = 0;
    
	// Convert to Wchar ( is there an easier way to do this? )
#if 1
	std::wstring wideString = Berkelium::UTF8ToWide(Berkelium::UTF8String::point_to(javaScript, scriptLength)).data();
	wctStrJScript = new wchar_t[wideString.length() + 1];
	memcpy(wctStrJScript, wideString.data(), wideString.length() * sizeof(wchar_t));
	wctStrJScript[wideString.length()] = 0;
#else
	wctStrJScript = new wchar_t[scriptLength + 1];
	MultiByteToWideChar( CP_ACP, 0, javaScript, scriptLength, wctStrJScript, scriptLength);
	wctStrJScript[scriptLength] = 0;
#endif
    
	std::wcerr << "Javascript converted: " << wctStrJScript << endl;

	if(pWindow)
		pWindow->getBerkeliumWindow()->executeJavascript(Berkelium::WideString::point_to(wctStrJScript, scriptLength));

	delete[] wctStrJScript;
}
PLUGIN_API bool Berkelium_Window_everReceivedTitleUpdate(int windowID)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		return pWindow->everReceivedTitleUpdate();
	else
		return false;
}
PLUGIN_API void Berkelium_Window_mouseUp(int windowID, int button)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		pWindow->getBerkeliumWindow()->mouseButton(button, false);
	else
		cerr << "Warning: no berkelium window found with ID " << windowID << "!" << endl;
}
// TEMP This should be a parameter in the callback function
PLUGIN_API const wchar_t *Berkelium_Window_getLastExternalHostMessage(int windowID)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		return pWindow->getLastExternalHostMessage().c_str();
	else
		return L"";
}
PLUGIN_API void Berkelium_Window_mouseMove(int windowID, int x, int y)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		pWindow->getBerkeliumWindow()->mouseMoved(x, y);
	else
		cerr << "Warning: no berkelium window found with ID " << windowID << "!" << endl;
}
PLUGIN_API bool Berkelium_Window_isDirty(int windowID){
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow){
    return pWindow->getDirty();
	}else{
		cerr << "Warning: no berkelium window found with ID " << windowID << "!" << endl;
    return false;
	}
}
PLUGIN_API void Berkelium_update(int windowID)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);

  //set dirty to false, if it needs changing, onPaint will change it to true
  pWindow->setDirty(false);

	//! @todo We need to call this only once, not for each object
	Berkelium::update();
}
// Note: we need this function because I can't get parameters in function pointers to work properly
PLUGIN_API Berkelium::Rect Berkelium_Window_getLastDirtyRect(int windowID)
{
	Berkelium::Rect result;

	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		result = pWindow->getLastDirtyRect();

	return result;
}
PLUGIN_API void Berkelium_Window_textEvent(int windowID, char c){

	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow){
		
        wchar_t outchars[2]; // the structure for passing chars
        outchars[0] = c; // the character we want to inject
        outchars[1] = 0; //terminating character
        pWindow->getBerkeliumWindow()->textEvent(outchars,1);

	}else{
		cerr << "Warning: no berkelium window found with ID " << windowID << "!" << endl;
	}
}
PLUGIN_API void Berkelium_Window_keyEvent(int windowID, int key){

	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow){

		bool pressed = true; 
        int wvmods = 0; //mapGLUTModsToBerkeliumMods(glutGetModifiers());
        int vk_code = key; // this is used for backspace as it cannot be passed as char
        int scancode = 0;

       pWindow->getBerkeliumWindow()->keyEvent(pressed, wvmods, vk_code, scancode);   

	}else{
		cerr << "Warning: no berkelium window found with ID " << windowID << "!" << endl;
	}
}
/// Thanks to agentdm
PLUGIN_API void Berkelium_Window_executeJavascript(int windowID, char* javaScript)
{
	cerr << "Javascript call made: " << javaScript << endl;
	UnityBerkeliumWindow *pWindow = getWindow(windowID);

	size_t scriptLength = ::strlen(javaScript);

	// Convert to Wchar ( is there an easier way to do this? )
	wchar_t *wctStrJScript = new wchar_t[scriptLength + 1];
	MultiByteToWideChar( CP_ACP, 0, javaScript, scriptLength, wctStrJScript, scriptLength);
	wctStrJScript[scriptLength] = 0;

	std::wcerr << "Javascript converted: " << wctStrJScript << endl;

	if(pWindow)
		pWindow->getBerkeliumWindow()->executeJavascript(Berkelium::WideString::point_to(wctStrJScript, scriptLength));

	delete[] wctStrJScript;
}
PLUGIN_API void Berkelium_Window_unfocus(int windowID)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		pWindow->getBerkeliumWindow()->unfocus();
}
PLUGIN_API void Berkelium_Window_setLoadingStateChanged(int windowID, UnityBerkeliumWindow::LoadingStateChangedFunc callback)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		pWindow->setLoadingStateChanged(callback);
}
PLUGIN_API void Berkelium_Window_setExternalHostCallback(int windowID, UnityBerkeliumWindow::ExternalHostFunc callback)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		pWindow->setExternalHostCallback(callback);
}
PLUGIN_API void Berkelium_Window_textEvent(int windowID, wchar_t c)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		pWindow->getBerkeliumWindow()->textEvent(&c, 1);
}
PLUGIN_API void Berkelium_Window_keyEvent(int windowID, bool pressed, int mods, int vk_code, int scancode)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		pWindow->getBerkeliumWindow()->keyEvent(pressed, mods, vk_code, scancode);
}
PLUGIN_API void Berkelium_Window_mouseMove(int windowID, int x, int y)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		pWindow->getBerkeliumWindow()->mouseMoved(x, y);
}
PLUGIN_API void Berkelium_Window_mouseUp(int windowID, int button)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		pWindow->getBerkeliumWindow()->mouseButton(button, false);
}
PLUGIN_API void Berkelium_Window_navigateTo(int windowID, char *url)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		pWindow->navigateTo(url);
}
PLUGIN_API void Berkelium_Window_setNavigationFunctions(int windowID, char* hookUrl, UnityBerkeliumWindow::NavHookCb navCb, UnityBerkeliumWindow::LoadCb loadCb)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		pWindow->setNavigationFunctions(hookUrl, navCb, loadCb);
}
PLUGIN_API void Berkelium_Window_setPaintFunctions(int windowID, UnityBerkeliumWindow::SetPixelsFunc setPixelsFunc, UnityBerkeliumWindow::ApplyTextureFunc applyTextureFunc, UnityBerkeliumWindow::ScrollRectFunc scrollRectFunc)
{
	UnityBerkeliumWindow *pWindow = getWindow(windowID);
	if(pWindow)
		pWindow->setPaintFunctions(setPixelsFunc, applyTextureFunc, scrollRectFunc);
}