#include <stdio.h>
#include <iconv.h>
#include <stdlib.h>
#include <string.h>
#include <IMProtocolStruct.h>
#include <assert.h>
#include "symbol.h"

static int g_symbol_table_size = 0;
static SymbolGroup *special_symbols = NULL;

static void
composer_symbol_table_init ()
{
  int i;
  if (special_symbols)
    return;
  
  g_symbol_table_size =
    sizeof (symbol_group_names) / sizeof (symbol_group_names[0]);
  special_symbols =
    (SymbolGroup *) calloc (g_symbol_table_size, sizeof (SymbolGroup));
  
  for (i = 0 ; i < g_symbol_table_size; i++){
    special_symbols[i].symbol_key = symbol_group_names[i];
    special_symbols[i].symbol_string = special[i];
  }
}


Boolean
composer_symbol_menu_lookup_start (int *number_of_candidates,
				   UTFCHAR ***symbol_list_return)
{
  iconv_t cd;
  size_t iconv_return;
  /* not used
  char inbuffer[1024];
  */
  char outbuffer[1024];
  char *inptr, *outptr;
  size_t inlen, outlen;
  int i;

  assert (number_of_candidates != NULL);
  assert (symbol_list_return != NULL);

  if (!g_symbol_table_size)
    composer_symbol_table_init ();

  *number_of_candidates = g_symbol_table_size;
  *symbol_list_return = 
    (UTFCHAR **) calloc (*number_of_candidates, sizeof (UTFCHAR *));


  cd = iconv_open ("UTF16", "UTF-8");
  if (cd == (iconv_t) -1){
    fprintf (stderr, "composer_symbol_menu_lookup_start: Iconv open failed\n");
    return False;
  }
  /*
    BEGIN: dummy conversion to flush BOM for the first time
  */
  
  inptr = special_symbols[0].symbol_key, outptr = outbuffer;
  inlen = strlen (special_symbols[0].symbol_key), outlen = sizeof (outbuffer);
  
  iconv (cd, &inptr, &inlen, &outptr, &outlen);
  /*
    END: dummy conversion to flush BOM for the first time
  */
  
  for (i = 0 ; i < g_symbol_table_size; i++){
    inptr = special_symbols[i].symbol_key;
    outptr = outbuffer;
    inlen = strlen (special_symbols[i].symbol_key);
    outlen = sizeof (outbuffer);
    
    iconv_return = iconv (cd, &inptr, &inlen, &outptr, &outlen);

    if (iconv_return == (size_t) -1){
      continue;
    }
    
    (*symbol_list_return)[i] =
      (UTFCHAR *) calloc (sizeof (outbuffer) - outlen + 2, 1);
    
    memcpy ((*symbol_list_return)[i],
	    outbuffer, sizeof (outbuffer) - outlen);
  }
  iconv_close (cd);
  return True;
}

Boolean
composer_symbol_detail_lookup_start (int n_group_id,
				     int *number_of_candidates,
				     UTFCHAR ***symbol_list_return)
{
  iconv_t cd;
  size_t iconv_return;
  /* not used
  char inbuffer[1024];
  */
  char outbuffer[1024];
  char *inptr, *outptr;
  size_t inlen, outlen;
  int i;

  char *ptr;

  assert (number_of_candidates != NULL);
  assert (symbol_list_return != NULL);
  assert ((n_group_id >= 0) && (n_group_id < g_symbol_table_size) );

  if (!g_symbol_table_size)
    composer_symbol_table_init ();

  if (n_group_id < 0 || n_group_id >= g_symbol_table_size)
    return False;

  cd = iconv_open ("UTF16", "UTF-8");
  if (cd == (iconv_t) -1){
    fprintf (stderr, "composer_symbol_menu_lookup_start: Iconv open failed\n");
    return False;
  }
  /*
    BEGIN: dummy conversion to flush BOM for the first time
  */
  
  inptr = special_symbols[0].symbol_key;
  outptr = outbuffer;
  inlen = strlen (special_symbols[0].symbol_key), outlen = sizeof (outbuffer);
  
  iconv (cd, &inptr, &inlen, &outptr, &outlen);
  
  /*
    END: dummy conversion to flush BOM for the first time
  */

  memset (outbuffer, 0, sizeof (outbuffer));
  
  inptr = special_symbols[n_group_id].symbol_string;
  outptr = outbuffer;
  inlen = strlen (special_symbols[n_group_id].symbol_string);
  outlen = sizeof (outbuffer);
  
  iconv_return = iconv (cd, &inptr, &inlen, &outptr, &outlen);
  if (iconv_return == (size_t) -1){
    /* if iconv fails, then I need to do some clean up
       before returns ...*/
    fprintf (stderr, "composer_symbol_detail_lookup_start : "
	     "iconv failed\n");
    return False;
  }
  iconv_close (cd);
  
  *number_of_candidates = (sizeof (outbuffer) - outlen) / 2;
  *symbol_list_return =
    (UTFCHAR **) calloc (*number_of_candidates, sizeof (UTFCHAR *));
  
  for (i = 0, ptr = outbuffer
	 ; i < *number_of_candidates ; i++, ptr += 2){
    (*symbol_list_return)[i] = (UTFCHAR *) calloc (2, sizeof (UTFCHAR));
    memcpy ((*symbol_list_return)[i], ptr, sizeof (UTFCHAR));
  }


  return True;
}

#ifdef TEST_RUN
void
_utfchar_print (UTFCHAR *utf_string)
{
  int len;
  char from_buffer[100], to_buffer[100];
  int  from_i = 0, to_i = 0;
  char *f_ptr, *t_ptr;
  iconv_t cd;
  size_t ret;

  len = _utfchar_length (utf_string);
  
  memset (from_buffer, 0, 100); memset (to_buffer, 0, 100);
  memcpy (from_buffer, utf_string, sizeof (UTFCHAR) * (len + 1));
  
  f_ptr = from_buffer, t_ptr = to_buffer;
  from_i = len * sizeof (UTFCHAR) , to_i = 100;
  
  cd = iconv_open ("EUC-KR", "UTF16");
  if (cd == (iconv_t) -1) {
    fprintf (stderr, "iconv_open error, returning..\n");
    return;
  }
  ret = iconv (cd, &f_ptr, &from_i, &t_ptr, &to_i);
  if (ret == (size_t) -1){
    fprintf (stderr, "iconv error, returning...\n");
    return;
  }
  fprintf (stdout, "%s", to_buffer);
  iconv_close (cd);
  return;
}
int
_utfchar_length(UTFCHAR * p)
{
      int i;
		assert (p != NULL);
		if (p == NULL)
			return 0;
      for (i = 0; *p; i++)
         p++;
      return i;
}

int
main (int argc, char **argv)
{
  UTFCHAR **symbol_list_return;
  int number_of_candidates;
  Bool mthd_return;
  int i;
  
  mthd_return = composer_symbol_menu_lookup_start (&number_of_candidates,
						   &symbol_list_return);
  for (i = 0 ; i < number_of_candidates; i++){
    _utfchar_print (symbol_list_return [i]);
    printf ("\n");
  }

  return 0;
}
#endif
