/*
-----------------------------------------------------------------------------
This source file is part of OpenSpace3D
For the latest info, see http://www.openspace3d.com

Copyright (c) 2011 I-maginer

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt
-----------------------------------------------------------------------------
*/

#include "scolEmbeddedWebNavigatorV8ContextHandler.h"
#include "scolEmbeddedWebNavigator.h"
#include "embeddedWebNavigatorJSFunction.h"

WEB_NAVIGATOR_GENERATE_SCOL_ADD_CB_FUNCTION(OnExternalCall, WEB_NAVIGATOR_JS_ON_EXTERNAL_CALL_CB)
int FireWebNavigatorReflexiveOnExternalCall(mmachine m, ScolWindowHandle hwnd, unsigned int msg, UINT wParam, LONG lParam, int* ret)
{
#ifdef SCOL_DEBUG
  MMechostr(MSKDEBUG, "FireWebNavigatorReflexiveOnExternalCall\n");
#endif

  // Retrieve script function and arguments
  Scol::EmbeddedWebNavigator::WebNavigatorJSFunction* functionCalled = (Scol::EmbeddedWebNavigator::WebNavigatorJSFunction*) lParam;

  int k = 0;
  if(!(k = OBJbeginreflex(m, OBJWEBNAVIGATORSCOL, wParam, WEB_NAVIGATOR_JS_ON_EXTERNAL_CALL_CB)))
	{
    // Push function name
    Mpushstrbloc(m, (char*)(functionCalled->function.c_str()));
		
    // Push every arguments
    for(unsigned int i=0; i<functionCalled->arguments.size(); i++)
		{
			if(k=Mpushstrbloc(m, (char*)(functionCalled->arguments.at(i).c_str()))) 
        return k;
		}

		if(MMpush(m, NIL))
      return MERRMEM;

    for(unsigned int i=0; i<functionCalled->arguments.size(); i++)
		{
			if(MMpush(m, 2*2)) 
        return MERRMEM;

			if(k=MBdeftab(m)) 
        return k;
		}
		k = OBJcallreflex(m, 2);

    // Function return value
    if(k == 0)
      functionCalled->returnValue = Scol::EmbeddedWebNavigator::WN_JS_FUNCTION_RETURN_VALUE_TRUE;
    else
      functionCalled->returnValue = Scol::EmbeddedWebNavigator::WN_JS_FUNCTION_RETURN_VALUE_FALSE;
	}
	return k;
}

WEB_NAVIGATOR_GENERATE_SCOL_ADD_CB_FUNCTION(OnExternalCallStr, WEB_NAVIGATOR_JS_ON_EXTERNAL_CALL_STR_CB)
int FireWebNavigatorReflexiveOnExternalCallStr(mmachine m, ScolWindowHandle hwnd, unsigned int msg, UINT wParam, LONG lParam, int* ret)
{
#ifdef SCOL_DEBUG
  MMechostr(MSKDEBUG, "FireWebNavigatorReflexiveOnExternalCallStr\n");
#endif

  // Retrieve script function and arguments
  Scol::EmbeddedWebNavigator::WebNavigatorJSFunction* functionCalled = (Scol::EmbeddedWebNavigator::WebNavigatorJSFunction*) lParam;

  int k = 0;
  if(!(k = OBJbeginreflex(m, OBJWEBNAVIGATORSCOL, wParam, WEB_NAVIGATOR_JS_ON_EXTERNAL_CALL_STR_CB)))
	{
    // Push function name
    Mpushstrbloc(m, (char*)(functionCalled->function.c_str()));
		
    // Push every arguments
    for(unsigned int i=0; i<functionCalled->arguments.size(); i++)
		{
			if(k=Mpushstrbloc(m, (char*)(functionCalled->arguments.at(i).c_str())))
        return k;
		}

		if(MMpush(m, NIL))
      return MERRMEM;

    for(unsigned int i=0; i<functionCalled->arguments.size(); i++)
		{
			if(MMpush(m, 2*2)) 
        return MERRMEM;

			if(k=MBdeftab(m)) 
        return k;
		}
		k = OBJcallreflex(m, 2);

    int scolRet = MMget(m, -2);
    std::string retMessage = "";

    if (scolRet != NIL)
    {
      retMessage = MMstartstr(m, MTOP(scolRet));
    }
    functionCalled->returnValueStr = retMessage;

    // Function return value
    if(k == 0)
      functionCalled->returnValue = Scol::EmbeddedWebNavigator::WN_JS_FUNCTION_RETURN_VALUE_TRUE;
    else
      functionCalled->returnValue = Scol::EmbeddedWebNavigator::WN_JS_FUNCTION_RETURN_VALUE_FALSE;
	}
	return k;
}


// Nb of Scol functions or types
#define WebNavigatorJSBindingScolFunctionsNb 2

/**
 *	Scol function names
 */
char* WebNavigatorJSBindingScolFunctionsNames[WebNavigatorJSBindingScolFunctionsNb] =
{
  "WebNavigatorCbOnExternalCall",
  "WebNavigatorCbOnExternalCallStr"
};

/**
 *	Pointers to C functions that manipulate the VM for each scol function previously defined
 */
int (*WebNavigatorJSBindingScolFunctionsPtr[WebNavigatorJSBindingScolFunctionsNb])(mmachine m)=
{
  WebNavigatorCbOnExternalCall,
  WebNavigatorCbOnExternalCallStr
};

/**
 *	Nb of arguments of each scol function
 */
int WebNavigatorJSBindingScolFunctionsNbArgs[WebNavigatorJSBindingScolFunctionsNb]=
{
  3,                                                                                // WebNavigatorCbOnExternalCall
  3                                                                                 // WebNavigatorCbOnExternalCallStr
};

/**
 *	Prototypes of the scol functions
 */
char* WebNavigatorJSBindingScolFunctionsType[WebNavigatorJSBindingScolFunctionsNb]=
{
  "fun [ObjWebNavigator fun [ObjWebNavigator u0 S [S r1]] u1 u0] ObjWebNavigator",  // WebNavigatorCbOnExternalCall
  "fun [ObjWebNavigator fun [ObjWebNavigator u0 S [S r1]] S u0] ObjWebNavigator"    // WebNavigatorCbOnExternalCallStr
};

int LoadWebNavigatorJSBinding(mmachine m)
{
  return PKhardpak(m, "WebNavigatorJSBinding", WebNavigatorJSBindingScolFunctionsNb, WebNavigatorJSBindingScolFunctionsNames, WebNavigatorJSBindingScolFunctionsPtr, WebNavigatorJSBindingScolFunctionsNbArgs, WebNavigatorJSBindingScolFunctionsType);
}
