/*
**********************************************************************
*   Copyright (c) 2000, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   Date        Name        Description
*   01/17/2000  aliu        Ported from Java.
**********************************************************************
*/
#include "unicode/jamohang.h"
#include "unicode/rep.h"
#include "unicode/unifilt.h"
#include "unicode/unicode.h"

/**
 * ID for this transliterator.
 */
const char* JamoHangulTransliterator::_ID = "Jamo-Hangul";

/**
 * Constructs a transliterator.
 */
JamoHangulTransliterator::JamoHangulTransliterator(UnicodeFilter* adoptedFilter) :
    Transliterator(_ID, adoptedFilter) {
    setMaximumContextLength(3);
}

/**
 * Copy constructor.
 */
JamoHangulTransliterator::JamoHangulTransliterator(const JamoHangulTransliterator& o) :
    Transliterator(o) {
}

/**
 * Assignment operator.
 */
JamoHangulTransliterator& JamoHangulTransliterator::operator=(
                                             const JamoHangulTransliterator& o) {
    Transliterator::operator=(o);
    return *this;
}

/**
 * Transliterator API.
 */
Transliterator* JamoHangulTransliterator::clone(void) const {
    return new JamoHangulTransliterator(*this);
}

/**
 * Implements {@link Transliterator#handleTransliterate}.
 */
void JamoHangulTransliterator::handleTransliterate(Replaceable& text, Position& offsets,
                                                   bool_t isIncremental) const {
    /**
     * Performs transliteration changing Jamo to Hangul 
     */
    int32_t cursor = offsets.cursor;
    int32_t limit = offsets.limit;
    if (cursor >= limit) return;

    int32_t count;

    UChar last = filteredCharAt(text, cursor++);
    UnicodeString str("a", 1);
    while (cursor <= limit) {
        UChar next = 0xFFFF; // go over end of string, just in case
        if (cursor < limit) next = filteredCharAt(text, cursor);
        UChar replacement = composeHangul(last, next, count);
        if (replacement != last) {
            str[0] = replacement;
            text.handleReplaceBetween(cursor-1, cursor-1 + count, str);
            limit = limit - count + 1; // fix up limit 2 => -1, 1 => 0
            last = replacement;
            if (next == 0xFFFF) break;
            // don't change cursor, so we revisit char
        } else {
            ++cursor;
            last = next;
        }
    }

    offsets.limit = limit + 1;
    offsets.cursor = cursor;
}

// These constants are from the Unicode book's algorithm.

#define SBase   (0xAC00)
#define LBase   (0x1100)
#define VBase   (0x1161)
#define TBase   (0x11A7)
#define LCount  (19)
#define VCount  (21)
#define TCount  (28)
#define NCount  (VCount * TCount)   // 588
#define SCount  (LCount * NCount)   // 11172
#define LLimit  (0x1200)

/**
 * Return composed character (if it is a modern jamo)
 * last otherwise.
 * If there is a replacement, returns count[0] = 2 if ch was used, 1 otherwise
 */
UChar JamoHangulTransliterator::composeHangul(UChar last, UChar ch, int32_t& count) {
    count = 2; // default is replace 2 chars
    // check to see if two current characters are L and V
    int32_t LIndex = last - LBase;
    if (0 <= LIndex && LIndex < LCount) {
        int32_t VIndex = ch - VBase;
        if (0 <= VIndex && VIndex < VCount) {
            // make syllable of form LV
            return (UChar)(SBase + (LIndex * VCount + VIndex) * TCount);
        } else {
            // it is isolated, so fix!
            count = 1; // not using ch
            return (UChar)(SBase + (LIndex * VCount) * TCount);
        }
    }
      
    // if neither case was true, see if we have an isolated Jamo we need to fix
    if (LBase <= last && last < LLimit) {
        // need to fix: it is either medial or final!
        int32_t VIndex = last - VBase;
        if (0 <= VIndex && VIndex < VCount) {
            LIndex = 0x110B - LBase; // use empty consonant
            // make syllable of form LV
            count = 1; // not using ch
            return (UChar)(SBase + (LIndex * VCount + VIndex) * TCount);
        }
        // ok, see if final. Use null consonant + a + final
        int32_t TIndex = last - TBase;
        if (0 <= TIndex && TIndex <= TCount) {  // need to fix!
            count = 1; // not using ch
            return (UChar)(0xC544 + TIndex);
        }
    }
 
    // check to see if two current characters are LV and T
    int32_t SIndex = last - SBase;
    if (0 <= SIndex && SIndex < SCount && (SIndex % TCount) == 0) {
        int32_t TIndex = ch - TBase;
        if (0 <= TIndex && TIndex <= TCount) {
            // make syllable of form LVT
            return (UChar)(last + TIndex);
        }
    }
      
    return last;
}    
