/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * 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 Netscape are
 * Copyright (C) 1998 Netscape Communications Corporation. All
 * Rights Reserved.
 *
 * Contributor(s): 
 *   Pierre Phaneuf <pp@ludusdesign.com>
 */

/*******************************************************************************
 * npScol.cpp
 ******************************************************************************
 * Scol Sample Plugin
 * Copyright (c) 1996 Netscape Communications. All rights reserved.
 ******************************************************************************
 * OVERVIEW
 * --------
 * Section 1 - Includes
 * Section 2 - Instance Structs
 * Section 3 - API Plugin Implementations
 * Section 4 - Utility Method Implementations
 *******************************************************************************/


/*------------------------------------------------------------------------------
 * Windows Includes
 *----------------------------------------------------------------------------*/
/* Moved before Section 1 by Tiry for avoiding error in Winnt.h */
#ifdef _WINDOWS /* Windows Includes */
#include "ScolInterface.h"
#include <Windows.h>
#include "GVar.h"
#endif /* _WINDOWS */



/*******************************************************************************
 * SECTION 1 - Includes
 ******************************************************************************/
#include <stdio.h>
#include <string.h>
#include "nsplugin.h"
#include "nsIServiceManager.h"
#include "nsISupports.h"
#include "nsIFactory.h"
#include "nsIGenericFactory.h"
#include "nsMemory.h"
#include "nsString.h"
#include "ScolCID.h"
#include "prmem.h"

#include "nsIScolPluginInstance.h"
#include "nsIScriptablePlugin.h"

/*------------------------------------------------------------------------------
 * UNIX includes
 *----------------------------------------------------------------------------*/
#ifdef XP_UNIX
#include <gdk/gdk.h>
#include <gdk/gdkprivate.h>
#include <gtk/gtk.h>
#include <gdksuperwin.h>
#include <gtkmozbox.h>
#endif /* XP_UNIX */

#ifdef XP_UNIX

gboolean draw (GtkWidget *widget, GdkEventExpose *event, gpointer data);

#endif





/*******************************************************************************
 * SECTION 2 - Instance Structs
 *******************************************************************************
 * Instance state information about the plugin.
 *
 * PLUGIN DEVELOPERS:
 *	Use this struct to hold per-instance information that you'll
 *	need in the various functions in this file.
 ******************************************************************************
 * First comes the PlatformInstance struct, which contains platform specific
 * information for each instance.
 *****************************************************************************/
 
/*------------------------------------------------------------------------------
 * Windows PlatformInstance
 *----------------------------------------------------------------------------*/

#if defined(XP_PC) && !defined(XP_OS2)          // XXXX OS2TODO
typedef struct _PlatformInstance
{
    HWND		fhWnd;
    WNDPROC		fDefaultWindowProc;
} PlatformInstance;

/*------------------------------------------------------------------------------
 * UNIX PlatformInstance
 *----------------------------------------------------------------------------*/

#elif defined(XP_UNIX)
typedef struct _PlatformInstance
{
    Window 		       window;
    GtkWidget         *moz_box;
    GdkSuperWin       *superwin;
    GtkWidget         *label;
    Display *		   display;
    uint32 		       x, y;
    uint32 		       width, height;
} PlatformInstance;

/*------------------------------------------------------------------------------
 * Macintosh PlatformInstance
 *----------------------------------------------------------------------------*/

#elif defined(XP_MAC)
typedef struct _PlatformInstance
{
    int			placeholder;
} PlatformInstance;

/*------------------------------------------------------------------------------
 * Stub PlatformInstance
 *----------------------------------------------------------------------------*/

#else
typedef struct _PlatformInstance
{
    int			placeholder;
} PlatformInstance;
#endif /* end Section 2 */


// Define constants for easy use
static NS_DEFINE_CID(kScolPluginCID, NS_SCOLPLUGIN_CID);
static NS_DEFINE_CID(kPluginManagerCID, NS_PLUGINMANAGER_CID);
static NS_DEFINE_IID(kIPluginManagerIID,        NS_IPLUGINMANAGER_IID        );
static NS_DEFINE_CID(kCPluginManagerCID,        NS_PLUGINMANAGER_CID         );

#define PLUGIN_MIME_TYPE "application/x-scol"

static const char kPluginName[] = "Cryo Interactive SCOL.";
static const char kPluginDescription[] = "Scol PlugIn for Netscape 6.x";

static const char* kMimeTypes[] = {
    PLUGIN_MIME_TYPE
};

static const char* kMimeDescriptions[] = {
    "Scol Netscape/Mozilla Plug-in"
};

static const char* kFileExtensions[] = {
    ".scol"
};

static const PRInt32 kNumMimeTypes = sizeof(kMimeTypes) / sizeof(*kMimeTypes);



////////////////////////////////////////////////////////////////////////////////
// Scol Plugin Classes
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// ScolPluginInstance represents an instance of the Scol plugin class.

class ScolPluginInstance : 
    public nsIPluginInstance, 
    public nsIScriptablePlugin,
    public nsIScolPluginInstance {

public:
    ////////////////////////////////////////////////////////////////////////////
    // for implementing a generic module
    static NS_METHOD
    Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);

    static NS_METHOD
    RegisterSelf(nsIComponentManager* aCompMgr,
                 nsIFile* aPath,
                 const char* aRegistryLocation,
                 const char* aComponentType,
                 const nsModuleComponentInfo *info);

    static NS_METHOD
    UnregisterSelf(nsIComponentManager* aCompMgr,
                   nsIFile* aPath,
                   const char* aRegistryLocation,
                   const nsModuleComponentInfo *info);

	//////////////////////////////////////////////////////
	// Fct to Call JS
	int SendMessageToJS(char *JSMessage);
	int SendEndEventToJS(int Reason);

    NS_DECL_ISUPPORTS
    NS_DECL_NSISCRIPTABLEPLUGIN
    NS_DECL_NSISCOLPLUGININSTANCE

    ////////////////////////////////////////////////////////////////////////////
    // from nsIEventHandler:

    // (Corresponds to NPP_HandleEvent.)
    // Note that for Unix and Mac the nsPluginEvent structure is different
    // from the old NPEvent structure -- it's no longer the native event
    // record, but is instead a struct. This was done for future extensibility,
    // and so that the Mac could receive the window argument too. For Windows
    // and OS2, it's always been a struct, so there's no change for them.
    NS_IMETHOD
    HandleEvent(nsPluginEvent* event, PRBool* handled);

    ////////////////////////////////////////////////////////////////////////////
    // from nsIPluginInstance:

    NS_IMETHOD
    Initialize(nsIPluginInstancePeer* peer);

    // Required backpointer to the peer.
    NS_IMETHOD
    GetPeer(nsIPluginInstancePeer* *result);

    // See comment for nsIPlugin::CreateInstance, above.
    NS_IMETHOD
    Start(void);

    // The old NPP_Destroy call has been factored into two plugin instance 
    // methods:
    //
    // Stop -- called when the plugin instance is to be stopped (e.g. by 
    // displaying another plugin manager window, causing the page containing 
    // the plugin to become removed from the display).
    //
    // Destroy -- called once, before the plugin instance peer is to be 
    // destroyed. This method is used to destroy the plugin instance. 

    NS_IMETHOD
    Stop(void);

    NS_IMETHOD
    Destroy(void);

    // (Corresponds to NPP_SetWindow.)
    NS_IMETHOD
    SetWindow(nsPluginWindow* window);

    NS_IMETHOD
    NewStream(nsIPluginStreamListener** listener);

    // (Corresponds to NPP_Print.)
    NS_IMETHOD
    Print(nsPluginPrint* platformPrint);

    NS_IMETHOD
    GetValue(nsPluginInstanceVariable variable, void *value);


//	void CALLBACK NSDispText (const char * TheText);
    ////////////////////////////////////////////////////////////////////////////
    // ScolPluginInstance specific methods:

    ScolPluginInstance(void);
    virtual ~ScolPluginInstance(void);

    void            PlatformNew(void);
    nsresult        PlatformDestroy(void);
    nsresult    	PlatformSetWindow(nsPluginWindow* window);
    PRInt16         PlatformHandleEvent(nsPluginEvent* event);

    void SetMode(nsPluginMode mode) { fMode = mode; }

#ifdef XP_UNIX
    NS_IMETHOD Repaint(void);
#endif

#if defined(XP_PC) && !defined(XP_OS2)
    static LRESULT CALLBACK 
    PluginWindowProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
#endif

    char*                       fText;

protected:
    nsIPluginInstancePeer*      fPeer;
    nsPluginWindow*             fWindow;
    nsPluginMode                fMode;
	nsIPluginManager*           mPluginManager;
    PlatformInstance            fPlatform;
private:
	char*						mOnJSMessage;
	char*						mOnScolEnd;
	ScolInterface* MyScolInterface ;
};



/**********************************************************************************/
/* This section is here to provide a mapping C Function -> Object member function */

/**********************************************************************************/
// Ptr to the unique instance of the PlugIn main class : 
// Used to map CallBack function to the class member function
ScolPluginInstance * MyScolPlugSingleton;
BOOL ScolQuit=FALSE;

int MyCallBackForScol(char* Msg)
{
return MyScolPlugSingleton->SendMessageToJS(Msg);
}

int MyEndCallBackForScol(int Reason)
{
ScolQuit=TRUE;
return MyScolPlugSingleton->SendEndEventToJS(Reason);
}








////////////////////////////////////////////////////////////////////////////////
// ScolPluginStream represents the stream used by ScolPluginInstances
// to receive data from the browser. 

class ScolPluginStreamListener : public nsIPluginStreamListener {
public:

    NS_DECL_ISUPPORTS

    ////////////////////////////////////////////////////////////////////////////
    // from nsIPluginStreamListener:

    /**
     * Notify the observer that the URL has started to load.  This method is
     * called only once, at the beginning of a URL load.<BR><BR>
     *
     * @return The return value is currently ignored.  In the future it may be
     * used to cancel the URL load..
     */
    NS_IMETHOD
    OnStartBinding(nsIPluginStreamInfo* pluginInfo);

    /**
     * Notify the client that data is available in the input stream.  This
     * method is called whenver data is written into the input stream by the
     * networking library...<BR><BR>
     * 
     * @param aIStream  The input stream containing the data.  This stream can
     * be either a blocking or non-blocking stream.
     * @param length    The amount of data that was just pushed into the stream.
     * @return The return value is currently ignored.
     */
    NS_IMETHOD
    OnDataAvailable(nsIPluginStreamInfo* pluginInfo, 
                                            nsIInputStream* input, 
                                            PRUint32 length);

    NS_IMETHOD
    OnFileAvailable(nsIPluginStreamInfo* pluginInfo, const char* fileName);

    /**
     * Notify the observer that the URL has finished loading.  This method is 
     * called once when the networking library has finished processing the 
     * URL transaction initiatied via the nsINetService::Open(...) call.<BR><BR>
     * 
     * This method is called regardless of whether the URL loaded successfully.<BR><BR>
     * 
     * @param status    Status code for the URL load.
     * @param msg   A text string describing the error.
     * @return The return value is currently ignored.
     */
    NS_IMETHOD
    OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status);

    NS_IMETHOD
    OnNotify(const char* url, nsresult status);

    NS_IMETHOD
    GetStreamType(nsPluginStreamType *result);

    ////////////////////////////////////////////////////////////////////////////
    // ScolPluginStreamListener specific methods:

    ScolPluginStreamListener(ScolPluginInstance* inst, const char* url);
    virtual ~ScolPluginStreamListener(void);

protected:
    const char*                 fMessageName;
};

/*******************************************************************************
 * SECTION 3 - API Plugin Implementations
 ******************************************************************************/

// XXXwaterson document!
static nsModuleComponentInfo gComponentInfo[] = {
    { "Scol Plugin",
      NS_SCOLPLUGIN_CID,
      NS_INLINE_PLUGIN_CONTRACTID_PREFIX PLUGIN_MIME_TYPE,
      ScolPluginInstance::Create,
      ScolPluginInstance::RegisterSelf,
      ScolPluginInstance::UnregisterSelf },
};

NS_IMPL_NSGETMODULE(ScolPlugin, gComponentInfo);



////////////////////////////////////////////////////////////////////////////////
// nsIScriptablePlugin methods
////////////////////////////////////////////////////////////////////////////////
NS_METHOD
ScolPluginInstance::GetScriptablePeer(void **aScriptablePeer)
{
   // We implement the interface we want to be scriptable by
   // (nsIScolPluginInstance) so we just return this.

   // NOTE if this function returns something other than
   // nsIPluginInstance, then that object will also need to implement
   // nsISecurityCheckedComponent to be scriptable.  The security
   // system knows to special-case nsIPluginInstance when checking
   // security, but in general, XPCOM components must implement
   // nsISecurityCheckedComponent to be scriptable from content
   // javascript.

   *aScriptablePeer = NS_STATIC_CAST(nsIScolPluginInstance *, this);
   NS_ADDREF(NS_STATIC_CAST(nsIScolPluginInstance *, *aScriptablePeer));
   return NS_OK;
}

NS_METHOD
ScolPluginInstance::GetScriptableInterface(nsIID **aScriptableInterface)
{
  *aScriptableInterface = (nsIID *)nsMemory::Alloc(sizeof(nsIID));
  NS_ENSURE_TRUE(*aScriptableInterface, NS_ERROR_OUT_OF_MEMORY);

  **aScriptableInterface = NS_GET_IID(nsIScolPluginInstance);

  return NS_OK;
}

////////////////////////////////////////////////////////////////////////////////
// ScolPluginInstance Methods
////////////////////////////////////////////////////////////////////////////////

NS_METHOD
ScolPluginInstance::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult)
{
    NS_PRECONDITION(aOuter == nsnull, "no aggregation");
    if (aOuter)
        return NS_ERROR_NO_AGGREGATION;

    ScolPluginInstance* plugin = new ScolPluginInstance();
    if (! plugin)
        return NS_ERROR_OUT_OF_MEMORY;

    nsresult rv;
    NS_ADDREF(plugin);
    rv = plugin->QueryInterface(aIID, aResult);
    NS_RELEASE(plugin);

	//::MessageBox(NULL,"Create!","Debug",0);

    return rv;
}

NS_METHOD
ScolPluginInstance::RegisterSelf(nsIComponentManager* aCompMgr,
                                   nsIFile* aPath,
                                   const char* aRegistryLocation,
                                   const char* aComponentType,
                                   const nsModuleComponentInfo *info)
{
    nsresult rv;

    nsIPluginManager* pm;
    rv = nsServiceManager::GetService(kPluginManagerCID, NS_GET_IID(nsIPluginManager),
                                      NS_REINTERPRET_CAST(nsISupports**, &pm));
    if (NS_SUCCEEDED(rv)) {
        rv = pm->RegisterPlugin(kScolPluginCID,
                                kPluginName,
                                kPluginDescription,
                                kMimeTypes,
                                kMimeDescriptions,
                                kFileExtensions,
                                kNumMimeTypes);

        NS_RELEASE(pm);
    }

    return rv;
}


NS_METHOD
ScolPluginInstance::UnregisterSelf(nsIComponentManager* aCompMgr,
                                     nsIFile* aPath,
                                     const char* aRegistryLocation,
                                     const nsModuleComponentInfo *info)
{
    nsresult rv;

    nsIPluginManager* pm;
    rv = nsServiceManager::GetService(kPluginManagerCID, NS_GET_IID(nsIPluginManager),
                                      NS_REINTERPRET_CAST(nsISupports**, &pm));
    if (NS_SUCCEEDED(rv)) {
        rv = pm->UnregisterPlugin(kScolPluginCID);
        NS_RELEASE(pm);
    }

    return rv;
}


ScolPluginInstance::ScolPluginInstance(void)
    : fText(NULL), fPeer(NULL), fWindow(NULL), fMode(nsPluginMode_Embedded)
{
    NS_INIT_REFCNT();

	//::MessageBox(NULL,"ScolPlugInst Constructor!","Debug",0);

	// Increment Global Instance counter
	NBPlugInstance++;

	// display Warning if there is more than One Instance
	// this limitation is because of Scol, not Mozilla API
	// - Plugin Hwnd and CallBack are shared resources in Scol DLL !!!!
	if (NBPlugInstance>1)
		::MessageBox(NULL,"You can only launch one instance of Scol","Sorry !",MB_OK|MB_ICONEXCLAMATION);

    static const char text[] = "Scol Netscape/Mozilla Plug-In";
    fText = (char*) nsMemory::Clone(text, sizeof(text));

#ifdef XP_UNIX
    fPlatform.moz_box = nsnull;
    fPlatform.superwin = nsnull;
    fPlatform.label = nsnull;
#endif

	// Create new Scol Access Object
	MyScolInterface = new ScolInterface();
	
	
	if(nsComponentManager::CreateInstance(kCPluginManagerCID, NULL, kIPluginManagerIID, (void**)&mPluginManager) != NS_OK) 
        NS_ERROR("Error trying to create plugin manager!");
}

ScolPluginInstance::~ScolPluginInstance(void)
{
	//::MessageBox(NULL,"ScolPlugInst Destructor!","Debug",0);
	// Decrement Global Instance counter
//	NBPlugInstance--;


    if(fText)
        nsMemory::Free(fText);
    PlatformDestroy(); // Perform platform specific cleanup

	PR_FREEIF(mOnJSMessage);
}

// These macros produce Scol version of QueryInterface and AddRef.
// See the nsISupports.h header file for details.

NS_IMPL_ISUPPORTS3(ScolPluginInstance, nsIPluginInstance, nsIScolPluginInstance, nsIScriptablePlugin)

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * NewInstance:
 * Creates a new instance of a plug-in and returns an error value. 
 * 
 * NewInstance ²creates a new instance of your plug-in with MIME type specified
 * by pluginType. The parameter mode is NP_EMBED if the instance was created
 * by an EMBED tag, or NP_FULL if the instance was created by a separate file.
 * You can allocate any instance-specific private data in instance->pdata at this
 * time. The NPP pointer is valid until the instance is destroyed. 
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

NS_METHOD
ScolPluginInstance::Initialize(nsIPluginInstancePeer* peer)
{
	//::MessageBox(NULL,"Initialize","Debug",0);

	// Store this instance in Global var :-(
	MyScolPlugSingleton=this;

	// Set JS CallBack Function
	MyScolInterface->set_SendMessageCallBack((void*)&MyCallBackForScol);
	MyScolInterface->set_ScolEndCallBack((void*)&MyEndCallBackForScol);

#ifdef NS_DEBUG
    printf("ScolPluginInstance::Initialize\n");
#endif
    
    NS_ASSERTION(peer != NULL, "null peer");

    fPeer = peer;
    nsIPluginTagInfo* taginfo;
    const char* const* names = nsnull;
    const char* const* values = nsnull;
    PRUint16 count = 0;
    nsresult result;

    peer->AddRef();
    result = peer->GetMode(&fMode);
    if (NS_FAILED(result)) return result;

   result = peer->QueryInterface(NS_GET_IID(nsIPluginTagInfo), (void **)&taginfo);

    if (!NS_FAILED(result))
    {
        taginfo->GetAttributes(count, names, values);
        NS_IF_RELEASE(taginfo);
    }


    printf("Attribute count = %d\n", count);

    for (int i = 0; i < count; i++)
    {
        printf("plugin param=%s, value=%s\n", names[i], values[i]);

		if (PL_strcasecmp(names[i], "onMessage") == 0) {
            //////////////////////////
            // onMessage Callback
            PR_FREEIF(mOnJSMessage);
            mOnJSMessage = PL_strdup(values[i]);
        } 
		else if (PL_strcasecmp(names[i], "DownloadURL") == 0) {
            //////////////////////////
            // Download URL Property
			MyScolInterface->set_DownloadURL((char *)values[i]);
        } 
		else if (PL_strcasecmp(names[i], "DownloadSize") == 0) {
            //////////////////////////
            // Download Size Property
			MyScolInterface->set_DownloadSize(atol(values[i]));
        } 
		else if (PL_strcasecmp(names[i], "ScolVersionNeeded") == 0) {
            //////////////////////////
            // ScolVersionNeeded Property
			MyScolInterface->set_ScolVersionNeeded((char *)values[i]);
		}
		else if (PL_strcasecmp(names[i], "ForceInstall") == 0) {
            //////////////////////////
            // ForceInstall Test Flag
			MyScolInterface->ForceInstall();
        } 
		else if (PL_strcasecmp(names[i], "onScolEnd") == 0) {
            //////////////////////////
            // ScolOnEnd CallBack
			PR_FREEIF(mOnScolEnd);
            mOnScolEnd = PL_strdup(values[i]);
        } 

    }


    PlatformNew(); 	/* Call Platform-specific initializations */
    return NS_OK;
}

NS_METHOD
ScolPluginInstance::GetPeer(nsIPluginInstancePeer* *result)
{
#ifdef NS_DEBUG
    printf("ScolPluginInstance::GetPeer\n");
#endif

    fPeer->AddRef();
    *result = fPeer;
    return NS_OK;
}

NS_METHOD
ScolPluginInstance::Start(void)
{
	//::MessageBox(NULL,"Start!","Debug",0);

#ifdef NS_DEBUG
    printf("ScolPluginInstance::Start\n");
#endif

    return NS_OK;
}

NS_METHOD
ScolPluginInstance::Stop(void)
{

// release MyScolInterface
delete MyScolInterface;
NBPlugInstance--;
//::MessageBox(NULL,"Stop!","Debug",0);
#ifdef NS_DEBUG
    printf("ScolPluginInstance::Stop\n");
#endif

    return NS_OK;
}

NS_METHOD
ScolPluginInstance::Destroy(void)
{
//::MessageBox(NULL,"Destroy!","Debug",0);
#ifdef NS_DEBUG
    printf("ScolPluginInstance::Destroy\n");
#endif

    return NS_OK;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * NPP_SetWindow:
 * Sets the window in which a plug-in draws, and returns an error value. 
 * 
 * NPP_SetWindow informs the plug-in instance specified by instance of the
 * the window denoted by window in which the instance draws. This nsPluginWindow
 * pointer is valid for the life of the instance, or until NPP_SetWindow is called
 * again with a different value. Subsequent calls to NPP_SetWindow for a given
 * instance typically indicate that the window has been resized. If either window
 * or window->window are NULL, the plug-in must not perform any additional
 * graphics operations on the window and should free any resources associated
 * with the window. 
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

NS_METHOD
ScolPluginInstance::SetWindow(nsPluginWindow* window)
{
#ifdef NS_DEBUG
    printf("ScolPluginInstance::SetWindow\n");
#endif

    nsresult result;

    /*
     * PLUGIN DEVELOPERS:
     *	Before setting window to point to the
     *	new window, you may wish to compare the new window
     *	info to the previous window (if any) to note window
     *	size changes, etc.
     */
    result = PlatformSetWindow(window);
    fWindow = window;
    return result;
}

NS_METHOD
ScolPluginInstance::NewStream(nsIPluginStreamListener** listener)
{
#ifdef NS_DEBUG
    printf("ScolPluginInstance::NewStream\n");
#endif

    if(listener != NULL)
    {
        ScolPluginStreamListener* sl = 
                new ScolPluginStreamListener(this, "http://www.mozilla.org");
        if(!sl)
            return NS_ERROR_UNEXPECTED;
        sl->AddRef();
        *listener = sl;
    }
    
    return NS_OK;
}


/* attribute string text; */
NS_IMETHODIMP ScolPluginInstance::GetText(char * *aText)
{
#ifdef NS_DEBUG
    printf("ScolPluginInstance::GetText\n");
#endif
    
    if(!fText)
    {
        *aText = NULL;
        return NS_OK;        
    }
    char* ptr = *aText = (char*) nsMemory::Clone(fText, strlen(fText)+1);
    return ptr ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP ScolPluginInstance::SetText(const char * aText)
{
#ifdef NS_DEBUG
    printf("ScolPluginInstance::SetText\n");
#endif

    if(fText)
    {
        nsMemory::Free(fText);
        fText = NULL;
    }

    if(aText)
    {
        fText = (char*) nsMemory::Clone(aText, strlen(aText)+1);
        if(!fText)
            return NS_ERROR_OUT_OF_MEMORY;

#if defined(XP_PC) && !defined(XP_OS2)
        if(fPlatform.fhWnd) {
            InvalidateRect( fPlatform.fhWnd, NULL, TRUE );
            UpdateWindow( fPlatform.fhWnd );
        }
#endif

#ifdef XP_UNIX
        // force a redraw
        Repaint();
#endif

    }

    return NS_OK;
}

/******************************************************************************************/
/******************************************************************************************/
/******************************************************************************************/

// XPCOM Scol Implementation 
// Here begins impelmentation of Scol Specific Methods

/******************************************************************************************/
/******************************************************************************************/
/******************************************************************************************/

/* long SendMessage (in string Message); */
NS_IMETHODIMP ScolPluginInstance::SendMessage(const char *Message, PRInt32 *_retval)
{
	//::MessageBox(NULL,"Message Sent to Scol","Debug",NULL);
	//::MessageBox(NULL,Message,"Debug",NULL);
	
	// Forward Call to Scol Inyterface Class
	if (MyScolInterface)
		*_retval=MyScolInterface->SendMessageToScol(Message);

	// Forward Message to JavaScript for Debug
	SendMessageToJS((char*) nsMemory::Clone(Message, strlen(Message)+1));
	SendEndEventToJS(0);
    return NS_OK;
}

/* long LaunchMachine (in string CmdLine, in long CmdShow, in long MemSize); */
NS_IMETHODIMP ScolPluginInstance::LaunchMachine(const char *CmdLine, PRInt32 CmdShow, PRInt32 MemSize, PRInt32 *_retval)
{
//	::MessageBox(NULL,"LauchMachine in NSI","DEBUG",0);
	HWND MyWin=fPlatform.fhWnd;
	if (MyScolInterface)
		*_retval=MyScolInterface->LaunchMachine(CmdLine,(long) CmdShow,(long) MemSize,MyWin);
    return NS_OK;
}

/* attribute string DownloadURL; */
NS_IMETHODIMP ScolPluginInstance::GetDownloadURL(char * *aDownloadURL)
{
    if (MyScolInterface)
		{
		char* ptr = *aDownloadURL = (char*) nsMemory::Clone(MyScolInterface->get_DownloadURL(), strlen(MyScolInterface->get_DownloadURL())+1);
		return ptr ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
		}
	else
		return NS_OK;
}
NS_IMETHODIMP ScolPluginInstance::SetDownloadURL(const char * aDownloadURL)
{
char * TxtTmp;

    if(aDownloadURL)
    {
        TxtTmp = (char*) nsMemory::Clone(aDownloadURL, strlen(aDownloadURL)+1);
        if(!TxtTmp)
            return NS_ERROR_OUT_OF_MEMORY;
		if (MyScolInterface)
			MyScolInterface->set_DownloadURL(TxtTmp);
		PR_FREEIF(TxtTmp);
	}
	return NS_OK;
}

/* attribute long DownloadSize; */
NS_IMETHODIMP ScolPluginInstance::GetDownloadSize(PRInt32 *aDownloadSize)
{
    if (MyScolInterface)
		*aDownloadSize = PR_INT32(MyScolInterface->get_DownloadSize());
	return NS_OK;
}
NS_IMETHODIMP ScolPluginInstance::SetDownloadSize(const PRInt32 aDownloadSize)
{
	if (MyScolInterface)
		MyScolInterface->set_DownloadSize((long)aDownloadSize);
	return NS_OK;
}

/* attribute string ScolVersionNeeded; */
NS_IMETHODIMP ScolPluginInstance::GetScolVersionNeeded(char * *aScolVersionNeeded)
{
	if (MyScolInterface)
	{
		char* ptr = *aScolVersionNeeded = (char*) nsMemory::Clone(MyScolInterface->get_ScolVersionNeeded(), strlen(MyScolInterface->get_ScolVersionNeeded())+1);
		return ptr ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
	}
	else
		return NS_OK;
}
NS_IMETHODIMP ScolPluginInstance::SetScolVersionNeeded(const char * aScolVersionNeeded)
{
char * TxtTmp;
	if(aScolVersionNeeded)
    {
        TxtTmp = (char*) nsMemory::Clone(aScolVersionNeeded, strlen(aScolVersionNeeded)+1);
        if(!TxtTmp)
            return NS_ERROR_OUT_OF_MEMORY;
    
		if (MyScolInterface)
			MyScolInterface->set_ScolVersionNeeded(TxtTmp);
		PR_FREEIF(TxtTmp);
	}
    return NS_OK;
}


/***************************************************************************/
/* JS Call CallBack Fire */
int ScolPluginInstance::SendMessageToJS(char *JSMessage)
{
	char *url;

    if (mOnJSMessage && mPluginManager) {
        url = (char *)PR_Malloc(PL_strlen(mOnJSMessage) + PL_strlen(JSMessage) + 15);
        if (!url)
            return NS_ERROR_OUT_OF_MEMORY;

        sprintf(url, "javascript:%s('%s')", mOnJSMessage,JSMessage);   
        mPluginManager->GetURL((nsIPluginInstance *)this, url, "_self");

        PR_FREEIF(url);
    }
    return 0;
}

/***************************************************************************/
/* JS Call CallBack Fire */
int ScolPluginInstance::SendEndEventToJS(int Reason)
{
	char JSMessage[10];
	char *url;

	sprintf(JSMessage,"%d",Reason);

    if (mOnScolEnd && mPluginManager) {
        url = (char *)PR_Malloc(PL_strlen(mOnScolEnd) + PL_strlen(JSMessage) + 15);
        if (!url)
            return NS_ERROR_OUT_OF_MEMORY;

        sprintf(url, "javascript:%s('%s')", mOnScolEnd,JSMessage);   
        mPluginManager->GetURL((nsIPluginInstance *)this, url, "_self");

        PR_FREEIF(url);
    }
    return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * NPP_Print:
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

NS_METHOD
ScolPluginInstance::Print(nsPluginPrint* printInfo)
{
#ifdef NS_DEBUG
    printf("ScolPluginInstance::Print\n");
#endif

    if (printInfo == NULL)
        return NS_ERROR_FAILURE;

    if (printInfo->mode == nsPluginMode_Full) {
        /*
         * PLUGIN DEVELOPERS:
         *	If your plugin would like to take over
         *	printing completely when it is in full-screen mode,
         *	set printInfo->pluginPrinted to TRUE and print your
         *	plugin as you see fit.  If your plugin wants Netscape
         *	to handle printing in this case, set
         *	printInfo->pluginPrinted to FALSE (the default) and
         *	do nothing.  If you do want to handle printing
         *	yourself, printOne is true if the print button
         *	(as opposed to the print menu) was clicked.
         *	On the Macintosh, platformPrint is a THPrint; on
         *	Windows, platformPrint is a structure
         *	(defined in npapi.h) containing the printer name, port,
         *	etc.
         */

        /* Do the default*/
        printInfo->print.fullPrint.pluginPrinted = PR_FALSE;
    }
    else {	/* If not fullscreen, we must be embedded */
        /*
         * PLUGIN DEVELOPERS:
         *	If your plugin is embedded, or is full-screen
         *	but you returned false in pluginPrinted above, NPP_Print
         *	will be called with mode == nsPluginMode_Embedded.  The nsPluginWindow
         *	in the printInfo gives the location and dimensions of
         *	the embedded plugin on the printed page.  On the
         *	Macintosh, platformPrint is the printer port; on
         *	Windows, platformPrint is the handle to the printing
         *	device context.
         */
    }
    return NS_OK;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * NPP_HandleEvent:
 * Mac-only, but stub must be present for Windows
 * Delivers a platform-specific event to the instance. 
 * 
 * On the Macintosh, event is a pointer to a standard Macintosh EventRecord.
 * All standard event types are passed to the instance as appropriate. In general,
 * return TRUE if you handle the event and FALSE if you ignore the event. 
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

NS_METHOD
ScolPluginInstance::HandleEvent(nsPluginEvent* event, PRBool* handled)
{
#ifdef NS_DEBUG
    printf("ScolPluginInstance::HandleEvent\n");
#endif

    *handled = (PRBool)PlatformHandleEvent(event);
    return NS_OK;
}

NS_METHOD
ScolPluginInstance::GetValue(nsPluginInstanceVariable variable, void *value)
{
#ifdef NS_DEBUG
    printf("ScolPluginInstance::GetValue\n");
#endif

    return NS_ERROR_FAILURE;
}

////////////////////////////////////////////////////////////////////////////////
// ScolPluginStreamListener Methods
////////////////////////////////////////////////////////////////////////////////

ScolPluginStreamListener::ScolPluginStreamListener(ScolPluginInstance* inst,
                                                       const char* msgName)
    : fMessageName(msgName)
{
    NS_INIT_REFCNT();
    char msg[256];
    sprintf(msg, "### Creating ScolPluginStreamListener for %s\n", fMessageName);
}

ScolPluginStreamListener::~ScolPluginStreamListener(void)
{
    char msg[256];
    sprintf(msg, "### Destroying ScolPluginStreamListener for %s\n", fMessageName);
}

// This macro produces a Scol version of QueryInterface, AddRef and Release.
// See the nsISupports.h header file for details.

NS_IMPL_ISUPPORTS1(ScolPluginStreamListener, nsIPluginStreamListener);

NS_METHOD
ScolPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo)
{
#ifdef NS_DEBUG
    printf("ScolPluginStreamListener::OnStartBinding\n");
#endif

    char msg[256];
    sprintf(msg, "### Opening plugin stream for %s\n", fMessageName);
    return NS_OK;
}

NS_METHOD
ScolPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo, 
                                            nsIInputStream* input, 
                                            PRUint32 length)
{
#ifdef NS_DEBUG
    printf("ScolPluginStreamListener::OnDataAvailable\n");
#endif

    char* buffer = new char[length];
    if (buffer) {
        PRUint32 amountRead = 0;
        nsresult rslt = input->Read(buffer, length, &amountRead);
        if (rslt == NS_OK) {
            char msg[256];
            sprintf(msg, "### Received %d bytes for %s\n", length, fMessageName);
        }
        delete buffer;
    }
    return NS_OK;
}

NS_METHOD
ScolPluginStreamListener::OnFileAvailable(nsIPluginStreamInfo* pluginInfo, 
                                            const char* fileName)
{
#ifdef NS_DEBUG
    printf("ScolPluginStreamListener::OnFileAvailable\n");
#endif

    char msg[256];
    sprintf(msg, "### File available for %s: %s\n", fMessageName, fileName);
    return NS_OK;
}

NS_METHOD
ScolPluginStreamListener::OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status )
{
#ifdef NS_DEBUG
    printf("ScolPluginStreamListener::OnStopBinding\n");
#endif

    char msg[256];
    sprintf(msg, "### Closing plugin stream for %s\n", fMessageName);
    return NS_OK;
}

NS_METHOD
ScolPluginStreamListener::OnNotify(const char* url, nsresult status)
{
#ifdef NS_DEBUG
    printf("ScolPluginStreamListener::OnNotify\n");
#endif

    return NS_OK;
}

NS_METHOD
ScolPluginStreamListener::GetStreamType(nsPluginStreamType *result)
{
#ifdef NS_DEBUG
    printf("ScolPluginStreamListener::GetStreamType\n");
#endif

    *result = nsPluginStreamType_Normal;
    return NS_OK;
}

/*******************************************************************************
 * SECTION 4 - Utility Method Implementations
 *******************************************************************************/

/*------------------------------------------------------------------------------
 * Platform-Specific Implemenations
 *------------------------------------------------------------------------------
 * UNIX Implementations
 *----------------------------------------------------------------------------*/

#if defined(XP_UNIX)

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * PlatformNew
 *
 * Initialize any Platform-Specific instance data.
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

void
ScolPluginInstance::PlatformNew(void)
{
//	::MessageBox(NULL,"PlateformNew","Debug",0);
    fPlatform.window = 0;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * PlatformDestroy
 *
 * Destroy any Platform-Specific instance data.
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

nsresult
ScolPluginInstance::PlatformDestroy(void)
{
//	::MessageBox(NULL,"PlateformDestroy","Debug",0);
    gtk_widget_destroy(fPlatform.moz_box);
    fPlatform.moz_box = 0;
    return NS_OK;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * PlatformSetWindow
 *
 * Perform platform-specific window operations
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

nsresult
ScolPluginInstance::PlatformSetWindow(nsPluginWindow* window)
{
#ifdef NS_DEBUG
    printf("ScolPluginInstance::PlatformSetWindow\n");
#endif

    if (window == NULL || window->window == NULL)
        return NS_ERROR_NULL_POINTER;

    GdkWindow *win = gdk_window_lookup((XID)window->window);

    if ( fPlatform.superwin && fPlatform.superwin->bin_window == win )
        return NS_OK;
    
    // should we destroy fPlatform.superwin ??
    
    fPlatform.superwin = gdk_superwin_new(win, 0, 0, window->width, window->height);

    // a little cleanup
    if (fPlatform.label)
        gtk_widget_destroy(fPlatform.label);
    if (fPlatform.moz_box)
        gtk_widget_destroy(fPlatform.moz_box);

    // create a containing mozbox and a label to put in it
    fPlatform.moz_box = gtk_mozbox_new(fPlatform.superwin->bin_window);
    fPlatform.label = gtk_label_new(fText);
    gtk_container_add(GTK_CONTAINER(fPlatform.moz_box), fPlatform.label);

    // grow the label to fit the entire mozbox
    gtk_widget_set_usize(fPlatform.label, window->width, window->height);

    // connect to expose events
    gtk_signal_connect (GTK_OBJECT(fPlatform.label), "expose_event",
                        GTK_SIGNAL_FUNC(draw), this);

    gtk_widget_show(fPlatform.label);
    gtk_widget_show(fPlatform.moz_box);

    return NS_OK;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * PlatformHandleEvent
 *
 * Handle platform-specific events.
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

int16
ScolPluginInstance::PlatformHandleEvent(nsPluginEvent* event)
{
    /* UNIX Plugins do not use HandleEvent */
    return 0;
}

NS_IMETHODIMP
ScolPluginInstance::Repaint(void)
{
#ifdef DEBUG
    printf("ScolPluginInstance::Repaint()\n");
#endif
    
    if ( !fPlatform.moz_box || !fPlatform.label )
        return NS_ERROR_FAILURE;

    // Set the label text
    gtk_label_set_text(GTK_LABEL(fPlatform.label), fText);

    // show the new label
    gtk_widget_show(fPlatform.label);
    gtk_widget_show(fPlatform.moz_box);

    return NS_OK;
}

gboolean draw (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
    ScolPluginInstance * pthis = (ScolPluginInstance *)data;

    pthis->Repaint();
    return TRUE;
}

/*------------------------------------------------------------------------------
 * Windows Implementations
 *----------------------------------------------------------------------------*/

#elif defined(XP_PC) && !defined(XP_OS2)
const char* gInstanceLookupString = "instance->pdata";

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * PlatformNew
 *
 * Initialize any Platform-Specific instance data.
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

void
ScolPluginInstance::PlatformNew(void)
{
    fPlatform.fhWnd = NULL;
    fPlatform.fDefaultWindowProc = NULL;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * PlatformDestroy
 *
 * Destroy any Platform-Specific instance data.
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

nsresult
ScolPluginInstance::PlatformDestroy(void)
{
    if( fWindow != NULL ) { /* If we have a window, clean
                                   * it up. */
        SetWindowLong( fPlatform.fhWnd, GWL_WNDPROC, (LONG)fPlatform.fDefaultWindowProc);
        fPlatform.fDefaultWindowProc = NULL;
		// Added By Tiry
		//DestroyWindow(fPlatform.fhWnd);
        fPlatform.fhWnd = NULL;
    }

    return NS_OK;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * PlatformSetWindow
 *
 * Perform platform-specific window operations
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

nsresult
ScolPluginInstance::PlatformSetWindow(nsPluginWindow* window)
{
    if( fWindow != NULL ) /* If we already have a window, clean
                           * it up before trying to subclass
                           * the new window. */
    {
        if( (window == NULL) || ( window->window == NULL ) ) {
            /* There is now no window to use. get rid of the old
             * one and exit. */
            SetWindowLong( fPlatform.fhWnd, GWL_WNDPROC, (LONG)fPlatform.fDefaultWindowProc);
            fPlatform.fDefaultWindowProc = NULL;
            fPlatform.fhWnd = NULL;
            return NS_OK;
        }

        else if ( fPlatform.fhWnd == (HWND) window->window ) {
            /* The new window is the same as the old one. Exit now. */
            return NS_OK;
        }
        else {
            /* Clean up the old window, so that we can subclass the new
             * one later. */
            SetWindowLong( fPlatform.fhWnd, GWL_WNDPROC, (LONG)fPlatform.fDefaultWindowProc);
            fPlatform.fDefaultWindowProc = NULL;
            fPlatform.fhWnd = NULL;
        }
    }
    else if( (window == NULL) || ( window->window == NULL ) ) {
        /* We can just get out of here if there is no current
         * window and there is no new window to use. */
        return NS_OK;
    }

    /* At this point, we will subclass
     * window->window so that we can begin drawing and
     * receiving window messages. */
    fPlatform.fDefaultWindowProc =
        (WNDPROC)SetWindowLong( (HWND)window->window,
                                GWL_WNDPROC, (LONG)ScolPluginInstance::PluginWindowProc);
    fPlatform.fhWnd = (HWND) window->window;
    SetProp(fPlatform.fhWnd, gInstanceLookupString, (HANDLE)this);

    InvalidateRect( fPlatform.fhWnd, NULL, TRUE );
    UpdateWindow( fPlatform.fhWnd );
    return NS_OK;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * PlatformHandleEvent
 *
 * Handle platform-specific events.
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

PRInt16
ScolPluginInstance::PlatformHandleEvent(nsPluginEvent* event)
{
    /* Windows Plugins use the Windows event call-back mechanism
       for events. (See PluginWindowProc) */
    return 0;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * PluginWindowProc
 *
 * Handle the Windows window-event loop.
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

LRESULT CALLBACK 
ScolPluginInstance::PluginWindowProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    ScolPluginInstance* inst = (ScolPluginInstance*) GetProp(hWnd, gInstanceLookupString);

    switch( Msg ) {
      case WM_PAINT: {
          PAINTSTRUCT paintStruct;
          HDC hdc;

          hdc = BeginPaint( hWnd, &paintStruct );

          if(paintStruct.fErase)
            FillRect(hdc, &paintStruct.rcPaint, 
                     (HBRUSH) GetStockObject(WHITE_BRUSH)); 

          if(inst->fText) {
            RECT rcWnd;
            GetWindowRect(hWnd, &rcWnd);
            SetTextAlign(hdc, TA_CENTER);
            TextOut(hdc, (rcWnd.right-rcWnd.left)/2, (rcWnd.bottom-rcWnd.top)/2, inst->fText, strlen(inst->fText));
          }

          EndPaint( hWnd, &paintStruct );
          break;
      }
      default: {
          CallWindowProc(inst->fPlatform.fDefaultWindowProc, hWnd, Msg, wParam, lParam);
      }
    }
    return 0;
}



/*------------------------------------------------------------------------------
 * Macintosh Implementations
 *----------------------------------------------------------------------------*/

#elif defined(XP_MAC)

PRBool	StartDraw(nsPluginWindow* window);
void 	EndDraw(nsPluginWindow* window);
void 	DoDraw(ScolPluginInstance* This);

CGrafPort 		gSavePort;
CGrafPtr		gOldPort;

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * PlatformNew
 *
 * Initialize any Platform-Specific instance data.
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

void
ScolPluginInstance::PlatformNew(void)
{
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * PlatformDestroy
 *
 * Destroy any Platform-Specific instance data.
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

nsresult
ScolPluginInstance::PlatformDestroy(void)
{
    return NS_OK;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * PlatformSetWindow
 *
 * Perform platform-specific window operations
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

nsresult
ScolPluginInstance::PlatformSetWindow(nsPluginWindow* window)
{
    fWindow = window;
    if( StartDraw( window ) ) {
        DoDraw(This);
        EndDraw( window );
    }
    return NS_OK;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * PlatformHandleEvent
 *
 * Handle platform-specific events.
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

int16
ScolPluginInstance::PlatformHandleEvent(nsPluginEvent* event)
{
    int16 eventHandled = FALSE;
	
    EventRecord* ev = (EventRecord*) event;
    if (This != NULL && event != NULL)
    {
        switch (ev->what)
        {
            /*
             * Draw ourselves on update events
             */
          case updateEvt:
            if( StartDraw( fWindow ) ) {
                DoDraw(This);
                EndDraw( fWindow );
            }
            eventHandled = true;
            break;
          default:
            break;
        }
    }
    return eventHandled;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * StartDraw
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

PRBool
ScolPluginInstance::StartDraw(nsPluginWindow* window)
{
    NP_Port* port;
    Rect clipRect;
    RGBColor  col;
	
    if (window == NULL)
        return FALSE;
    port = (NP_Port*) window->window;
    if (window->clipRect.left < window->clipRect.right)
    {
	/* Preserve the old port */
        GetPort((GrafPtr*)&gOldPort);
        SetPort((GrafPtr)port->port);
	/* Preserve the old drawing environment */
        gSavePort.portRect = port->port->portRect;
        gSavePort.txFont = port->port->txFont;
        gSavePort.txFace = port->port->txFace;
        gSavePort.txMode = port->port->txMode;
        gSavePort.rgbFgColor = port->port->rgbFgColor;
        gSavePort.rgbBkColor = port->port->rgbBkColor;
        GetClip(gSavePort.clipRgn);
	/* Setup our drawing environment */
        clipRect.top = window->clipRect.top + port->porty;
        clipRect.left = window->clipRect.left + port->portx;
        clipRect.bottom = window->clipRect.bottom + port->porty;
        clipRect.right = window->clipRect.right + port->portx;
        SetOrigin(port->portx,port->porty);
        ClipRect(&clipRect);
        clipRect.top = clipRect.left = 0;
        TextSize(12);
        TextFont(geneva);
        TextMode(srcCopy);
        col.red = col.green = col.blue = 0;
        RGBForeColor(&col);
        col.red = col.green = col.blue = 65000;
        RGBBackColor(&col);
        return TRUE;
    }
    else
        return FALSE;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * EndDraw
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

void
ScolPluginInstance::EndDraw(nsPluginWindow* window)
{
    CGrafPtr myPort;
    NP_Port* port = (NP_Port*) window->window;
    SetOrigin(gSavePort.portRect.left, gSavePort.portRect.top);
    SetClip(gSavePort.clipRgn);
    GetPort((GrafPtr*)&myPort);
    myPort->txFont = gSavePort.txFont;
    myPort->txFace = gSavePort.txFace;
    myPort->txMode = gSavePort.txMode;
    RGBForeColor(&gSavePort.rgbFgColor);
    RGBBackColor(&gSavePort.rgbBkColor);
    SetPort((GrafPtr)gOldPort);
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
 * DoDraw
 +++++++++++++++++++++++++++++++++++++++++++++++++*/

void
ScolPluginInstance::DoDraw(void)
{
    Rect drawRect;
    drawRect.top = 0;
    drawRect.left = 0;
    drawRect.bottom = drawRect.top + fWindow->height;
    drawRect.right = drawRect.left + fWindow->width;
    EraseRect( &drawRect );
    MoveTo( 2, 12 );
    DrawString("\pHello, World!");
}



/*------------------------------------------------------------------------------
 * Stub Implementations
 *----------------------------------------------------------------------------*/

#else

void
ScolPluginInstance::PlatformNew(void)
{
}

nsresult
ScolPluginInstance::PlatformDestroy(void)
{
    return NS_ERROR_NOT_IMPLEMENTED;
}

nsresult
ScolPluginInstance::PlatformSetWindow(nsPluginWindow* window)
{
    return NS_ERROR_NOT_IMPLEMENTED;
}

int16
ScolPluginInstance::PlatformHandleEvent(nsPluginEvent* event)
{
    int16 eventHandled = FALSE;
    return eventHandled;
}

#endif /* end Section 5 */

/******************************************************************************/


/*void CALLBACK ScolPluginInstance::NSDispText(const char * TheText)
{
	SetText(TheText);
}*/



/******************************************************************************/
/* Added By Tiry */

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
	char buf[255];

		PlugInDllHINSTANCE=hInstance;
		sprintf(buf,"Attach Hisntance=%d",PlugInDllHINSTANCE);
		//::MessageBox(NULL,buf,"Debug",0);
	}
	else if (dwReason == DLL_PROCESS_DETACH)
  {
		//::MessageBox(NULL,"DeAttach","Debug",0);

	}
	return TRUE;    // ok
}


