/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "NativeBreakIterator"

#include "JNIHelp.h"
#include "ErrorCode.h"
#include "ScopedUtfChars.h"
#include "unicode/ubrk.h"
#include "unicode/putil.h"
#include <stdlib.h>

static jint getIterator(JNIEnv* env, jstring locale, UBreakIteratorType type) {
    UErrorCode status = U_ZERO_ERROR;
    ScopedUtfChars localeChars(env, locale);
    if (!localeChars.c_str()) {
        return 0;
    }
    UBreakIterator* it = ubrk_open(type, localeChars.c_str(), NULL, 0, &status);
    icu4jni_error(env, status);
    return reinterpret_cast<uintptr_t>(it);
}

static jint getCharacterInstanceImpl(JNIEnv* env, jclass, jstring locale) {
    return getIterator(env, locale, UBRK_CHARACTER);
}

static jint getLineInstanceImpl(JNIEnv* env, jclass, jstring locale) {
    return getIterator(env, locale, UBRK_LINE);
}

static jint getSentenceInstanceImpl(JNIEnv* env, jclass, jstring locale) {
    return getIterator(env, locale, UBRK_SENTENCE);
}

static jint getWordInstanceImpl(JNIEnv* env, jclass, jstring locale) {
    return getIterator(env, locale, UBRK_WORD);
}

static UBreakIterator* breakIterator(jint address) {
    return reinterpret_cast<UBreakIterator*>(static_cast<uintptr_t>(address));
}

static void closeBreakIteratorImpl(JNIEnv*, jclass, jint address) {
    ubrk_close(breakIterator(address));
}

static jint cloneImpl(JNIEnv* env, jclass, jint address) {
    UErrorCode status = U_ZERO_ERROR;
    jint bufferSize = U_BRK_SAFECLONE_BUFFERSIZE;
    UBreakIterator* it = ubrk_safeClone(breakIterator(address), NULL, &bufferSize, &status);
    icu4jni_error(env, status);
    return reinterpret_cast<uintptr_t>(it);
}

static void setTextImpl(JNIEnv* env, jclass, jint address, jstring text) {
    UErrorCode status = U_ZERO_ERROR;
    const UChar* chars = env->GetStringChars(text, NULL);
    ubrk_setText(breakIterator(address), chars, env->GetStringLength(text), &status);
    env->ReleaseStringChars(text, chars);
    icu4jni_error(env, status);
}

static jboolean isBoundaryImpl(JNIEnv*, jclass, jint address, jint offset) {
    return ubrk_isBoundary(breakIterator(address), offset);
}

static jint nextImpl(JNIEnv*, jclass, jint address, jint n) {
    UBreakIterator* bi = breakIterator(address);
    if (n < 0) {
        while (n++ < -1) {
            ubrk_previous(bi);
        }
        return ubrk_previous(bi);
    } else if (n == 0) {
        return ubrk_current(bi);
    } else {
        while (n-- > 1) {
            ubrk_next(bi);
        }
        return ubrk_next(bi);
    }
    return -1;
}

static jint precedingImpl(JNIEnv*, jclass, jint address, jint offset) {
    return ubrk_preceding(breakIterator(address), offset);
}

static jint firstImpl(JNIEnv*, jclass, jint address) {
    return ubrk_first(breakIterator(address));
}

static jint followingImpl(JNIEnv*, jclass, jint address, jint offset) {
    return ubrk_following(breakIterator(address), offset);
}

static jint currentImpl(JNIEnv*, jclass, jint address) {
    return ubrk_current(breakIterator(address));
}

static jint previousImpl(JNIEnv*, jclass, jint address) {
    return ubrk_previous(breakIterator(address));
}

static jint lastImpl(JNIEnv*, jclass, jint address) {
    return ubrk_last(breakIterator(address));
}

static JNINativeMethod gMethods[] = {
    { "cloneImpl", "(I)I", (void*) cloneImpl },
    { "closeBreakIteratorImpl", "(I)V", (void*) closeBreakIteratorImpl },
    { "currentImpl", "(I)I", (void*) currentImpl },
    { "firstImpl", "(I)I", (void*) firstImpl },
    { "followingImpl", "(II)I", (void*) followingImpl },
    { "getCharacterInstanceImpl", "(Ljava/lang/String;)I", (void*) getCharacterInstanceImpl },
    { "getLineInstanceImpl", "(Ljava/lang/String;)I", (void*) getLineInstanceImpl },
    { "getSentenceInstanceImpl", "(Ljava/lang/String;)I", (void*) getSentenceInstanceImpl },
    { "getWordInstanceImpl", "(Ljava/lang/String;)I", (void*) getWordInstanceImpl },
    { "isBoundaryImpl", "(II)Z", (void*) isBoundaryImpl },
    { "lastImpl", "(I)I", (void*) lastImpl },
    { "nextImpl", "(II)I", (void*) nextImpl },
    { "precedingImpl", "(II)I", (void*) precedingImpl },
    { "previousImpl", "(I)I", (void*) previousImpl },
    { "setTextImpl", "(ILjava/lang/String;)V", (void*) setTextImpl },
};
int register_com_ibm_icu4jni_text_NativeBreakIterator(JNIEnv* env) {
    return jniRegisterNativeMethods(env, "com/ibm/icu4jni/text/NativeBreakIterator",
            gMethods, NELEM(gMethods));
}
