/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Netscape Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/NPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is mozilla.org code.
 *
 * The Initial Developer of the Original Code is 
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or 
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the NPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the NPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

//////////////////////////////////////////////////
//
// CPlugin class implementation
//
#ifdef XP_WIN
#include <windows.h>
#include <windowsx.h>
#endif

#ifdef XP_MAC
#include <TextEdit.h>
#endif

#ifdef XP_UNIX
#include <string.h>
#endif

#include "plugin.h"

static NPIdentifier sLaunchMachine_id;
static NPIdentifier sSendScolMessage_id;
static NPIdentifier sPluginType_id;
static NPIdentifier sDownloadURL_id;
static NPIdentifier sDownloadSize_id;
static NPIdentifier sScolVersionNeeded_id;

// Helper class that can be used to map calls to the NPObject hooks
// into virtual methods on instances of classes that derive from this
// class.
class ScriptablePluginObjectBase : public NPObject
{
public:
  ScriptablePluginObjectBase(NPP npp)
    : mNpp(npp)
  {
  }

  virtual ~ScriptablePluginObjectBase()
  {
  }

  // Virtual NPObject hooks called through this base class. Override
  // as you see fit.
  virtual void Invalidate();
  virtual bool HasMethod(NPIdentifier name);
  virtual bool Invoke(NPIdentifier name, const NPVariant *args,
                      uint32_t argCount, NPVariant *result);
  virtual bool InvokeDefault(const NPVariant *args, uint32_t argCount,
                             NPVariant *result);
  virtual bool HasProperty(NPIdentifier name);
  virtual bool GetProperty(NPIdentifier name, NPVariant *result);
  virtual bool SetProperty(NPIdentifier name, const NPVariant *value);
  virtual bool RemoveProperty(NPIdentifier name);
  virtual bool Enumerate(NPIdentifier **identifier, uint32_t *count);
  virtual bool Construct(const NPVariant *args, uint32_t argCount,
                         NPVariant *result);

public:
  static void _Deallocate(NPObject *npobj);
  static void _Invalidate(NPObject *npobj);
  static bool _HasMethod(NPObject *npobj, NPIdentifier name);
  static bool _Invoke(NPObject *npobj, NPIdentifier name,
                      const NPVariant *args, uint32_t argCount,
                      NPVariant *result);
  static bool _InvokeDefault(NPObject *npobj, const NPVariant *args,
                             uint32_t argCount, NPVariant *result);
  static bool _HasProperty(NPObject * npobj, NPIdentifier name);
  static bool _GetProperty(NPObject *npobj, NPIdentifier name,
                           NPVariant *result);
  static bool _SetProperty(NPObject *npobj, NPIdentifier name,
                           const NPVariant *value);
  static bool _RemoveProperty(NPObject *npobj, NPIdentifier name);
  static bool _Enumerate(NPObject *npobj, NPIdentifier **identifier,
                         uint32_t *count);
  static bool _Construct(NPObject *npobj, const NPVariant *args,
                         uint32_t argCount, NPVariant *result);

protected:
  NPP mNpp;
};

#define DECLARE_NPOBJECT_CLASS_WITH_BASE(_class, ctor)                        \
static NPClass s##_class##_NPClass = {                                        \
  NP_CLASS_STRUCT_VERSION_CTOR,                                               \
  ctor,                                                                       \
  ScriptablePluginObjectBase::_Deallocate,                                    \
  ScriptablePluginObjectBase::_Invalidate,                                    \
  ScriptablePluginObjectBase::_HasMethod,                                     \
  ScriptablePluginObjectBase::_Invoke,                                        \
  ScriptablePluginObjectBase::_InvokeDefault,                                 \
  ScriptablePluginObjectBase::_HasProperty,                                   \
  ScriptablePluginObjectBase::_GetProperty,                                   \
  ScriptablePluginObjectBase::_SetProperty,                                   \
  ScriptablePluginObjectBase::_RemoveProperty,                                \
  ScriptablePluginObjectBase::_Enumerate,                                     \
  ScriptablePluginObjectBase::_Construct                                      \
}

#define GET_NPOBJECT_CLASS(_class) &s##_class##_NPClass

void ScriptablePluginObjectBase::Invalidate()
{
}

bool ScriptablePluginObjectBase::HasMethod(NPIdentifier name)
{
  return false;
}

bool ScriptablePluginObjectBase::Invoke(NPIdentifier name, const NPVariant *args,
                                   uint32_t argCount, NPVariant *result)
{
  return false;
}

bool ScriptablePluginObjectBase::InvokeDefault(const NPVariant *args,
                                          uint32_t argCount, NPVariant *result)
{
  return false;
}

bool ScriptablePluginObjectBase::HasProperty(NPIdentifier name)
{
  return false;
}

bool ScriptablePluginObjectBase::GetProperty(NPIdentifier name, NPVariant *result)
{
  return false;
}

bool ScriptablePluginObjectBase::RemoveProperty(NPIdentifier name)
{
  return false;
}

bool ScriptablePluginObjectBase::Enumerate(NPIdentifier **identifier,
                                      uint32_t *count)
{
  return false;
}

bool ScriptablePluginObjectBase::Construct(const NPVariant *args, uint32_t argCount,
                                      NPVariant *result)
{
  return false;
}

// static
void ScriptablePluginObjectBase::_Deallocate(NPObject *npobj)
{
  // Call the virtual destructor.
  delete (ScriptablePluginObjectBase *)npobj;
}

// static
void ScriptablePluginObjectBase::_Invalidate(NPObject *npobj)
{
  ((ScriptablePluginObjectBase *)npobj)->Invalidate();
}

// static
bool ScriptablePluginObjectBase::_HasMethod(NPObject *npobj, NPIdentifier name)
{
  return ((ScriptablePluginObjectBase *)npobj)->HasMethod(name);
}

// static
bool ScriptablePluginObjectBase::_Invoke(NPObject *npobj, NPIdentifier name,
                                    const NPVariant *args, uint32_t argCount,
                                    NPVariant *result)
{
  return ((ScriptablePluginObjectBase *)npobj)->Invoke(name, args, argCount,
                                                       result);
}

// static
bool ScriptablePluginObjectBase::_InvokeDefault(NPObject *npobj,
                                           const NPVariant *args,
                                           uint32_t argCount,
                                           NPVariant *result)
{
  return ((ScriptablePluginObjectBase *)npobj)->InvokeDefault(args, argCount,
                                                              result);
}

// static
bool ScriptablePluginObjectBase::_HasProperty(NPObject * npobj, NPIdentifier name)
{
  return ((ScriptablePluginObjectBase *)npobj)->HasProperty(name);
}

// static
bool ScriptablePluginObjectBase::_GetProperty(NPObject *npobj, NPIdentifier name,
                                         NPVariant *result)
{
  return ((ScriptablePluginObjectBase *)npobj)->GetProperty(name, result);
}

// static
bool ScriptablePluginObjectBase::_SetProperty(NPObject *npobj, NPIdentifier name,
                                         const NPVariant *value)
{
  return ((ScriptablePluginObjectBase *)npobj)->SetProperty(name, value);
}

// static
bool ScriptablePluginObjectBase::_RemoveProperty(NPObject *npobj, NPIdentifier name)
{
  return ((ScriptablePluginObjectBase *)npobj)->RemoveProperty(name);
}

// static
bool ScriptablePluginObjectBase::_Enumerate(NPObject *npobj,
                                       NPIdentifier **identifier,
                                       uint32_t *count)
{
  return ((ScriptablePluginObjectBase *)npobj)->Enumerate(identifier, count);
}

// static
bool ScriptablePluginObjectBase::_Construct(NPObject *npobj, const NPVariant *args,
                                       uint32_t argCount, NPVariant *result)
{
  return ((ScriptablePluginObjectBase *)npobj)->Construct(args, argCount,
                                                          result);
}

class ConstructablePluginObject : public ScriptablePluginObjectBase
{
public:
  ConstructablePluginObject(NPP npp)
    : ScriptablePluginObjectBase(npp)
  {
  }

  virtual bool Construct(const NPVariant *args, uint32_t argCount,
                         NPVariant *result);
};

static NPObject * AllocateConstructablePluginObject(NPP npp, NPClass *aClass)
{
  return new ConstructablePluginObject(npp);
}

DECLARE_NPOBJECT_CLASS_WITH_BASE(ConstructablePluginObject, AllocateConstructablePluginObject);

bool ConstructablePluginObject::Construct(const NPVariant *args, uint32_t argCount, NPVariant *result)
{
  //printf("Creating new ConstructablePluginObject!\n");

  NPObject *myobj =
    NPN_CreateObject(mNpp, GET_NPOBJECT_CLASS(ConstructablePluginObject));
  if (!myobj)
    return false;

  OBJECT_TO_NPVARIANT(myobj, *result);

  return true;
}

class ScriptablePluginObject : public ScriptablePluginObjectBase
{
public:
  ScriptablePluginObject(NPP npp)
    : ScriptablePluginObjectBase(npp)
  {
  }

  virtual bool HasMethod(NPIdentifier name);
  virtual bool HasProperty(NPIdentifier name);
  virtual bool GetProperty(NPIdentifier name, NPVariant *result);
  virtual bool Invoke(NPIdentifier name, const NPVariant *args,
                      uint32_t argCount, NPVariant *result);
  virtual bool InvokeDefault(const NPVariant *args, uint32_t argCount,
                             NPVariant *result);
};

static NPObject * AllocateScriptablePluginObject(NPP npp, NPClass *aClass)
{
  return new ScriptablePluginObject(npp);
}

DECLARE_NPOBJECT_CLASS_WITH_BASE(ScriptablePluginObject,
                                 AllocateScriptablePluginObject);

bool ScriptablePluginObject::HasMethod(NPIdentifier name)
{
	return (name == sLaunchMachine_id)||(name == sSendScolMessage_id);
}

bool ScriptablePluginObject::HasProperty(NPIdentifier name)
{
  return (name == sPluginType_id)||(name == sDownloadURL_id)||(name == sDownloadSize_id)||(name == sScolVersionNeeded_id);;
}

bool ScriptablePluginObject::GetProperty(NPIdentifier name, NPVariant *result)
{
  CPlugin * plugin = (CPlugin *)mNpp->pdata;
  VOID_TO_NPVARIANT(*result);

  if (name == sPluginType_id) {
    NPObject *myobj =
      NPN_CreateObject(mNpp, GET_NPOBJECT_CLASS(ConstructablePluginObject));
    if (!myobj) {
      return PR_FALSE;
    }

    OBJECT_TO_NPVARIANT(myobj, *result);

    return PR_TRUE;
  }
  else if (name == sDownloadURL_id)
	{
		char* sCmd = (char*)NPN_MemAlloc(strlen(plugin->get_DownloadURL()));
		
		sprintf(sCmd, plugin->get_DownloadURL());
		STRINGZ_TO_NPVARIANT(sCmd, *result);
		
		//MessageBox(NULL, plugin->get_DownloadURL(), "GetDownloadURL to Scol called!\n", MB_OK);
	  return PR_TRUE;
	}
  else if (name == sDownloadSize_id)
	{
		char* sCmd;
		char tmpstr[sizeof(long)*8+1];
		
		_ltoa_s(plugin->get_DownloadSize(), tmpstr, (sizeof(long)*8+1), 10);
		
		sCmd = (char*)NPN_MemAlloc(strlen(tmpstr) + 1);
		
		sprintf(sCmd, tmpstr);
		STRINGZ_TO_NPVARIANT(sCmd, *result);
		
		//MessageBox(NULL, sCmd, "GetDownloadSize to Scol called!\n", MB_OK);
	  return PR_TRUE;
	}
  else if (name == sScolVersionNeeded_id)
	{
		char* sCmd = (char*)NPN_MemAlloc(strlen(plugin->get_ScolVersionNeeded()));
		
		sprintf(sCmd, plugin->get_ScolVersionNeeded());
		STRINGZ_TO_NPVARIANT(sCmd, *result);
		
		//MessageBox(NULL, sCmd, "GetVersionNeeded to Scol called!\n", MB_OK);
	  return PR_TRUE;
	}

  return PR_TRUE;
}

bool ScriptablePluginObjectBase::SetProperty(NPIdentifier name, const NPVariant *value)
{
  CPlugin * plugin = (CPlugin *)mNpp->pdata;

  if (name == sDownloadURL_id)
	{
    char* sCmd = (char*) NPVARIANT_TO_STRING(value[0]).UTF8Characters;

		plugin->set_DownloadURL(sCmd);
		
		//MessageBox(NULL, sCmd, "SetDownloadURL to Scol called!\n", MB_OK);
		return PR_TRUE;
	}
  else if (name == sDownloadSize_id)
	{
		char* sCmd = (char*) NPVARIANT_TO_STRING(value[0]).UTF8Characters;
		
		plugin->set_DownloadSize(atoi(sCmd));
		
		//MessageBox(NULL, sCmd, "SetDownloadSize to Scol called!\n", MB_OK);
		return PR_TRUE;
	}
  else if (name == sScolVersionNeeded_id)
	{
		char* sCmd = (char*) NPVARIANT_TO_STRING(value[0]).UTF8Characters;
		
		plugin->set_ScolVersionNeeded(sCmd);
		
		//MessageBox(NULL, sCmd, "SetVersionNeeded to Scol called!\n", MB_OK);
		return PR_TRUE;
	}
	
  return PR_FALSE;
}



/* *************************************************************************************** */
/*  Scol integration                                                                       */
/* *************************************************************************************** */
bool ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
{
	CPlugin * plugin = (CPlugin *)mNpp->pdata;
  if(plugin == NULL)
    return false;
	
	//if (!plugin->m_bScolInitialized)
	//	return NPERR_GENERIC_ERROR;

	//if (ScolInstance == NULL)
	//	return NPERR_GENERIC_ERROR;

  if (name == sLaunchMachine_id)
	{
		char* sCmdLine = (char*) NPVARIANT_TO_STRING(args[0]).UTF8Characters;
		char* sCmdShow = (char*) NPVARIANT_TO_STRING(args[1]).UTF8Characters;
		char* sMemSize = (char*) NPVARIANT_TO_STRING(args[2]).UTF8Characters;
    
		//MessageBox(NULL, sCmdLine, "LaunchMachine called!\n", MB_OK);
    result->type = NPVariantType_Int32;
    result->value.intValue = (long)plugin->LaunchScolMachine(sCmdLine,(long) sCmdShow,(long) sMemSize, plugin->getNavigatorWindow());
    return true;
  }
  else if (name == sSendScolMessage_id)
	{
    NPString npvar = NPVARIANT_TO_STRING(args[0]);
    
    //Convert UTF-8 to ISO for scol
    int length = MultiByteToWideChar(CP_UTF8, 0, (char*)npvar.UTF8Characters, -1, NULL, 0);
    wchar_t* strVar = new wchar_t[length];
    MultiByteToWideChar(CP_UTF8, 0, (char*)npvar.UTF8Characters, -1, strVar, length); 

    int wchar_count = WideCharToMultiByte(CP_ACP, 0, strVar, -1, NULL, 0, NULL, NULL);
    char* sCmd = new char[wchar_count];
    WideCharToMultiByte(CP_ACP, 0, strVar, -1, sCmd, wchar_count, NULL, NULL);
    delete[] strVar;

    if (plugin->SendMessageToScol(sCmd))
    {
      delete sCmd;
      return true;
    }
    else
    {
      delete sCmd;
      return false;
    }
  }

  return false;
}

bool ScriptablePluginObject::InvokeDefault(const NPVariant *args, uint32_t argCount, NPVariant *result)
{
  printf ("ScriptablePluginObject default method called!\n");

  STRINGZ_TO_NPVARIANT(strdup("default method return val"), *result);

  return PR_TRUE;
}

CPlugin::CPlugin(NPP pNPInstance, NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved) :
  m_pNPInstance(pNPInstance),
  m_Window(NULL),
	m_pNPStream(NULL),
  m_bInitialized(FALSE),
  m_pScriptableObject(NULL),
#ifdef XP_WIN
  m_hWnd(NULL),
#endif
	m_Text(NULL)
{
#ifdef XP_WIN
  m_hWnd = NULL;
#endif
	NPN_GetValue(m_pNPInstance, NPNVWindowNPObject, &sWindowObj);

	sLaunchMachine_id = NPN_GetStringIdentifier("LaunchMachine");
	sSendScolMessage_id = NPN_GetStringIdentifier("SendScolMessage");
	sDownloadURL_id = NPN_GetStringIdentifier("DownloadURL");
	sPluginType_id = NPN_GetStringIdentifier("PluginType");
	sDownloadSize_id = NPN_GetStringIdentifier("DownloadSize");
	sScolVersionNeeded_id = NPN_GetStringIdentifier("ScolVersionNeeded");  

  sprintf(mOnScolEnd,"%s", "onScolEnd");
  sprintf(mOnJSMessage,"%s", "onScolMessage");

	// parameters
	for ( int i = 0; i < argc; i++)
	{
			if (!stricmp(argn[i], "DownloadURL"))
			{
				if (strlen(argv[i]) > 1)
					this->set_DownloadURL(argv[i]);
			}
			else if (!stricmp(argn[i], "DownloadSize"))
			{
				this->set_DownloadSize(atol(argv[i]));
			}
			else if (!stricmp(argn[i], "ScolVersionNeeded"))
			{
				this->set_ScolVersionNeeded((char*)argv[i]);
			}
			else if (!stricmp(argn[i], "ForceInstall"))
			{
				if (!stricmp("true", argv[i]) || !stricmp("1", argv[i]) || !stricmp("yes", argv[i]))
					this->ForceInstall();
			}
			else if (!stricmp(argn[i], "onScolMessage"))
			{
				//////////////////////////
				// onMessage Callback
        sprintf(mOnJSMessage,"%s",argv[i]);
			}
			else if (!stricmp(argn[i], "onScolEnd"))
			{
				//////////////////////////
				// ScolOnEnd CallBack
        sprintf(mOnScolEnd,"%s",argv[i]);
			}
	}
	
	m_Text = SCOL_PRODUCT_NAME;
	NPN_MemAlloc(strlen(m_Text));
}

CPlugin::~CPlugin()
{
  if (sWindowObj)
    NPN_ReleaseObject(sWindowObj);
  if (m_pScriptableObject)
    NPN_ReleaseObject(m_pScriptableObject);

  sWindowObj = 0;
}

void CPlugin::shut()
{
	#ifdef XP_WIN
		// subclass it back
		if (m_hWnd != NULL)
		{
			SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG)m_OldWinProc);
			m_hWnd = NULL;
		}
	#endif
}

#ifdef XP_WIN
static LRESULT CALLBACK PluginWinProc(HWND, UINT, WPARAM, LPARAM);
#endif

NPBool CPlugin::init(NPWindow* pNPWindow)
{
  if(pNPWindow == NULL)
    return FALSE;

#ifdef XP_WIN

	m_hWnd = (HWND)pNPWindow->window;

  if(m_hWnd == NULL)
    return FALSE;
  
	m_OldWinProc = (WNDPROC)GetWindowLongPtr(m_hWnd, GWLP_WNDPROC);

	// subclass window so we can intercept window messages and
	// do our drawing to it	
	SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG)PluginWinProc);  
  
	// associate window with our CPlugin object so we can access 
	// it in the window procedure
	SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG)this);

  UpdateWindow(m_hWnd);
#endif

  m_Window = pNPWindow;
	m_bInitialized = TRUE;
  
	return TRUE;
}

HWND CPlugin::getNavigatorWindow()
{
	return m_hWnd;
}

NPP CPlugin::getNPPInstance()
{
	return m_pNPInstance;
}

WNDPROC CPlugin::getPreviousWinProc()
{
	return m_OldWinProc;
}

NPBool CPlugin::isInitialized()
{
  return m_bInitialized;
}

int16_t CPlugin::handleEvent(void* event)
{
  return 0;
}


// this will clean the plugin window
void CPlugin::clear()
{
#ifdef XP_WIN
  //InvalidateRect(m_hWnd, NULL, TRUE);
  UpdateWindow(m_hWnd);
#endif
}

NPObject * CPlugin::GetScriptableObject()
{
  if (!m_pScriptableObject) {
    m_pScriptableObject =
      NPN_CreateObject(m_pNPInstance,
                       GET_NPOBJECT_CLASS(ScriptablePluginObject));
  }

  if (m_pScriptableObject) {
    NPN_RetainObject(m_pScriptableObject);
  }

  return m_pScriptableObject;
}

NPObject * CPlugin::GetNPWindow()
{
  return sWindowObj;
}


#ifdef XP_WIN

static LRESULT CALLBACK PluginWinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	CPlugin * inst = (CPlugin *)GetWindowLong(hWnd, GWL_USERDATA);
	{
		switch( msg )
		{
      case WM_SIZE:
      {
        HWND hWndChild;
        RECT fatherRect;

        hWndChild = GetWindow(hWnd, GW_CHILD);
        if (hWndChild != NULL)
        {
          GetClientRect(hWnd, &fatherRect);
          MoveWindow(hWndChild, 0, 0, fatherRect.right, fatherRect.bottom, true);
        }
        break;
      }
			case WM_PAINT:
			{
				PAINTSTRUCT paintStruct;
				HDC hdc = BeginPaint(hWnd, &paintStruct);
			  
        //if(paintStruct.fErase)
          FillRect(hdc, &paintStruct.rcPaint, 
                   (HBRUSH) GetStockObject(WHITE_BRUSH)); 
        
				if(inst->m_Text)
				{
					RECT rcWnd;
					GetWindowRect(hWnd, &rcWnd);
					//SelectObject(paintStruct.hdc, GetStockObject(WHITE_BRUSH));
          /*Rectangle(paintStruct.hdc,
                      paintStruct.rcPaint.left,
                      paintStruct.rcPaint.top,
                      paintStruct.rcPaint.right,
                      paintStruct.rcPaint.bottom);
          */
					SetTextAlign(hdc, TA_CENTER);
					TextOut(hdc, (rcWnd.right-rcWnd.left)/2, (rcWnd.bottom-rcWnd.top)/2, inst->m_Text, strlen(inst->m_Text));
				}
        
				EndPaint( hWnd, &paintStruct );
        break;
			}

      case WM_COPYDATA:
      {
        PCOPYDATASTRUCT cpd;
        cpd = (PCOPYDATASTRUCT)lParam;
        switch( cpd->dwData )
        {
          case WM_SCOLSETWPTR:
          {
            inst->set_ScolHWindow(*((HWND *) cpd->lpData));
            // show scol console
            //ShowWindow(inst->get_ScolHWindow(), SW_SHOW);
            break;
          }

          case WM_SCOLAXMESS:
          {
            char* myaxdata = (char*) cpd->lpData;
            
            //MessageBox(NULL, myaxdata, "debug", 0);
            
            NPString str;
            char script[1024];
	          
	          if (inst->mOnJSMessage[0] == NULL)
		          sprintf(script, "%s", myaxdata);
	          else
		          sprintf(script, "%s('%s');", inst->mOnJSMessage, myaxdata);
            
            str.UTF8Characters = script;
            str.UTF8Length = strlen(str.UTF8Characters);
            
            // NPVariant needed by chrome 
            NPVariant curNPvar;
            NPN_Evaluate(inst->getNPPInstance(), inst->GetNPWindow(), &str, &curNPvar);
            NPN_ReleaseVariantValue (&curNPvar);
            break;
          }
        }
        break;
      }

			case WM_SCOLEND:
			{
        inst->ScolClosed();

        NPString str;
        char script[1024];
	      sprintf(script, "%s();", inst->mOnScolEnd);

        str.UTF8Characters = script;
        str.UTF8Length = strlen(str.UTF8Characters);
        
        // NPVariant needed by chrome 
        NPVariant curNPvar;
        NPN_Evaluate(inst->getNPPInstance(), inst->GetNPWindow(), &str, &curNPvar);
        NPN_ReleaseVariantValue (&curNPvar);
				break;
			}

			default:
				CallWindowProc(inst->getPreviousWinProc(), hWnd, msg, wParam, lParam);
		}
	}
	
	return DefWindowProc(hWnd, msg, wParam, lParam);
}
#endif
