/* -*- Mode: C; c-file-style: "gnu" -*-
   japharJVMConsole.cpp -- japhar's java console for mozilla.
   Created: Chris Toshok <toshok@hungry.com>, 19-Sep-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 "jniint.h"
#include "japharJVMConsole.h"

extern PRLogModuleInfo *japharOJILm;

japharJVMConsole::japharJVMConsole(nsISupports* outer)
{
  NS_INIT_AGGREGATED(outer);

  _console = NULL;

  HungryEnv *henv = HVM_ThreadGetEnv();
  JNIEnv *env = (JNIEnv*)henv->thread_env;
  jclass console_class;
  jmethodID ctor;

  console_class = env->FindClass("com/hungry/java/japhar/JapharConsole");
  if (console_class == NULL)
    return;

  ctor = env->GetMethodID(console_class, "<init>", "()V");
  _console = env->NewGlobalRef(env->NewObject(console_class, ctor));

  _showMethod = env->GetMethodID(console_class, "show", "()V");
  _hideMethod = env->GetMethodID(console_class, "hide", "()V");
  _printMethod = env->GetMethodID(console_class, "print", "(Ljava/lang/String;Ljava/lang/String;)V");
}

japharJVMConsole::~japharJVMConsole()
{
  HungryEnv *henv = HVM_ThreadGetEnv();
  JNIEnv *env = (JNIEnv*)henv->thread_env;

  if (_console)
    env->DeleteGlobalRef(_console);
}

NS_IMPL_AGGREGATED(japharJVMConsole)

nsresult
japharJVMConsole::AggregatedQueryInterface(const nsIID& aIID,
					   void ** aInstancePtr)
{
  static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
  static NS_DEFINE_IID(kIJVMConsoleIID, NS_IJVMCONSOLE_IID);

  if (NULL == aInstancePtr)
    {
      return NS_ERROR_NULL_POINTER;
    }
  else if (aIID.Equals(kIJVMConsoleIID))
    {
      *aInstancePtr = (void*) ((nsIJVMConsole*)this);
    }
  else if (aIID.Equals(kISupportsIID))
    {
      *aInstancePtr = (void*) ((nsISupports*)this);
    }
  return NS_NOINTERFACE;
}

/////////////////////////////////////////////////
// nsIJVMConsole Interface
/////////////////////////////////////////////////

nsresult
japharJVMConsole::Show(void)
{
  HungryEnv *henv = HVM_ThreadGetEnv();
  JNIEnv *env = (JNIEnv*)henv->thread_env;

  PR_LOG (japharOJILm, PR_LOG_DEBUG, ("In japharJVMConsole::ShowConsole\n"));

  if (_console)
    env->CallVoidMethod(_console, _showMethod);

  return NS_OK;
}

nsresult
japharJVMConsole::Hide(void)
{
  HungryEnv *henv = HVM_ThreadGetEnv();
  JNIEnv *env = (JNIEnv*)henv->thread_env;

  PR_LOG (japharOJILm, PR_LOG_DEBUG, ("In japharJVMConsole::HideConsole\n"));

  if (_console)
    env->CallVoidMethod(_console, _hideMethod);

  return NS_OK;
}

nsresult
japharJVMConsole::IsVisible(PRBool *result)
{
  PR_LOG (japharOJILm, PR_LOG_DEBUG, ("In japharJVMConsole::isConsoleVisible\n"));
  *result = PR_FALSE;
  return NS_OK;
}

// Prints a message to the Java console. The encodingName specifies the
// encoding of the message, and if NULL, specifies the default platform
// encoding.
/*
** XXX toshok - umm.. this won't work if the encoding specified has
** embedded 0's in it, as I'm sure some of the character encodings
** java supports can.  
*/
nsresult
japharJVMConsole::Print(const char* msg,
			const char* encodingName)
{
  HungryEnv *henv = HVM_ThreadGetEnv();
  JNIEnv *env = (JNIEnv*)henv->thread_env;
  jbyteArray msg_bytes;
  jbyte* bytes;
  int msg_length;
  jstring msg_str, encoding_str;
  jclass string_class;
  jmethodID ctor;

  PR_LOG (japharOJILm, PR_LOG_DEBUG, ("In japharJVMConsole::Print(msg = %s)\n", msg));
  
  string_class = env->FindClass("java/lang/String");

  if (!_console)
    return NS_OK;

  msg_length = strlen(msg);
  msg_bytes = env->NewByteArray(msg_length);
  bytes = env->GetByteArrayElements(msg_bytes, NULL);

  memcpy(bytes, msg, msg_length);
  env->ReleaseByteArrayElements(msg_bytes, bytes, JNI_COMMIT);

  if (encodingName != NULL)
    {
      encoding_str = env->NewStringUTF(encodingName);
      ctor = env->GetMethodID(string_class, "<init>", "([BLjava/lang/String;)V");
      msg_str = env->NewObject(string_class, ctor, msg_bytes, encoding_str);
    }
  else
    {
      ctor = env->GetMethodID(string_class, "<init>", "([B)V");
      msg_str = env->NewObject(string_class, ctor, msg_bytes);
    }
  
  env->CallVoidMethod(_console, _printMethod, msg_str);

  return NS_OK;
}
