/*
    zghash.c - extension for GHashTable
    Copyright (C) 2002-2021 Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/

#include <glib.h>
#include <zgptrarray.h>
#include <zdebug.h>

void zg_hash_safe_insert(GHashTable *table, char *key, char *value){
    gpointer orig_key;
    gpointer orig_value;

    if (g_hash_table_lookup_extended(table, (gpointer) key, &orig_key, &orig_value)) {
        g_hash_table_remove(table, orig_key);
        g_free(orig_key);
        g_free(orig_value);
    }
    g_hash_table_insert(table, key, value);
}

gboolean zg_hash_free_item(gpointer key, gpointer value, gpointer user_data){
    if (key)       g_free(key);
    if (value)     g_free(value);
    if (user_data) g_free(user_data);  // sakra fakt? Neni to argument predavany pri ruseni?

    return TRUE;
}

gboolean zg_hash_free_key(gpointer key, gpointer value, gpointer user_data){
	if (key) {
        //dbg("zg_hash_free_key(%p)\n", key);
        g_free(key);
    }
    return TRUE;
}

void zg_hash_free(GHashTable *hash){
    if (!hash) return;
    g_hash_table_foreach_remove(hash, zg_hash_free_item, NULL);
    g_hash_table_destroy(hash);
}


static void zg_hash_get_keys(gpointer key, gpointer value, gpointer user_data){
    GPtrArray *arr = (GPtrArray*)user_data;
    g_ptr_array_add(arr, key);
}

void zg_hash_table_foreach_sorted(GHashTable *hash, 
        GHFunc func, 
        int (*compar)(const void *, const void *), 
        gpointer user_data){

     unsigned int i;
     GPtrArray *keys = g_ptr_array_new();
     g_hash_table_foreach(hash, zg_hash_get_keys, keys);
     zg_ptr_array_qsort(keys, compar);
     for (i = 0; i < keys->len; i++){ 
         gpointer key = g_ptr_array_index(keys, i);
         func(key, g_hash_table_lookup(hash, key), user_data);
     }

     g_ptr_array_free(keys, FALSE);
}

