/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2022  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 "header.h"
#include "bfu.h"
#include "fifo.h"
#include "main.h"
#include "namedb.h"
#include "tsdl.h"

struct namedb *namedb;

struct namedb *init_namedb(){
    struct namedb *namedb;

	progress(VTEXT(T_INIT_NAMEDB));		

    namedb = g_new0(struct namedb, 1);
    namedb->names = g_hash_table_new(g_str_hash, g_str_equal);
    return namedb;
}

gboolean free_names_item(gpointer key, gpointer value, gpointer user_data){
    
    g_free(key);
    g_free(value);
    return TRUE;    
}

void free_namedb(struct namedb *namedb){
	progress(VTEXT(T_FREE_NAMEDB));		

    g_hash_table_foreach_remove(namedb->names, free_names_item, NULL);
    g_hash_table_destroy(namedb->names);
    g_free(namedb);
}

gint get_namedb_size(struct namedb *namedb){
    return g_hash_table_size(namedb->names);
}

#define NAMEDB_DELIM " \t\r\n"

void load_one_namedb(struct namedb *namedb, gchar *s){
    gchar *call, *name;
    char *token_ptr;
    
    call = strtok_r(s, NAMEDB_DELIM, &token_ptr);
    if (!call) return;

    name = strtok_r(NULL, NAMEDB_DELIM, &token_ptr);
    if (!name) return;

    if (strlen(call)==0 || strlen(name)==0) return;
    
    add_namedb(namedb, call, name);
}

int load_namedb_from_file(struct namedb *namedb, gchar *filename){
    FILE *f;
    char s[102];

    /*dbg("load_namedb_from_file(%s)\n", filename);*/
    
    f = fopen(filename, "rt");
    if (!f){
        /*dbg("Can't open '%s'\n", filename);*/
        return -1;
    }

    while((fgets(s, 100, f))!=NULL){
        load_one_namedb(namedb,s);
    }

    fclose(f);
    return 0;
}

int load_namedb_from_mem(struct namedb *namedb, const char *file, size_t len){
    GString *gs; 
	long int pos;
    
    gs = g_string_sized_new(100);
    
    pos=0;
    while(1){
        if (!zfile_mgets(gs, file, &pos, len, 1)) break;
		load_one_namedb(namedb, gs->str);
    }
    g_string_free(gs, 1);
    return 0;

}


void read_namedb_files(struct namedb *namedb){
    gchar *s;
	int ret = 0;

	progress(VTEXT(T_LOAD_NAMEDB2));		

/*#ifdef UNIX
    ret |= load_namedb_from_file(namedb, SHAREDIR"/tucnaknames");
#endif*/
    s = g_strconcat(tucnak_dir, "/tucnaknames", NULL); 
	z_wokna(s);
    ret |= load_namedb_from_file(namedb, s);
	if (ret) load_namedb_from_mem(namedb, txt_tucnaknames, sizeof(txt_tucnaknames));
    g_free(s);
	namedb->dirty = 0;
}

int namedb_ret;

void save_one_name(gpointer key, gpointer value, gpointer user_data){
    FILE *f;
    gchar *call, *name;
    int ret;

    f   = (FILE *) user_data;
    call = (gchar *) key;
    name = (gchar *) value;

    ret=fprintf(f, "%s %s\n", call, name);
    if (ret<=0) namedb_ret++;
}

int save_namedb_into_file(struct namedb *namedb, gchar *filename){
    FILE *f;

    f = fopen(filename, "wt"); 
    if (!f) {
        return errno;
    }
    namedb_ret=0;
    g_hash_table_foreach(namedb->names, save_one_name, (gpointer) f);
    fclose(f);
	namedb->dirty = 0;
    return namedb_ret;
}

int save_namedb(struct namedb *namedb, int verbose){
	char *s;
	int ret;
	
	if (!namedb->dirty) return 0;

	s = g_strconcat(tucnak_dir, "/tucnaknames", NULL);
	z_wokna(s);
    ret=save_namedb_into_file(namedb, s);        
    if (ret){
        errbox(VTEXT(T_CANT_WRITE), ret);
    }else{
        if (verbose) log_addf(VTEXT(T_SAVED_S), s);
    }
    g_free(s);
	return ret;
}


static void format_one_name(gpointer key, gpointer value, gpointer user_data){
    GString *gs;
    gchar *call, *name;

    gs   = (GString *) user_data;
    call = (gchar *) key;
    name = (gchar *) value;

    g_string_append_printf(gs, "%s %s;", call, name);
}

int format_namedb_string(struct namedb *namedb, GString *gs){
    g_hash_table_foreach(namedb->names, format_one_name, (gpointer) gs);
	return 0;
}

void add_namedb(struct namedb *namedb, gchar *call, gchar *name){
    gchar *namedbi;
    
    /*dbg("add %s=%s\n", call, name);*/
    namedbi = (char *)g_hash_table_lookup(namedb->names, call);
    
    if (!namedbi){
        g_hash_table_insert(namedb->names, g_strdup(call), g_strdup(name));
		namedb->dirty = 1;
    }
}


gchar *find_name_by_call(struct namedb *namedb, gchar *call){
    gchar *namedbi;
    char rawcall[120];

    z_get_raw_call(rawcall, call);
    
    namedbi = (gchar *) g_hash_table_lookup(namedb->names, rawcall);
    if (!namedbi) return NULL;
    
    return namedbi;
}

