/* gtkselection.c -- Native C functions for GtkSelection class using gtk+.
   Copyright (C) 2005, 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

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

GNU Classpath 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
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


#include "jcl.h"
#include "gtkpeer.h"
#include "gnu_java_awt_peer_gtk_GtkSelection.h"

static jmethodID mimeTypesAvailableID;

/* Note this is actually just a GtkClipboardReceivedFunc, not a real
   GtkClipboardTargetsReceivedFunc, see requestMimeTypes. */
static void
clipboard_targets_received (GtkClipboard *clipboard
			    __attribute__((unused)),
			    GtkSelectionData *target_data,
			    gpointer selection)
{
  GdkAtom *targets = NULL;
  gint targets_len = 0;
  gchar **target_strings = NULL;
  jobjectArray strings = NULL;
  int strings_len = 0;
  gboolean include_text = FALSE;
  gboolean include_image = FALSE;
  gboolean include_uris = FALSE;
  jobject selection_obj = (jobject) selection;
  JNIEnv *env = cp_gtk_gdk_env ();

  if (target_data != NULL && target_data->length > 0)
    {
      include_text = gtk_selection_data_targets_include_text (target_data);

#if GTK_MINOR_VERSION > 4
      include_image = gtk_selection_data_targets_include_image (target_data,
								TRUE);
#endif
      if (gtk_selection_data_get_targets (target_data, &targets, &targets_len))
	{
	  int i;
	  GdkAtom uri_list_atom = gdk_atom_intern ("text/uri-list", FALSE);
	  target_strings = g_new (gchar*, targets_len);
	  if (target_strings != NULL)
	    for (i = 0; i < targets_len; i++)
	      {
		gchar *name =  gdk_atom_name (targets[i]);
		if (strchr (name, '/') != NULL)
		  {
		    target_strings[i] = name;
		    strings_len++;
		    if (! include_uris && targets[i] == uri_list_atom)
		      include_uris = TRUE;
		  }
		else
		  target_strings[i] = NULL;
	      }
	}

      if (target_strings != NULL)
	{
	  int i = 0, j = 0;
	  jclass stringClass;
	  
	  if (include_text)
	    strings_len++;
	  if (include_image)
	    strings_len++;
	  if (include_uris)
	    strings_len++;
	  
	  stringClass = (*env)->FindClass (env, "java/lang/String");
	  strings = (*env)->NewObjectArray (env, strings_len, stringClass,
					    NULL);
	  (*env)->DeleteLocalRef(env, stringClass);

	  if (strings != NULL)
	    {
	      if (include_text)
		(*env)->SetObjectArrayElement (env, strings, i++,
					       cp_gtk_stringTarget);
	      if (include_image)
		(*env)->SetObjectArrayElement (env, strings, i++,
					       cp_gtk_imageTarget);
	      if (include_uris)
		(*env)->SetObjectArrayElement (env, strings, i++,
					       cp_gtk_filesTarget);
	      
	      while(i < strings_len)
		{
		  if (target_strings[j] == NULL)
		    j++;
		  else
		    {
		      jstring string;
		      string = (*env)->NewStringUTF (env,
						     target_strings[j++]);
		      if (string == NULL)
			break;
		      (*env)->SetObjectArrayElement (env, strings, i++,
						     string);
		      (*env)->DeleteLocalRef (env, string);
		    }
		}

	      (*env)->DeleteLocalRef(env, strings);
	    }

	  for (i = 0; i < targets_len; i++)
	    g_free (target_strings[i]);
	  g_free (target_strings);
	}
    }

  (*env)->CallVoidMethod (env, selection_obj,
			  mimeTypesAvailableID,
			  strings);
  (*env)->DeleteGlobalRef (env, selection_obj);
}

JNIEXPORT void JNICALL 
Java_gnu_java_awt_peer_gtk_GtkSelection_requestMimeTypes
(JNIEnv *env, jobject selection, jboolean clipboard)
{
  jobject selection_obj;
  GtkClipboard *gtk_clipboard;
  selection_obj = (*env)->NewGlobalRef(env, selection);
  if (selection_obj == NULL)
    return;

  if (mimeTypesAvailableID == NULL)
    {
      jclass gtk_selection_class;
      gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
      mimeTypesAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
						"mimeTypesAvailable",
						"([Ljava/lang/String;)V");
      if (mimeTypesAvailableID == NULL)
	return;
    }

  if (clipboard)
    gtk_clipboard = cp_gtk_clipboard;
  else
    gtk_clipboard = cp_gtk_selection;

  /* We would have liked to call gtk_clipboard_request_targets ()
     since that is more general. But the result of that, an array of
     GdkAtoms, cannot be used with the
     gtk_selection_data_targets_include_<x> functions (despite what
     the name suggests). */
  gdk_threads_enter ();
  gtk_clipboard_request_contents (gtk_clipboard,
				  gdk_atom_intern ("TARGETS", FALSE),
				  clipboard_targets_received,
				  (gpointer) selection_obj);
  gdk_threads_leave ();
}


static jmethodID textAvailableID;

static void
clipboard_text_received (GtkClipboard *clipboard
			 __attribute__((unused)),
			 const gchar *text,
			 gpointer selection)
{
  jstring string;
  jobject selection_obj = (jobject) selection;

  JNIEnv *env = cp_gtk_gdk_env ();
  if (text != NULL)
    string = (*env)->NewStringUTF (env, text);
  else
    string = NULL;

  (*env)->CallVoidMethod (env, selection_obj,
                          textAvailableID,
                          string);
  (*env)->DeleteGlobalRef (env, selection_obj);

  if (string != NULL)
    (*env)->DeleteLocalRef (env, string);

}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkSelection_requestText
(JNIEnv *env, jobject selection, jboolean clipboard)
{
  jobject selection_obj;
  GtkClipboard *gtk_clipboard;
  selection_obj = (*env)->NewGlobalRef(env, selection);
  if (selection_obj == NULL)
    return;

  if (textAvailableID == NULL)
    {
      jclass gtk_selection_class;
      gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
      textAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
					     "textAvailable",
					     "(Ljava/lang/String;)V");
      if (textAvailableID == NULL)
        return;
    }

  if (clipboard)
    gtk_clipboard = cp_gtk_clipboard;
  else
    gtk_clipboard = cp_gtk_selection;

  gdk_threads_enter ();
  gtk_clipboard_request_text (gtk_clipboard,
			      clipboard_text_received,
			      (gpointer) selection_obj);
  gdk_threads_leave ();
}

static jmethodID imageAvailableID;

static void
clipboard_image_received (GtkClipboard *clipboard
			  __attribute__((unused)),
			  GdkPixbuf *pixbuf,
			  gpointer selection)
{
  jobject pointer = NULL;
  jobject selection_obj = (jobject) selection;
  JNIEnv *env = cp_gtk_gdk_env ();

  if (pixbuf != NULL)
    {
      g_object_ref (pixbuf);
      pointer = JCL_NewRawDataObject (env, (void *) pixbuf);
    }

  (*env)->CallVoidMethod (env, selection_obj,
			  imageAvailableID,
                          pointer);
  (*env)->DeleteGlobalRef (env, selection_obj);
}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkSelection_requestImage (JNIEnv *env,
						      jobject obj,
						      jboolean clipboard)
{
  jobject selection_obj;
  GtkClipboard *gtk_clipboard;
  selection_obj = (*env)->NewGlobalRef(env, obj);
  if (selection_obj == NULL)
    return;

  if (imageAvailableID == NULL)
    {
      jclass gtk_selection_class;
      gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
      imageAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
					     "imageAvailable",
					     "(Lgnu/classpath/Pointer;)V");
      if (imageAvailableID == NULL)
        return;
    }

  if (clipboard)
    gtk_clipboard = cp_gtk_clipboard;
  else
    gtk_clipboard = cp_gtk_selection;

#if GTK_MINOR_VERSION > 4
  gdk_threads_enter ();
  gtk_clipboard_request_image (gtk_clipboard,
			       clipboard_image_received,
			       (gpointer) selection_obj);
  gdk_threads_leave ();
#else
  clipboard_image_received (gtk_clipboard, NULL, (gpointer) selection_obj);
#endif
}

static jmethodID urisAvailableID;

static void
clipboard_uris_received (GtkClipboard *clipboard
			 __attribute__((unused)),
			 GtkSelectionData *uri_data,
			 gpointer selection)
{
  gchar **uris = NULL;
  jobjectArray strings = NULL;
  jobject selection_obj = (jobject) selection;
  JNIEnv *env = cp_gtk_gdk_env ();

#if GTK_MINOR_VERSION > 4
  if (uri_data != NULL)
    uris = gtk_selection_data_get_uris (uri_data);
#else
  if (uri_data != NULL)
    uris = NULL;
#endif

  if (uris != NULL)
    {
      int len, i;
      gchar **count = uris;
      jclass stringClass = (*env)->FindClass (env, "java/lang/String");

      len = 0;
      while (count[len])
	len++;

      strings = (*env)->NewObjectArray (env, len, stringClass, NULL);
      (*env)->DeleteLocalRef(env, stringClass);

      if (strings != NULL)
	{
	  for (i = 0; i < len; i++)
	    {
	      jstring string = (*env)->NewStringUTF (env, uris[i]);
	      if (string == NULL)
		break;
	      (*env)->SetObjectArrayElement (env, strings, i, string);
	      (*env)->DeleteLocalRef (env, string);
	    }

	  (*env)->DeleteLocalRef(env, strings);
	}
      g_strfreev (uris);
    }

  (*env)->CallVoidMethod (env, selection_obj,
                          urisAvailableID,
                          strings);
  (*env)->DeleteGlobalRef (env, selection_obj);
}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkSelection_requestURIs (JNIEnv *env,
						     jobject obj,
						     jboolean clipboard)
{
#if GTK_MINOR_VERSION > 4
  GdkAtom uri_atom;
#endif
  jobject selection_obj;
  GtkClipboard *gtk_clipboard;
  selection_obj = (*env)->NewGlobalRef(env, obj);
  if (selection_obj == NULL)
    return;

  if (urisAvailableID == NULL)
    {
      jclass gtk_selection_class;
      gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
      urisAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
					     "urisAvailable",
                                             "([Ljava/lang/String;)V");
      if (urisAvailableID == NULL)
        return;
    }

  if (clipboard)
    gtk_clipboard = cp_gtk_clipboard;
  else
    gtk_clipboard = cp_gtk_selection;

#if GTK_MINOR_VERSION > 4
  /* There is no real request_uris so we have to make one ourselves. */
  gdk_threads_enter ();
  uri_atom = gdk_atom_intern ("text/uri-list", FALSE);
  gtk_clipboard_request_contents (gtk_clipboard,
				  uri_atom,
				  clipboard_uris_received,
				  (gpointer) selection_obj);
  gdk_threads_leave ();
#else
  clipboard_uris_received (gtk_clipboard, NULL, (gpointer) selection_obj);
#endif
}

static jmethodID bytesAvailableID;

static void
clipboard_bytes_received (GtkClipboard *clipboard
			  __attribute__((unused)),
			  GtkSelectionData *selection_data,
			  gpointer selection)
{
  jbyteArray bytes = NULL;
  jobject selection_obj = (jobject) selection;
  JNIEnv *env = cp_gtk_gdk_env ();

   if (selection_data != NULL && selection_data->length > 0)
    {
      bytes = (*env)->NewByteArray (env, selection_data->length);
      if (bytes != NULL)
	(*env)->SetByteArrayRegion(env, bytes, 0, selection_data->length,
				   (jbyte *) selection_data->data);
    }

  (*env)->CallVoidMethod (env, selection_obj,
                          bytesAvailableID,
                          bytes);
  (*env)->DeleteGlobalRef (env, selection_obj);
}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkSelection_requestBytes (JNIEnv *env,
						      jobject obj,
						      jboolean clipboard,
						      jstring target_string)
{
  int len;
  const gchar *target_text;
  GdkAtom target_atom;
  jobject selection_obj;
  GtkClipboard *gtk_clipboard;
  selection_obj = (*env)->NewGlobalRef(env, obj);
  if (selection_obj == NULL)
    return;

  if (bytesAvailableID == NULL)
    {
      jclass gtk_selection_class;
      gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
      bytesAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
					      "bytesAvailable",
					      "([B)V");
      if (bytesAvailableID == NULL)
        return;
    }

  len = (*env)->GetStringUTFLength (env, target_string);
  if (len == -1)
    return;
  target_text = (*env)->GetStringUTFChars (env, target_string, NULL);
  if (target_text == NULL)
    return;

  if (clipboard)
    gtk_clipboard = cp_gtk_clipboard;
  else
    gtk_clipboard = cp_gtk_selection;

  gdk_threads_enter ();
  target_atom = gdk_atom_intern (target_text, FALSE);
  gtk_clipboard_request_contents (gtk_clipboard,
                                  target_atom,
                                  clipboard_bytes_received,
                                  (gpointer) selection_obj);
  gdk_threads_leave ();

  (*env)->ReleaseStringUTFChars (env, target_string, target_text);
}
