/*
 * Copyright 2003 Sun Microsystems Inc.
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Authors: Karl Park <karl.park@sun.com>
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <le-options.h>
#include "configapi.h"
#include "kolelog.h"

static KOLE_config *leoption_make_deletion_option (const char *sdel);
static KOLE_config *leoption_make_charset_option (const char *cset);
static KOLE_config *leoption_make_keyboard_option (const char *kbd);
static KOLE_config *leoption_make_commit_option (const char *scommitby);
KOLE_config *
leoption_make_option (KOLE_option_type type)
{
  KOLE_config *leconf;
  leconf = (KOLE_config *) malloc (sizeof (KOLE_config));
  if (!leconf)
    return NULL;

  leconf->type = type;

  return leconf;
}

KOLE_config *
leoption_make_option_with_string_value (const char *sopt,
					const char *vstr)

{
  KOLE_config *pconf;
  assert (vstr != NULL);
#if 0
  fprintf (stderr,"option : %s, value :%s\n", sopt, vstr);
#endif
  
  if (!vstr){
    KOLE_LOG (LOGDEST_STDERR,
	     "leoption_make_option_with_value: vstr is NULL");
    return NULL;
  }

  if (!strcmp (sopt, STR_OPTION_CHARSET)){
    
    pconf =
      leoption_make_option_with_value (KOLE_OPTION_TYPE_CHARSET, vstr);
    
  } else if (!strcmp (sopt, STR_OPTION_DELETION)){
    
    pconf =
      leoption_make_option_with_value (KOLE_OPTION_TYPE_DELETION, vstr);
    
  } else if (!strcmp (sopt, STR_OPTION_KEYBOARD)){
    pconf =
      leoption_make_option_with_value (KOLE_OPTION_TYPE_KEYBOARD, vstr);
    
  } else if (!strcmp (sopt, STR_OPTION_COMMITMODE)){
    
    pconf =
      leoption_make_option_with_value (KOLE_OPTION_TYPE_COUNT, vstr);
    
  } else {
    pconf = NULL;
  }
  if (!pconf){
    KOLE_LOG (LOGDEST_STDERR,
	     "leoption_make_option_with_string_value error");
    return NULL;
  }
  return pconf;
}

KOLE_config *
leoption_make_option_with_value (KOLE_option_type type,
				 const char *vstr)

{
  KOLE_config *pconf;
  assert (vstr != NULL);
  
  if (!vstr){
    KOLE_LOG (LOGDEST_STDERR,
	     "leoption_make_option_with_value: vstr is NULL");
    return NULL;
  }
  
  switch (type){
  case KOLE_OPTION_TYPE_KEYBOARD:
    pconf = leoption_make_keyboard_option (vstr);
    if (!pconf){
      KOLE_LOG (LOGDEST_STDERR,
	       "leoption_make_option_with_value error");
      return NULL;
    } else
      return pconf;
    break;
    
  case  KOLE_OPTION_TYPE_CHARSET:
    pconf = leoption_make_charset_option (vstr);
    if (!pconf){
      KOLE_LOG (LOGDEST_STDERR,
	       "leoption_make_option_with_value error\n");
      return NULL;
    } else
      return pconf;
    break;
    
  case KOLE_OPTION_TYPE_DELETION:
    pconf = leoption_make_deletion_option (vstr);
    if (!pconf){
      fprintf (stderr,
	       "leoption_make_deletion_option error\n");
      return NULL;
    } else
      return pconf;
    break;
  case KOLE_OPTION_TYPE_CHARBASED_COMMIT:
    pconf = leoption_make_commit_option (vstr);
    if (!pconf){
      fprintf (stderr,
	       "leoption_make_deletion_option error\n");
      return NULL;
    } else
      return pconf;
    
  default:
    fprintf (stderr,
	     "leoption_make_option_with_value error\n");
    return NULL;
    break;
  }

}

KOLE_config *
leoption_copy (KOLE_config *option)
{
  KOLE_config *opt;
  
  assert (option != NULL);
  if (!option){
    fprintf (stderr, "leoption_copy failed: parameter is NULL\n");
    return NULL;
  }
  
  opt = (KOLE_config *) malloc (sizeof (KOLE_config));
  
  if (!opt){
    fprintf (stderr, "leoption_copy failed: memory alloc error\n");
    return NULL;
  }

  memcpy (opt, option, sizeof (KOLE_config));
  return opt;
}

void
leoption_delete (KOLE_config *option)
{
  if (!option)
    return;
  if (option->vstr)
    free (option->vstr);

  free (option);
}

static KOLE_config *
leoption_make_charset_option (const char *cset)
{
  KOLE_config *pconf;
  assert (cset != NULL);

  if (!cset)
    return NULL;
  
  pconf = leoption_make_option (KOLE_OPTION_TYPE_CHARSET);
  
  pconf->vstr = (char *) strdup (cset);
  
  if (!strcmp (cset, STR_CHARSET_EUC))
    {
      pconf->v.cset = IN_EUC;
    }
  else if (!strcmp (cset, STR_CHARSET_UNICODE))
    {
      pconf->v.cset = IN_UNICODE;
    }
  else
    {
      pconf->v.cset = IN_UNICODE;
    }
  return pconf;
}

static KOLE_config *
leoption_make_keyboard_option (const char *kbd)
{
  KOLE_config *pconf;
  assert (kbd != NULL);

  if (!kbd)
    return NULL;
  
  pconf = leoption_make_option (KOLE_OPTION_TYPE_KEYBOARD);
  pconf->vstr = (char *) strdup (kbd);
  
  if (!strcmp (kbd, STR_KEYBOARD_LAYOUT_2PAIR))
    {
      pconf->v.kbd = LAYOUT_2PART;
    }
  else if (!strcmp (kbd, STR_KEYBOARD_LAYOUT_3PAIRFINAL))
    {
      pconf->v.kbd = LAYOUT_3PART_FINAL;
    }
  else if (!strcmp (kbd, STR_KEYBOARD_LAYOUT_3PAIR390))
    {
      pconf->v.kbd = LAYOUT_3PART390;
    }
  else
    {
      pconf->v.kbd = LAYOUT_2PART;
    }
  return pconf;
  
}

static KOLE_config *
leoption_make_deletion_option (const char *sdel)
{
  KOLE_config *pconf;
  
  assert (sdel != NULL);
  if (!sdel)
    return NULL;
  
  pconf = leoption_make_option (KOLE_OPTION_TYPE_DELETION);
  pconf->vstr = (char *) strdup (sdel);
  
  if (!strcmp (sdel, STR_DELETION_BY_JASO_NO))
    {
      pconf->v.del = BY_JASO;
    }
  else if (!strcmp (sdel, STR_DELETION_BY_JASO_YES))
    {
      pconf->v.del = BY_CHAR;
    }
  else
    {
      pconf->v.del = BY_CHAR;
    }
  return pconf;
}

static KOLE_config *
leoption_make_commit_option (const char *scommitby)
{
  KOLE_config *pconf;
  
  assert (scommitby != NULL);
  if (!scommitby)
    return NULL;
  pconf = leoption_make_option (KOLE_OPTION_TYPE_CHARBASED_COMMIT);
  
  pconf->vstr = (char *) strdup (scommitby);
  
  if (!strcmp (scommitby, STR_COMMITMODE_BY_CHAR))
    {
      pconf->v.commit_by = COMMIT_BY_CHAR;
    }
  else if (!strcmp (scommitby, STR_COMMITMODE_BY_HOTKEY))
    {
      pconf->v.commit_by = COMMIT_BY_HOTKEY;
    }
  else
    {
      pconf->v.commit_by = COMMIT_BY_HOTKEY;
    }
  return pconf;
}

void
leoption_debug_print (KOLE_config *p)
{
  switch (p->type)
    {
    case KOLE_OPTION_TYPE_KEYBOARD:
      KOLE_LOG (LOGDEST_STDOUT,
		"%s : %d(%s)",
		STR_OPTION_KEYBOARD,
		p->v.kbd,
		p->v.kbd == LAYOUT_2PART ?  STR_KEYBOARD_LAYOUT_2PAIR :
		(p->v.kbd == LAYOUT_3PART390 ? STR_KEYBOARD_LAYOUT_3PAIR390 :
		 STR_KEYBOARD_LAYOUT_3PAIRFINAL));
      break;
      
    case KOLE_OPTION_TYPE_CHARSET:
      KOLE_LOG (LOGDEST_STDOUT,
		"%s : %d(%s)",
		STR_OPTION_CHARSET,
		p->v.cset,
		p->v.cset == IN_EUC ?  STR_CHARSET_EUC :  STR_CHARSET_UNICODE);
      break;
    case KOLE_OPTION_TYPE_DELETION:
      KOLE_LOG (LOGDEST_STDOUT,
		"%s : %d(%s)",
		STR_OPTION_DELETION,
		p->v.del,
		p->v.del == BY_CHAR ?
		STR_DELETION_BY_JASO_YES :  STR_DELETION_BY_JASO_NO
		);
      break;
    case KOLE_OPTION_TYPE_CHARBASED_COMMIT:
      KOLE_LOG (LOGDEST_STDOUT,
		"%s : %d(%s)",
		STR_OPTION_COMMITMODE,
		p->v.commit_by,
		p->v.commit_by == COMMIT_BY_CHAR ?
		STR_COMMITMODE_BY_CHAR :  STR_COMMITMODE_BY_HOTKEY
		);      
      break;
    default:
      break;
    }
}
