/* Magical NSA API -- Associate a C ptr with an instance of an object
   Copyright (C) 1998, 2002 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 <stdlib.h>
#include <assert.h>
#include <jni.h>
#include "native_state.h"

#define DEFAULT_TABLE_SIZE 97

struct state_table *
cp_gtk_init_state_table_with_size (JNIEnv * env, jclass clazz, jint size)
{
  struct state_table *table;
  jfieldID hash;
  jclass clazz_g;

  hash = (*env)->GetFieldID (env, clazz, "native_state", "I");
  if (hash == NULL)
    return NULL;

  clazz_g = (*env)->NewGlobalRef (env, clazz);
  if (clazz_g == NULL)
    return NULL;

  table = (struct state_table *) malloc (sizeof (struct state_table));
  table->size = size;
  table->head = (struct state_node **) calloc (sizeof (struct state_node *),
					       table->size);
  table->hash = hash;
  table->clazz = clazz_g;

  return table;
}

struct state_table *
cp_gtk_init_state_table (JNIEnv * env, jclass clazz)
{
  return cp_gtk_init_state_table_with_size (env, clazz, DEFAULT_TABLE_SIZE);
}

static void *
remove_node (struct state_node **head, jint obj_id)
{
  struct state_node *back_ptr = NULL;
  struct state_node *node = *head;

  while (node != NULL)
    {
      if (node->key == obj_id)
	{
	  void *return_value;
	  if (back_ptr == NULL)
	    *head = node->next;
	  else
	    back_ptr->next = node->next;
	  return_value = node->c_state;
	  free (node);
	  return return_value;
	}
      back_ptr = node;
      node = node->next;
    }

  return NULL;
}

static void *
get_node (struct state_node **head, jint obj_id)
{
  struct state_node *back_ptr = NULL;
  struct state_node *node = *head;

  while (node != NULL)
    {
      if (node->key == obj_id)
	{
	  /* Move the node we found to the front of the list.  */
	  if (back_ptr != NULL)
	    {
	      back_ptr->next = node->next;
	      node->next = *head;
	      *head = node;
	    }

	  /* Return the match.  */
	  return node->c_state;
	}

      back_ptr = node;
      node = node->next;
    }

  return NULL;
}

static void
add_node (struct state_node **head, jint obj_id, void *state)
{
  struct state_node *node = *head;
  struct state_node *back_ptr = NULL;

  struct state_node *new_node;

  if (node != NULL)
    {
      while (node->next != NULL && obj_id != node->key)
	{
	  back_ptr = node;
	  node = node->next;
	}

      if (node->key == obj_id)
	{
	  /* If we're updating a node, move it to the front of the
	     list.  */
	  if (back_ptr != NULL)
	    {
	      back_ptr->next = node->next;
	      node->next = *head;
	      *head = node;
	    }
	  node->c_state = state;
	  return;
	}
    }

  new_node = (struct state_node *) malloc (sizeof (struct state_node));
  new_node->key = obj_id;
  new_node->c_state = state;
  new_node->next = *head;
  *head = new_node;
}

#ifndef NDEBUG
static void
cp_gtk_check_compat (JNIEnv * env, jobject obj, struct state_table *table)
{
  jclass objclazz;

  objclazz = (*env)->GetObjectClass(env, obj);
  assert ((*env)->IsAssignableFrom(env, objclazz, table->clazz));
  (*env)->DeleteLocalRef(env, objclazz);
}
#endif

void
cp_gtk_set_state_oid (JNIEnv * env, jobject lock, struct state_table *table,
	       jint obj_id, void *state)
{
  jint hash;

  hash = obj_id % table->size;

  (*env)->MonitorEnter (env, lock);
  add_node (&table->head[hash], obj_id, state);
  (*env)->MonitorExit (env, lock);
}

void *
cp_gtk_get_state_oid (JNIEnv * env, jobject lock, struct state_table *table,
	       jint obj_id)
{
  jint hash;
  void *return_value;

  hash = obj_id % table->size;

  (*env)->MonitorEnter (env, lock);
  return_value = get_node (&table->head[hash], obj_id);
  (*env)->MonitorExit (env, lock);

  return return_value;
}

void *
cp_gtk_remove_state_oid (JNIEnv * env, jobject lock, struct state_table *table,
		  jint obj_id)
{
  jint hash;
  void *return_value;

  hash = obj_id % table->size;

  (*env)->MonitorEnter (env, lock);
  return_value = remove_node (&table->head[hash], obj_id);
  (*env)->MonitorExit (env, lock);

  return return_value;
}

int
cp_gtk_set_state (JNIEnv * env, jobject obj, struct state_table *table, void *state)
{
  jint obj_id;

#ifndef NDEBUG
  cp_gtk_check_compat(env, obj, table);
#endif

  obj_id = (*env)->GetIntField (env, obj, table->hash);

  if ((*env)->ExceptionOccurred (env) != NULL)
    return -1;

  cp_gtk_set_state_oid (env, table->clazz, table, obj_id, state);
  return 0;
}

void *
cp_gtk_get_state (JNIEnv * env, jobject obj, struct state_table *table)
{
  jint obj_id;

#ifndef NDEBUG
  cp_gtk_check_compat(env, obj, table);
#endif

  obj_id = (*env)->GetIntField (env, obj, table->hash);

  if ((*env)->ExceptionOccurred (env) != NULL)
    return NULL;

  return cp_gtk_get_state_oid (env, table->clazz, table, obj_id);
}

void *
cp_gtk_remove_state_slot (JNIEnv * env, jobject obj, struct state_table *table)
{
  jint obj_id;

#ifndef NDEBUG
  cp_gtk_check_compat(env, obj, table);
#endif

  obj_id = (*env)->GetIntField (env, obj, table->hash);

  if ((*env)->ExceptionOccurred (env) != NULL)
    return NULL;

  return cp_gtk_remove_state_oid (env, table->clazz, table, obj_id);
}
