/* GtkListPeer.c -- implements GtkListPeer's native methods
   Copyright (C) 1998, 1999, 2003, 2004 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 "gtkpeer.h"
#include "gnu_java_awt_peer_gtk_GtkListPeer.h"

static jmethodID postListItemEventID;
static GtkWidget *list_get_widget (GtkWidget *widget);

void
cp_gtk_list_init_jni (void)
{
  jclass gtklistpeer;

  gtklistpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
                                         "gnu/java/awt/peer/gtk/GtkListPeer");

  postListItemEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtklistpeer,
                                                   "postItemEvent",
                                                   "(II)V");
}

enum
  {
    COLUMN_STRING,
    N_COLUMNS
  };

static gboolean item_highlighted_cb (GtkTreeSelection *selection,
                                     GtkTreeModel *model,
                                     GtkTreePath *path,
                                     gboolean path_currently_selected,
                                     jobject peer);


JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_create
  (JNIEnv *env, jobject obj, jint rows)
{
  GtkWidget *sw;
  GtkWidget *list;
  GtkWidget *eventbox;
  GtkCellRenderer *renderer;
  GtkTreeViewColumn *column;
  GtkListStore *list_store;
  GtkTreeIter iter;
  GtkRequisition req;
  gint i;

  gdk_threads_enter ();

  /* Create global reference and save it for future use */
  gtkpeer_set_global_ref (env, obj);

  list_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING);
  /* Add the number of rows so that we can calculate the tree view's
     size request. */
  for (i = 0; i < rows; i++)
    {
      gtk_list_store_append (list_store, &iter);
      gtk_list_store_set (list_store, &iter,
                          COLUMN_STRING, "",
                          -1);
    }
  list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes (NULL,
				     renderer,
				     "text",
				     COLUMN_STRING,
				     NULL);

  eventbox = gtk_event_box_new ();
  sw = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
				  GTK_POLICY_AUTOMATIC,
				  GTK_POLICY_AUTOMATIC);
  gtk_container_add (GTK_CONTAINER (eventbox), sw);
  
  gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);

  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE);

  gtk_widget_size_request (GTK_WIDGET (list), &req);

  gtk_widget_set_size_request (GTK_WIDGET (list), req.width, req.height);

  gtk_container_add (GTK_CONTAINER (sw), list);

  /* Remove the blank rows. */
  gtk_list_store_clear (list_store);

  gtk_widget_show (list);
  gtk_widget_show (sw);

  gtkpeer_set_widget (env, obj, eventbox);

  gdk_threads_leave ();
}

JNIEXPORT void JNICALL 
Java_gnu_java_awt_peer_gtk_GtkListPeer_connectSignals
  (JNIEnv *env, jobject obj)
{
  void *ptr;
  jobject gref;
  GtkWidget *list;
  GtkTreeSelection *selection;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);
  gref = gtkpeer_get_global_ref (env, obj);

  list = list_get_widget (GTK_WIDGET (ptr));

  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
  gtk_tree_selection_set_select_function (selection, item_highlighted_cb,
                                          gref, NULL);

  cp_gtk_component_connect_signals (G_OBJECT (list), gref);

  gdk_threads_leave ();
}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetModifyFont
  (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
{
  const char *font_name;
  void *ptr;
  GtkWidget *list;
  PangoFontDescription *font_desc;

  gdk_threads_enter();

  ptr = gtkpeer_get_widget (env, obj);

  list = list_get_widget (GTK_WIDGET (ptr));

  font_name = (*env)->GetStringUTFChars (env, name, NULL);

  font_desc = pango_font_description_from_string (font_name);
  pango_font_description_set_size (font_desc,
                                   size * cp_gtk_dpi_conversion_factor);

  if (style & AWT_STYLE_BOLD)
    pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);

  if (style & AWT_STYLE_ITALIC)
    pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);

  gtk_widget_modify_font (GTK_WIDGET (list), font_desc);

  pango_font_description_free (font_desc);

  (*env)->ReleaseStringUTFChars (env, name, font_name);

  gdk_threads_leave();
}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetRequestFocus
  (JNIEnv *env, jobject obj)
{
  void *ptr;
  GtkWidget *list;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);
  
  list = list_get_widget (GTK_WIDGET (ptr));
  gtk_widget_grab_focus (list);

  gdk_threads_leave ();
}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_append
  (JNIEnv *env, jobject obj, jobjectArray items)
{
  void *ptr;
  GtkWidget *list;
  GtkTreeIter iter;
  GtkTreeModel *list_store;
  jint count;
  jint i;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  count = (*env)->GetArrayLength (env, items);

  list = list_get_widget (GTK_WIDGET (ptr));
  list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));

  for (i = 0; i < count; i++)
    {
      const char *text;
      jobject item;

      item = (*env)->GetObjectArrayElement (env, items, i);

      text = (*env)->GetStringUTFChars (env, item, NULL);
      gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
      gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
                          COLUMN_STRING, text,
                          -1);
      (*env)->ReleaseStringUTFChars (env, item, text);
      (*env)->DeleteLocalRef(env, item);
    }

  gdk_threads_leave ();
}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_add
  (JNIEnv *env, jobject obj, jstring text, jint index)
{
  void *ptr;
  const char *str;
  GtkWidget *list;
  GtkTreeIter iter;
  GtkTreeModel *list_store;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);
  str = (*env)->GetStringUTFChars (env, text, NULL);

  list = list_get_widget (GTK_WIDGET (ptr));
  list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));

  if (index == -1)
    gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
  else
    gtk_list_store_insert (GTK_LIST_STORE (list_store), &iter, index);

  gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
                      COLUMN_STRING, str, -1);

  (*env)->ReleaseStringUTFChars (env, text, str);

  gdk_threads_leave ();
}


JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_delItems
  (JNIEnv *env, jobject obj, jint start, jint end)
{
  void *ptr;
  GtkWidget *list;
  GtkTreeIter iter;
  GtkTreeModel *list_store;
  jint i;
  jint num_items;
    
  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  list = list_get_widget (GTK_WIDGET (ptr));
  list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));

  /* Special case: remove all rows. */
  if (end == -1)
    gtk_list_store_clear (GTK_LIST_STORE (list_store));
  else
    {
      i = 0;
      num_items = end - start + 1;
      gtk_tree_model_iter_nth_child (list_store, &iter, NULL, start);
      while (i < num_items)
	{
	  gtk_list_store_remove (GTK_LIST_STORE (list_store), &iter);
	  i++;
	}
    }

  gdk_threads_leave ();
}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_select
  (JNIEnv *env, jobject obj, jint index)
{
  void *ptr;
  GtkWidget *list;
  GtkTreePath *path;
    
  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  list = list_get_widget (GTK_WIDGET (ptr));
  path = gtk_tree_path_new_from_indices (index, -1);
  gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, NULL, FALSE);

  gdk_threads_leave ();
}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_deselect
  (JNIEnv *env, jobject obj, jint index)
{
  void *ptr;
  GtkWidget *list;
  GtkTreeSelection *selection;
  GtkTreePath *path;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  list = list_get_widget (GTK_WIDGET (ptr));
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
  path = gtk_tree_path_new_from_indices (index, -1);
  gtk_tree_selection_unselect_path (selection, path);

  gdk_threads_leave ();
}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_getSize
  (JNIEnv *env, jobject obj, jint rows, jint visible_rows, jintArray jdims)
{
  void *ptr;
  jint *dims;
  GtkRequisition current_req;
  GtkRequisition natural_req;
  GtkWidget* bin;

  gdk_threads_enter ();

  dims = (*env)->GetIntArrayElements (env, jdims, NULL);
  dims[0] = dims[1] = 0;

  ptr = gtkpeer_get_widget (env, obj);
  bin = list_get_widget (GTK_WIDGET (ptr));
  
  /* Save the widget's current size request. */
  gtk_widget_size_request (bin, &current_req);
      
  /* Get the widget's "natural" size request. */
  gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
  gtk_widget_size_request (bin, &natural_req);

  /* Reset the widget's size request. */
  gtk_widget_set_size_request (bin,
                               current_req.width, current_req.height);

  dims[0] = natural_req.width;

  /* Calculate the final height, by comparing the number of rows
     in the list to the number of rows requested by the caller.
     FIXME: Is there a GTK method that counts the number of rows
     in the list? If so, we don't need to bring visible_rows from
     the Java peer. */
  if (rows == visible_rows)
    dims[1] = natural_req.height;
  else
    dims[1] = natural_req.height / visible_rows * rows;

  (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);

  gdk_threads_leave ();
}


JNIEXPORT jintArray JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_getSelectedIndexes
  (JNIEnv *env, jobject obj)
{
  void *ptr;
  GtkWidget *list;
  GtkTreeSelection *selection;
  jintArray result_array;
  jint *result_array_iter;
  GList *current_row;
  GList *rows;
  gint *indices;
  jint count;
  jint i;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  list = list_get_widget (GTK_WIDGET (ptr));
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
  count = gtk_tree_selection_count_selected_rows (selection);
  if (count > 0)
    {
      current_row = rows = gtk_tree_selection_get_selected_rows (selection, NULL);

      result_array = (*env)->NewIntArray (env, count);

      result_array_iter = (*env)->GetIntArrayElements (env, result_array, NULL);

      for (i = 0; i < count; i++)
        {
          indices = gtk_tree_path_get_indices (current_row->data);
          result_array_iter[i] = indices ? indices[0] : -1;
          current_row = g_list_next (current_row);
        }

      if (rows)
        {
          g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
          g_list_free (rows);
        }

      (*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
    }
  else
    result_array = NULL;

  gdk_threads_leave ();

  return result_array;
}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_makeVisible
  (JNIEnv *env, jobject obj, jint index)
{
  void *ptr;
  GtkWidget *list;
  GtkTreePath *path;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  list = list_get_widget (GTK_WIDGET (ptr));
  path = gtk_tree_path_new_from_indices (index, -1);
  gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (list), path,
                                NULL, FALSE, 0.0, 0.0);

  gdk_threads_leave ();
}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_setMultipleMode
  (JNIEnv *env, jobject obj, jboolean mode)
{
  void *ptr;
  GtkWidget *list;
  GtkTreeSelection *selection;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  list = list_get_widget (GTK_WIDGET (ptr));
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
  gtk_tree_selection_set_mode (selection,
                               mode ? GTK_SELECTION_MULTIPLE
                               : GTK_SELECTION_SINGLE);

  gdk_threads_leave ();
}

static gboolean
item_highlighted_cb (GtkTreeSelection *selection __attribute__((unused)),
                     GtkTreeModel *model,
                     GtkTreePath *path,
                     gboolean path_currently_selected,
                     jobject peer)
{
  GtkTreeIter iter;
  jint row;
  gint *indices;

  if (gtk_tree_model_get_iter (model, &iter, path))
    {
      indices = gtk_tree_path_get_indices (path);
      row = indices ? indices[0] : -1;

      if (!path_currently_selected)
        {
          (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
                                        postListItemEventID,
                                        row,
                                        (jint) AWT_ITEM_SELECTED);
        }
      else
        {
          (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
                                        postListItemEventID,
                                        row,
                                        (jint) AWT_ITEM_DESELECTED);
        }
    }

  return TRUE;
}

static GtkWidget *
list_get_widget (GtkWidget *widget)
{
   GtkWidget *wid;
   g_assert (GTK_IS_EVENT_BOX (widget));

   wid = gtk_bin_get_child (GTK_BIN (widget));
   g_assert (GTK_IS_SCROLLED_WINDOW (wid));

   wid = gtk_bin_get_child (GTK_BIN (wid));

   return wid;
}

