#include <stdlib.h>
#include <string.h>
#include <iconv.h>
#include <stdio.h>

#include "lkarma.h"

struct utf8{
    iconv_t in;
    iconv_t out;
    char * charset;
};

static struct utf8 utf={(iconv_t)-1, (iconv_t)-1, NULL};

void utf8_destroy(void)
{
    free(utf.charset);
    iconv_close(utf.in);
    iconv_close(utf.out);
    utf.in=utf.out=(iconv_t)-1;
}

int utf8_set_codeset(char * codeset)
{
    if(utf.in != (iconv_t)(-1)) {
        iconv_close(utf.in);
        utf.in  = (iconv_t)(-1);
    }
    if(utf.out != (iconv_t)(-1)) {
        iconv_close(utf.out);
        utf.out = (iconv_t)(-1);
    }
    
    if(utf.charset) 
        free(utf.charset);
    utf.charset=strdup(codeset);
    utf.in=iconv_open("UTF-8", codeset);
    utf.out=iconv_open(codeset, "UTF-8");
    if ((utf.in  == (iconv_t)-1) || (utf.out == (iconv_t)-1)) {
        lk_errors_set(E_ICONVO);
        free(utf.charset);
        return -1;
    }
    return 0;
}

char * utf8_get_codeset(void)
{
    return utf.charset;
}

char * utf8_from_codeset(char * data)
{
    char *ivalue, *auxdata, *auxvalue;
    size_t insz, outsz, nconv;

    if (data == NULL) return NULL;

    auxdata = data;
    insz = strlen(auxdata);
    outsz = 2 * insz;
    ivalue = (char *)malloc(outsz+1);
    ivalue[0] = '\0';
    auxvalue = ivalue;
    nconv = iconv(utf.in, &auxdata, &insz, &auxvalue, &outsz);
    auxdata = data;  /* *auxdata has been modified by iconv ... */
    if (nconv == (size_t)-1) {
        lk_errors_set(E_ICONV);
        ivalue=strdup(data);
    }
    else auxvalue[0] = '\0';
    ivalue = realloc(ivalue, strlen(ivalue)+1);

    return ivalue;
}

char * utf8_to_codeset(char * data)
{
    char *ivalue, *auxdata, *auxvalue;
    size_t insz, outsz, nconv;

    if (data == NULL) return NULL;

    auxdata=data;
    insz = strlen(auxdata);
    outsz = 2 * insz;
    ivalue = (char *)malloc(outsz+1);
    ivalue[0] = '\0';
    auxvalue = ivalue;
    nconv = iconv(utf.out, &auxdata, &insz, &auxvalue, &outsz);
    auxdata = data;  /* *auxdata has been modified by iconv ... */
    if (nconv == (size_t)-1) {
        lk_errors_set(E_ICONV);
        ivalue=strdup(data);
    }
    else auxvalue[0] = '\0';
    ivalue = realloc(ivalue, strlen(ivalue)+1);

    return ivalue;
}
