/* //device/libs/android_runtime/android_pim_EventRecurrence.cpp
**
** Copyright 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.
*/

#include <pim/EventRecurrence.h>
#include "jni.h"
#include "nativehelper/JNIHelp.h"
#include <utils/String8.h>

namespace android {

struct cached_array_fields_t
{
    jfieldID array;
    jfieldID count;
};

static jfieldID freq_field;
static jfieldID until_field;
static jfieldID count_field;
static jfieldID interval_field;
static jfieldID wkst_field;
static cached_array_fields_t bysecond_fields;
static cached_array_fields_t byminute_fields;
static cached_array_fields_t byhour_fields;
static cached_array_fields_t byday_fields;
static cached_array_fields_t bydayNum_fields;
static cached_array_fields_t bymonthday_fields;
static cached_array_fields_t byyearday_fields;
static cached_array_fields_t byweekno_fields;
static cached_array_fields_t bymonth_fields;
static cached_array_fields_t bysetpos_fields;

static status_t
set_array(JNIEnv* env, int inCount, int* inArray,
            jobject This, const cached_array_fields_t& fields)
{
    if (inCount > 0) {
        jintArray array = (jintArray) env->GetObjectField(This, fields.array);
        if (array == NULL || env->GetArrayLength(array) < inCount) {
            // +4 because it's cheap to allocate a little extra here, and
            // that reduces the chance that we'll come back here again
            array = env->NewIntArray(inCount+4);
            env->SetObjectField(This, fields.array, array);
        }
        if (array == NULL) {
            return NO_MEMORY;
        }
        env->SetIntArrayRegion(array, 0, inCount, inArray);

    }
    env->SetIntField(This, fields.count, inCount);
    return NO_ERROR;
}

/*
 * In class android.pim.EventRecurrence
 *  public native int parse(String str);
 */
#define SET_ARRAY_AND_CHECK(name) \
    /*printf("setting " #name " to %d elements\n", er.name##Count);*/ \
    if (set_array(env, er.name##Count, er.name, This, name##_fields) \
            != NO_ERROR) { \
        jniThrowException(env, "java/lang/RuntimeException", \
                "EventRecurrence.parse error setting field " #name " or " \
                #name "Count."); \
        return ; \
    }
static void
EventRecurrence_parse(JNIEnv* env, jobject This, jstring jstr)
{
    if (jstr == NULL) {
        jniThrowNullPointerException(env, "EventRecurrence.parse str parameter null");
        return ;
    }
    const jchar* jchars = env->GetStringChars(jstr, NULL);
    jsize len = env->GetStringLength(jstr);
    String16 str(jchars, len);
    env->ReleaseStringChars(jstr, jchars);

    //printf("the string was '%s'\n", String8(str).string());

    EventRecurrence er;
    if (NO_ERROR != er.parse(str)) {
        String8 msg("Error parsing recurrence: '");
        msg.append(String8(str));
        msg.append("'");

        jniThrowException(env,
                "android/pim/EventRecurrence$InvalidFormatException",
                msg.string());
        return ;
    }

    jstring untilStr;
    if (er.until.size() > 0) {
        untilStr = env->NewString(er.until.string(), er.until.size());
        if (untilStr == NULL) {
            jniThrowException(env, "java/lang/RuntimeException",
                    "EventRecurrence.parse error setting field 'until'");
            return ;
        }
    } else {
        untilStr = NULL;
    }
    env->SetObjectField(This, until_field, untilStr);

    env->SetIntField(This, freq_field, er.freq);
    env->SetIntField(This, count_field, er.count);
    env->SetIntField(This, interval_field, er.interval);
    env->SetIntField(This, wkst_field, er.wkst);

    SET_ARRAY_AND_CHECK(bysecond)
    SET_ARRAY_AND_CHECK(byminute)
    SET_ARRAY_AND_CHECK(byhour)
    SET_ARRAY_AND_CHECK(byday)
    // we'll just set the bydayCount field twice, it'll be less code total
    if (set_array(env, er.bydayCount, er.bydayNum, This, bydayNum_fields)
            != NO_ERROR) {
        jniThrowException(env, "java/lang/RuntimeException",
                "EventRecurrence.parse error setting field bydayNum or "
                "bydayCount.");
        return ;
    }
    SET_ARRAY_AND_CHECK(bymonthday)
    SET_ARRAY_AND_CHECK(byyearday)
    SET_ARRAY_AND_CHECK(byweekno)
    SET_ARRAY_AND_CHECK(bymonth)
    SET_ARRAY_AND_CHECK(bysetpos)
}

/*
 * JNI registration.
 */
static JNINativeMethod METHODS[] = {
    /* name, signature, funcPtr */
    { "parse", "(Ljava/lang/String;)V", (void*)EventRecurrence_parse }
};

static const char*const CLASS_NAME = "android/pim/EventRecurrence";

int register_android_pim_EventRecurrence(JNIEnv* env)
{
    jclass clazz = env->FindClass(CLASS_NAME);
    if (clazz == NULL) {
        LOGE("Field lookup unable to find class '%s'\n", CLASS_NAME);
        return -1;
    }

    freq_field = env->GetFieldID(clazz, "freq", "I");
    count_field = env->GetFieldID(clazz, "count", "I");
    interval_field = env->GetFieldID(clazz, "interval", "I");
    wkst_field = env->GetFieldID(clazz, "wkst", "I");

    until_field = env->GetFieldID(clazz, "until", "Ljava/lang/String;");

    bysecond_fields.array = env->GetFieldID(clazz, "bysecond", "[I");
    bysecond_fields.count = env->GetFieldID(clazz, "bysecondCount", "I");
    byminute_fields.array = env->GetFieldID(clazz, "byminute", "[I");
    byminute_fields.count = env->GetFieldID(clazz, "byminuteCount", "I");
    byhour_fields.array = env->GetFieldID(clazz, "byhour", "[I");
    byhour_fields.count = env->GetFieldID(clazz, "byhourCount", "I");
    byday_fields.array = env->GetFieldID(clazz, "byday", "[I");
    byday_fields.count = env->GetFieldID(clazz, "bydayCount", "I");
    bydayNum_fields.array = env->GetFieldID(clazz, "bydayNum", "[I");
    bydayNum_fields.count = byday_fields.count;
    bymonthday_fields.array = env->GetFieldID(clazz, "bymonthday", "[I");
    bymonthday_fields.count = env->GetFieldID(clazz, "bymonthdayCount", "I");
    byyearday_fields.array = env->GetFieldID(clazz, "byyearday", "[I");
    byyearday_fields.count = env->GetFieldID(clazz, "byyeardayCount", "I");
    byweekno_fields.array = env->GetFieldID(clazz, "byweekno", "[I");
    byweekno_fields.count = env->GetFieldID(clazz, "byweeknoCount", "I");
    bymonth_fields.array = env->GetFieldID(clazz, "bymonth", "[I");
    bymonth_fields.count = env->GetFieldID(clazz, "bymonthCount", "I");
    bysetpos_fields.array = env->GetFieldID(clazz, "bysetpos", "[I");
    bysetpos_fields.count = env->GetFieldID(clazz, "bysetposCount", "I");

    return jniRegisterNativeMethods(env, CLASS_NAME,
        METHODS, sizeof(METHODS)/sizeof(METHODS[0]));
}

}; // namespace android
