#include <config.h>
#include <stdlib.h>
#include "IIIMPUtil.hh"

IIIMP_string*
convert_IMText_to_iiimp_string(
    IIIMP_data_s *data_s,
    IMText *pimtext
)
{
    return iiimp_string_new(data_s,
			    pimtext->char_length,
			    pimtext->text.utf_chars);
}

IIIMP_text*
convert_IMText_to_iiimp_text(
    IIIMP_data_s *data_s,
    IMText *pimtext
)
{
    int i, j;
    IIIMP_text *ptext;
    IIIMP_char_with_feedback *phead;

    if (!pimtext) {
	phead = NULL;
    } else {
	// convert IIIMP feedback.

	const int IIIMP_FEEDBACK_MAX_SLOTS = 32;
	IIIMP_feedback_attr fbattrtmp[IIIMP_FEEDBACK_MAX_SLOTS];
	IIIMP_char_with_feedback *pcur, *pcur2;
	IIIMP_feedback_attr_list *pattr;
	IMFeedbackList *pfbl;
	IMFeedback *pfb;
	UTFCHAR *pu;

	phead = pcur = NULL;
	for (i = 0, pu= pimtext->text.utf_chars, pfbl = pimtext->feedback;
	     i < pimtext->char_length;
	     i++, pu++, pfbl++) {
	    if (pfbl->count_feedbacks > (sizeof(fbattrtmp) / sizeof(fbattrtmp[0]))) {
		goto error;
	    }
	    for (j = 0, pfb = pfbl->feedbacks;
		 j < pfbl->count_feedbacks;
		 j++, pfb++) {
		fbattrtmp[j].nbyte = 8; // !!!! Is it correct?  I regard nbyte member
		// as byte size of IIIMP stream representation,
		// not structure system-dependent size.
		fbattrtmp[j].id = pfb->type;
		fbattrtmp[j].feedback = pfb->value;
	    }

	    pattr = iiimp_feedback_attr_list_new(data_s, pfbl->count_feedbacks, fbattrtmp);
	    if (!pattr) goto error;
	    pcur2 = iiimp_char_with_feedback_new(data_s, *pu, pattr);
	    if (!pcur2) {
		iiimp_feedback_attr_list_delete(data_s, pattr);
		goto error;
	    }
	    if (pcur) {
		pcur->next = pcur2;
		pcur = pcur2;
	    } else {
		phead = pcur = pcur2;
	    }
	}
    }

#if 0 // TODO!!
    {
	// convert IIIMP annotation
	IMAnnotation *pima;
	IMAnnotationValue *pimav;

	for (i = 0, pima = pimtext->annotations;
	     i < pimtext->count_annotations;
	     i++, pima++) {
	    for (j = 0, pimav = pima->values;
		 j < pima->num_values;
		 j++, pimav++) {
		pimav = iiimp_annotation_new(data_s, ...);
	    }
	
	}
    }
#endif

    ptext = iiimp_text_new(data_s, phead, NULL);
    if (!ptext) goto error;

    return ptext;

error:
    if (phead) iiimp_char_with_feedback_delete(data_s, phead);
    return NULL;
}


IIIMP_contents*
convert_IMText_to_iiimp_contents_string(
    IIIMP_data_s *data_s,
    IMText *pimtext
)
{
    IIIMP_string *pstr = convert_IMText_to_iiimp_string(data_s, pimtext);
    if (!pstr) return NULL;
    return iiimp_contents_string_new(data_s, pstr);
}

IIIMP_contents*
convert_IMText_to_iiimp_contents_text(
    IIIMP_data_s *data_s,
    IMText *pimtext
)
{
    IIIMP_text *ptext = convert_IMText_to_iiimp_text(data_s, pimtext);
    if (!ptext) return NULL;
    IIIMP_contents *pcont = iiimp_contents_text_new(data_s, ptext);
    if (!pcont) {
	iiimp_text_delete(data_s, ptext);
	return NULL;
    }

    return pcont;
}


ICAttribute
convert_iiimp_icattr(
    IIIMP_icattribute *pattr
)
{
    // TODO character subsets...
    ICAttribute icattr;
    for (; pattr; pattr = pattr->next) {
	switch (pattr->id) {
	  case IIIMP_ICATTRIBUTE_INPUT_LANGUAGE:
	   icattr.set_inputlanguage(CONV_IIIMP_STR(pattr->value.input_language));
	   break;
	  case IIIMP_ICATTRIBUTE_CHARACTER_SUBSETS:
	  {
	      int i;
	      IIIMP_card32 *p = pattr->value.character_subsets->ptr;
	      int n = pattr->value.character_subsets->count;
	      IMCharSubsets imcs;

	      for (i = 0; i < n; i++, p++) {
		  imcs.add_csidx(*p);
	      }
	      icattr.set_charsubsets(imcs);
	  }
	  break;
	  case IIIMP_ICATTRIBUTE_INPUT_METHOD_NAME:
	   icattr.set_inputmethod(CONV_IIIMP_STR(pattr->value.input_method_name));
	   break;
#if 0
	  case IIIMP_ICATTRIBUTE_INPUT_METHOD:
#endif
	  default:
	   break;
	}
    }

    return icattr;
}

IIIMP_card16
convert_IMObject_type_to_iiimp_predefined_attribid(
    enum IMObject::OBJTYPE otype
)
{
    switch (otype){
      case IMObject::EIMIL_CONFIG:
       return IIIMP_IMATTRIBUTE_CHARACTER_CONVERSION_DEFINITION_RULE;
      case IMObject::IMDESCRIPTOR:
       return IIIMP_IMATTRIBUTE_INPUT_METHOD_LIST;
      case IMObject::BINARY_GUI:
       return IIIMP_IMATTRIBUTE_BINARY_GUI_OBJECT;
      case IMObject::BINARY_LWE:
       return IIIMP_IMATTRIBUTE_BINARY_LIGHT_WEIGHT_ENGINE_OBJECT;
      case IMObject::JAVA_GUI:
       return IIIMP_IMATTRIBUTE_JAR_GUI_OBJECT;
      case IMObject::JAVA_LWE:
       return IIIMP_IMATTRIBUTE_JAR_LIGHT_WEIGHT_ENGINE_OBJECT;
      case IMObject::SCRIPT_GUI:
       return IIIMP_IMATTRIBUTE_SCRIPT_GUI_OBJECT;
      case IMObject::SCRIPT_LWE:
       return IIIMP_IMATTRIBUTE_SCRIPT_LIGHT_WEIGHT_ENGINE_OBJECT;

      case IMObject::UNKNOWN:
      case IMObject::OPERATION:
      case IMObject::NUMBER_VARIABLE:
      case IMObject::BOOL_VARIABLE:
      case IMObject::CHAR_VARIABLE:
      case IMObject::MTEXT_VARIABLE:
      case IMObject::EVENT_VARIABLE:

      case IMObject::NUMBER_PROPERTY:
      case IMObject::BOOL_PROPERTY:
      case IMObject::CHAR_PROPERTY:
      case IMObject::MTEXT_PROPERTY:
      case IMObject::EVENT_PROPERTY:
      default:
       ERROR_INTERNAL("Cannot convert this object type %d to IIIMP category.");
   }
    return 0;
}

/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
