/*-
 * $Id: rr-profileregistry.c,v 1.8 2002/10/06 18:17:03 jonas Exp $
 *
 * See the file LICENSE for redistribution information. 
 * If you have not received a copy of the license, please contact CodeFactory
 * by email at info@codefactory.se, or on the web at http://www.codefactory.se/
 * You may also write to: CodeFactory AB, SE-903 47, Umeå, Sweden.
 *
 * Copyright (c) 2002 Jonas Borgström <jonas@codefactory.se>
 * Copyright (c) 2002 Daniel Lundin   <daniel@codefactory.se>
 * Copyright (c) 2002 CodeFactory AB.  All rights reserved.
 */

#include <librr/rr.h>

static GObjectClass *parent_class = NULL;

static void finalize (GObject *object);

static void
rr_profile_registry_init (GObject *object)
{
	RRProfileRegistry *profreg = (RRProfileRegistry *)object;
	
	g_static_rw_lock_init (&(profreg->rwlock));
	profreg->profiles_by_uri = g_hash_table_new_full (g_str_hash, 
							  g_str_equal,
							  g_free,
							  NULL);
	profreg->config_by_type = g_hash_table_new_full (g_direct_hash, 
							 g_direct_equal,
							 NULL,
							 NULL);
}

static void
rr_profile_registry_class_init (GObjectClass *klass)
{
	klass->finalize = finalize;

	parent_class = g_type_class_peek_parent (klass);
}

GType 
rr_profile_registry_get_type (void)
{
	static GType rr_type = 0;

	if (!rr_type) {
		static GTypeInfo type_info = {
			sizeof (RRProfileRegistryClass),
			NULL,
			NULL,
			(GClassInitFunc) rr_profile_registry_class_init,
			NULL,
			NULL,
			sizeof (RRProfileRegistry),
			16,
			(GInstanceInitFunc) rr_profile_registry_init
		};
		rr_type = g_type_register_static (G_TYPE_OBJECT, 
						  "RRProfileRegistry", 
						  &type_info, 
						  0);
	}
	return rr_type;
}

static void
finalize (GObject *object)
{
	RRProfileRegistry *profreg = (RRProfileRegistry *)object;

	g_static_rw_lock_writer_lock (&(profreg->rwlock));
	g_static_rw_lock_writer_unlock (&(profreg->rwlock));
	g_hash_table_destroy (profreg->profiles_by_uri);
	g_hash_table_destroy (profreg->config_by_type);
	g_static_rw_lock_free (&(profreg->rwlock));

	parent_class->finalize (object);
}


gboolean
rr_profile_registry_add_profile (RRProfileRegistry *profreg, GType type,
				 gpointer global_config)
{
	gchar *uri;

	g_return_val_if_fail (g_type_is_a (type, RR_TYPE_CHANNEL),
			      FALSE);
	g_return_val_if_fail (profreg->profiles_by_uri, FALSE);
	g_return_val_if_fail (RR_IS_PROFILE_REGISTRY (profreg), FALSE);

	g_static_rw_lock_writer_lock (&(profreg->rwlock));

	uri = g_type_get_qdata (type, 
				g_quark_from_string (RR_CHANNEL_GTYPE_KEY_URI));
	if (NULL == uri) {
		g_printerr ("Profile URI not found in type qdata\n");
		g_static_rw_lock_writer_unlock (&(profreg->rwlock));
		return FALSE;
	}
	g_hash_table_insert (profreg->profiles_by_uri, g_strdup (uri), 
			     GUINT_TO_POINTER (type));

	g_hash_table_insert (profreg->config_by_type, GUINT_TO_POINTER (type), 
			     global_config);

	g_static_rw_lock_writer_unlock (&(profreg->rwlock));
	
	return TRUE;
}


gboolean
rr_profile_registry_remove_profile (RRProfileRegistry *profreg, 
				    GType type)
{
	gchar *uri;
	g_return_val_if_fail (g_type_is_a (type, RR_TYPE_CHANNEL),
			      FALSE);
	g_return_val_if_fail (profreg->profiles_by_uri, FALSE);
	g_return_val_if_fail (RR_IS_PROFILE_REGISTRY (profreg), FALSE);
	
	g_static_rw_lock_writer_lock (&(profreg->rwlock));

	uri = g_type_get_qdata (type, 
				g_quark_from_string (RR_CHANNEL_GTYPE_KEY_URI));
	if (NULL == uri) {
		g_printerr ("Profile URI not found in type qdata\n");
		g_static_rw_lock_writer_unlock (&(profreg->rwlock));
		return FALSE;
	}
	g_hash_table_remove (profreg->profiles_by_uri, uri);

	g_static_rw_lock_writer_unlock (&(profreg->rwlock));

	return TRUE;
}

gpointer
rr_profile_registry_get_global_config (RRProfileRegistry *profreg, GType type)
{
	gpointer data;

	g_return_val_if_fail (RR_IS_PROFILE_REGISTRY (profreg), G_TYPE_INVALID);
	g_return_val_if_fail (g_type_is_a (type, RR_TYPE_CHANNEL),
			      NULL);

 	g_static_rw_lock_reader_lock (&(profreg->rwlock));
	
	data = g_hash_table_lookup (profreg->config_by_type, 
				    GUINT_TO_POINTER (type));

	g_static_rw_lock_reader_unlock (&(profreg->rwlock));

	return data;
}

GType
rr_profile_registry_lookup_by_uri (RRProfileRegistry *profreg,
				const gchar *uri)
{
	GType type;

	g_return_val_if_fail (RR_IS_PROFILE_REGISTRY (profreg), G_TYPE_INVALID);
	g_return_val_if_fail (profreg->profiles_by_uri, G_TYPE_INVALID);
	g_return_val_if_fail (uri, G_TYPE_INVALID);

 	g_static_rw_lock_reader_lock (&(profreg->rwlock));
	
	type = GPOINTER_TO_UINT (g_hash_table_lookup (profreg->profiles_by_uri, 
uri));

	g_static_rw_lock_reader_unlock (&(profreg->rwlock));

	return type;
}


static void
hash_pair_dup (gpointer key, gpointer value, gpointer user_data)
{
	GHashTable *newhash = (GHashTable *)user_data;
	
	g_hash_table_insert (newhash, g_strdup (key), value);
}

          
RRProfileRegistry *
rr_profile_registry_dup (RRProfileRegistry *profreg)
{
	RRProfileRegistry *newprofreg;
	g_return_val_if_fail (RR_IS_PROFILE_REGISTRY (profreg), NULL);

	newprofreg = g_object_new (RR_TYPE_PROFILE_REGISTRY, NULL);

 	g_static_rw_lock_reader_lock (&(profreg->rwlock));

	/* Copy the hash, duplicating the string keys */
	g_hash_table_foreach (profreg->profiles_by_uri,
			      hash_pair_dup, newprofreg->profiles_by_uri);

 	g_static_rw_lock_reader_unlock (&(profreg->rwlock));

	return newprofreg;
}

RRProfileRegistry *
rr_profile_registry_new (void)
{
	return g_object_new (RR_TYPE_PROFILE_REGISTRY, NULL);
}


syntax highlighted by Code2HTML, v. 0.9.1