/* -*- Mode: C; c-file-style: "gnu" -*-
   japharPlugin.cpp -- the mozilla plugin entry point for the japhar OJI plugin.
   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
*/
#include "config.h"

#include "nsCOMPtr.h"
#include "nsIModule.h"
#include "nsIGenericFactory.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "japharJVMPlugin.h"

static NS_DEFINE_CID(kJapharPluginCID, JAPHAR_PLUGIN_CID);

class japharPluginModule : public nsIModule 
{
  NS_DECL_ISUPPORTS
  NS_DECL_NSIMODULE

private:

  PRBool mInitialized;

  void Shutdown();

public:

  japharPluginModule();

  virtual ~japharPluginModule();

  nsresult Initialize();
};

//----------------------------------------------------------------------------
// Class japharPluginModule [implementation]

NS_IMPL_ISUPPORTS(japharPluginModule, nsIModule::GetIID())

japharPluginModule::japharPluginModule()
: mInitialized(PR_FALSE)
{
  NS_INIT_ISUPPORTS();
}

japharPluginModule::~japharPluginModule()
{
  Shutdown();
}

nsresult japharPluginModule::Initialize()
{
  return NS_OK;
}

void japharPluginModule::Shutdown()
{
}

//----------------------------------------------------------------------------
// Interface nsIModule [implementation]

NS_IMETHODIMP japharPluginModule::GetClassObject(nsIComponentManager *aCompMgr,
						 const nsCID& aClass,
						 const nsIID& aIID,
						 void ** r_classObj)
{
  nsresult rv;

  // Defensive programming: Initialize *r_classObj in case of error below
  if (!r_classObj) {
    return NS_ERROR_INVALID_POINTER;
  }
  *r_classObj = NULL;

  if (!mInitialized) {
    rv = Initialize();
    if (NS_FAILED(rv)) {
      return rv;
    }
    mInitialized = PR_TRUE;
  }

  // Choose the appropriate factory, based on the desired instance
  // class type (aClass).
  japharJVMPlugin *fact;
  if (aClass.Equals(kJapharPluginCID)) {
    fact = new japharJVMPlugin();
  }
  
  if (fact) {
    rv = fact->QueryInterface(aIID, r_classObj);
  }
  
  return rv;
}

struct Components {
    const char* mDescription;
    const nsID* mCID;
    const char* mProgID;
};

// The list of components we register
static Components gComponents[] = {
  { "Japhar JVM Plugin", &kJapharPluginCID,
    "component:/hungry/japhar/jvm-plugin" }
};
#define NUM_COMPONENTS (sizeof(gComponents) / sizeof(gComponents[0]))

NS_IMETHODIMP
japharPluginModule::RegisterSelf(nsIComponentManager *aCompMgr,
				 nsIFileSpec* aPath,
				 const char* registryLocation,
				 const char* componentType)
{
    nsresult rv = NS_OK;

    Components* cp = gComponents;
    Components* end = cp + NUM_COMPONENTS;
    while (cp < end) {
        rv = aCompMgr->RegisterComponentSpec(*cp->mCID, cp->mDescription,
                                             cp->mProgID, aPath, PR_TRUE,
                                             PR_TRUE);
        if (NS_FAILED(rv)) {
	  break;
        }
        cp++;
    }

    return rv;
}

NS_IMETHODIMP
japharPluginModule::UnregisterSelf(nsIComponentManager* aCompMgr,
				   nsIFileSpec* aPath,
				   const char* registryLocation)
{
  Components* cp = gComponents;
  Components* end = cp + NUM_COMPONENTS;
  while (cp < end) {
    nsresult rv = aCompMgr->UnregisterComponentSpec(*cp->mCID, aPath);
    if (NS_FAILED(rv)) {
      break;
    }
    cp++;
  }
  
  return NS_OK;
}

NS_IMETHODIMP
japharPluginModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload)
{
  if (!okToUnload) {
    return NS_ERROR_INVALID_POINTER;
  }
  *okToUnload = PR_FALSE;
  return NS_ERROR_FAILURE;
}

extern "C" NS_EXPORT nsresult
NSGetModule(nsIComponentManager *compMgr,
	    nsIFileSpec *location,
	    nsIModule** return_cobj)
{
  nsresult rv = NS_OK;

  NS_ENSURE_ARG_POINTER(return_cobj);

  // Create an initialize the module instance
  japharPluginModule *jvm = new japharPluginModule();
  if (!jvm) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  // Increase refcnt and store away nsIModule interface to m in return_cobj
  rv = jvm->QueryInterface(NS_GET_IID(nsIModule), (void**)return_cobj);
  if (NS_FAILED(rv)) {
    delete jvm;
    jvm = nsnull;
  }
  return rv;
}
