/* -*- Mode: C; c-file-style: "gnu" -*-
   japharJVMPluginInstance.cpp -- japhar's mozilla java runtime support 
                                  (this class is instanciated for APPLET tags.)
   Created: Chris Toshok <toshok@hungry.com>, 8-Aug-1998
 */
/*
  This file is part of Japhar, the GNU Virtual Machine for Java Bytecodes.
  Japhar is a project of The Hungry Programmers, GNU, and OryxSoft.

  Copyright (C) 1997, 1998, 1999 The Hungry Programmers

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library 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
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#ifndef _japharJVMPluginInstance_h
#define _japharJVMPluginInstance_h

#include "nsplugin.h"
#include "nsIJVMPluginInstance.h"
#include <Xm/Xm.h>

class japharJVMPluginInstance : public virtual nsIJVMPluginInstance,
				public virtual nsIPluginInstance {
public:
  /////////////////////////////////////////////////
  // nsISupports
  /////////////////////////////////////////////////

  NS_DECL_ISUPPORTS

  /////////////////////////////////////////////////
  // nsIEventHandler
  /////////////////////////////////////////////////

  /**
   * Handles an event. An nsIEventHandler can also get registered with with
   * nsIPluginManager2::RegisterWindow and will be called whenever an event
   * comes in for that window.
   *
   * 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.
   *
   * (Corresponds to NPP_HandleEvent.)
   *
   * @param event - the event to be handled
   * @param handled - set to PR_TRUE if event was handled
   * @result - NS_OK if this operation was successful
   */
  NS_IMETHOD
  HandleEvent(nsPluginEvent* event, PRBool* handled);


  /////////////////////////////////////////////////
  // nsIPluginInstance
  /////////////////////////////////////////////////

  /**
   * Initializes a newly created plugin instance, passing to it the plugin
   * instance peer which it should use for all communication back to the browser.
   * 
   * @param peer - the corresponding plugin instance peer
   * @result - NS_OK if this operation was successful
   */
  NS_IMETHOD
  Initialize(nsIPluginInstancePeer* peer);

  /**
   * Returns a reference back to the plugin instance peer. This method is
   * used whenever the browser needs to obtain the peer back from a plugin
   * instance. The implementation of this method should be sure to increment
   * the reference count on the peer by calling AddRef.
   *
   * @param resultingPeer - the resulting plugin instance peer
   * @result - NS_OK if this operation was successful
   */
  NS_IMETHOD
  GetPeer(nsIPluginInstancePeer* *resultingPeer);
  
  /**
   * Called to instruct the plugin instance to start. This will be called after
   * the plugin is first created and initialized, and may be called after the
   * plugin is stopped (via the Stop method) if the plugin instance is returned
   * to in the browser window's history.
   *
   * @result - NS_OK if this operation was successful
   */
  NS_IMETHOD
  Start(void);
  
  /**
   * Called to instruct the plugin instance to stop, thereby suspending its state.
   * This method will be called whenever the browser window goes on to display
   * another page and the page containing the plugin goes into the window's history
   * list.
   *
   * @result - NS_OK if this operation was successful
   */
  NS_IMETHOD
  Stop(void);
  
  /**
   * Called to instruct the plugin instance to destroy itself. This is called when
   * it become no longer possible to return to the plugin instance, either because 
   * the browser window's history list of pages is being trimmed, or because the
   * window containing this page in the history is being closed.
   *
   * @result - NS_OK if this operation was successful
   */
  NS_IMETHOD
  Destroy(void);
  
  /**
   * Called when the window containing the plugin instance changes.
   *
   * (Corresponds to NPP_SetWindow.)
   *
   * @param window - the plugin window structure
   * @result - NS_OK if this operation was successful
   */
  NS_IMETHOD
  SetWindow(nsPluginWindow* window);

    /**
     * Called to tell the plugin that the initial src/data stream is
     * ready.  Expects the plugin to return a nsIPluginStreamListener.
     *
     * (Corresponds to NPP_NewStream.)
     *
     * @param listener - listener the browser will use to give the plugin the data
     * @result - NS_OK if this operation was successful
     */
  NS_IMETHOD
  NewStream(nsIPluginStreamListener** listener);
  
  /**
   * Called to instruct the plugin instance to print itself to a printer.
   *
   * (Corresponds to NPP_Print.)
   *
   * @param platformPrint - platform-specific printing information
   * @result - NS_OK if this operation was successful
   */
  NS_IMETHOD
  Print(nsPluginPrint* platformPrint);

  /**
   * Called to notify the plugin instance that a URL request has been
   * completed. (See nsIPluginManager::GetURL and nsIPluginManager::PostURL).
   *
   * (Corresponds to NPP_URLNotify.)
   *
   * @param url - the requested URL
   * @param target - the target window name
   * @param reason - the reason for completion
   * @param notifyData - the notify data supplied to GetURL or PostURL
   * @result - NS_OK if this operation was successful
   */
  NS_IMETHOD
  URLNotify(const char* url, const char* target,
	    nsPluginReason reason, void* notifyData);


  /**
   * Returns the value of a variable associated with the plugin instance.
   *
   * @param variable - the plugin instance variable to get
   * @param value - the address of where to store the resulting value
   * @result - NS_OK if this operation was successful
   */
  NS_IMETHOD
  GetValue(nsPluginInstanceVariable variable, void *value);
  
  /////////////////////////////////////////////////
  // nsIJVMPluginInstance
  /////////////////////////////////////////////////
  
  // This method is called when LiveConnect wants to find the Java object
  // associated with this plugin instance, e.g. the Applet or JavaBean object.
  NS_IMETHOD
  GetJavaObject(jobject *result);
  
  NS_IMETHOD
  GetText(const char* *result);

  nsISupports *GetPluginManager();

  japharJVMPluginInstance(JavaVM *vm, nsISupports *pluginManager);
private:
  static void Redraw(Widget w, XtPointer closure, XEvent *event);

  nsresult InitializeClassLoader();
  nsresult InitializeAppletContext();
  nsresult InitializeApplet();

  nsIPluginInstancePeer* _peer;
  const char *_code, *_archive, *_name;
  const char *_codebase;
  PRBool _mayscript;

  Window _window;
  Display *_display;
  int _x;
  int _y;
  int _width;
  int _height;

  JavaVM *_vm;
  JNIEnv *_env;
  jobject _obj;

  jobject _applContext;
  jclass _applet_class;

  jclass _class_loader_class;
  jobject _class_loader;

  jmethodID _start_method;
  jmethodID _stop_method;
  jmethodID _init_method;
  jmethodID _destroy_method;

  nsISupports *_pluginman;

  jboolean _started;
};

#endif /* _japharJVMPluginInstance_h */
