/*
 * Copyright (C) 2011 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 <VideoEditorClasses.h>
#include <VideoEditorJava.h>
#include <VideoEditorLogging.h>
#include <VideoEditorOsal.h>

extern "C" {
#include <M4OSA_CharStar.h>
};


void
videoEditJava_checkAndThrowIllegalArgumentException(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                bool                                condition,
                const char*                         pMessage)
{
    // Check if the previous action succeeded.
    if (*pResult)
    {
        // Check if the condition is true.
        if (condition)
        {
            // Log the exception.
            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",\
                    "videoEditJava_checkAndThrowIllegalArgumentException, %s", pMessage);

            // Reset the result flag.
            (*pResult) = false;

            // Throw an exception.
            jniThrowException(pEnv, "java/lang/IllegalArgumentException", pMessage);
        }
    }
}

void
videoEditJava_checkAndThrowRuntimeException(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                bool                                condition,
                M4OSA_ERR                           result)
{
    const char* pMessage = NULL;

    // Check if the previous action succeeded.
    if (*pResult)
    {
        // Check if the condition is true.
        if (condition)
        {
            // Get the error string.
            pMessage = videoEditJava_getErrorName(result);

            // Log the exception.
            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
                    "videoEditJava_checkAndThrowRuntimeException, %s", pMessage);

            // Reset the result flag.
            (*pResult) = false;

            // Throw an exception.
            jniThrowException(pEnv, "java/lang/RuntimeException", pMessage);
        }
    }
}

void
videoEditJava_checkAndThrowIllegalStateException(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                bool                                condition,
                const char*                         pMessage)
{
    // Check if the previous action succeeded.
    if (*pResult)
    {
        // Check if the condition is true.
        if (condition)
        {
            // Log the exception.
            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
                    "videoEditJava_checkAndThrowIllegalStateException, %s", pMessage);

            // Reset the result flag.
            (*pResult) = false;

            // Throw an exception.
            jniThrowException(pEnv, "java/lang/IllegalStateException", pMessage);
        }
    }
}

void
videoEditJava_getClass(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                const char*                         pName,
                jclass*                             pClazz)
{
    // Only look for the class if locating the previous action succeeded.
    if (*pResult)
    {
        // Log the function call.
        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
                "videoEditJava_getClass(%s)", pName);

        // Look up the class.
        jclass clazz = pEnv->FindClass(pName);

        // Clear any resulting exceptions.
        pEnv->ExceptionClear();

        // Check if the class could be located.
        if (NULL != clazz)
        {
            // Return the class.
            (*pClazz) = clazz;
        }
        else
        {
            // Reset the result flag.
            (*pResult) = false;

            // Log the error.
            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
                    "videoEditJava_getClass, error: unable to locate class %s", pName);

            // Throw an exception.
            jniThrowException(pEnv, "java/lang/ClassNotFoundException",
                    "unable to locate class");
        }
    }
}

void
videoEditJava_getMethodId(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                jclass                              clazz,
                const char*                         pName,
                const char*                         pType,
                jmethodID*                          pMethodId)
{
    // Only look for the class if locating the previous action succeeded.
    if (*pResult)
    {
        // Log the function call.
        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
                "videoEditJava_getMethodId(%s,%s)", pName, pType);

        // Look up the method id.
        jmethodID methodId = pEnv->GetMethodID(clazz, pName, pType);

        // Clear any resulting exceptions.
        pEnv->ExceptionClear();

        // Check if the method could be located.
        if (NULL != methodId)
        {
            // Return the method id.
            (*pMethodId) = methodId;
        }
        else
        {
            // Reset the result flag.
            (*pResult) = false;

            // Log the error.
            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
                    "videoEditJava_getMethodId, error: unable to locate method %s with type %s",
                    pName, pType);

            // Throw an exception.
            jniThrowException(pEnv, "java/lang/NoSuchMethodException", "unable to locate method");
        }
    }
}

void
videoEditJava_getFieldId(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                jclass                              clazz,
                const char*                         pName,
                const char*                         pType,
                jfieldID*                           pFieldId)
{
    // Only look for the class if locating the previous action succeeded.
    if (*pResult)
    {
        // Log the function call.
        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
                "videoEditJava_getFieldId(%s,%s)", pName, pType);

        // Look up the field id.
        jfieldID fieldId = pEnv->GetFieldID(clazz, pName, pType);

        // Clear any resulting exceptions.
        pEnv->ExceptionClear();

        // Check if the field could be located.
        if (NULL != fieldId)
        {
            // Return the field id.
            (*pFieldId) = fieldId;
        }
        else
        {
            // Reset the result flag.
            (*pResult) = false;

            // Log the error.
            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
                    "videoEditJava_getFieldId, error: unable to locate field %s with type %s",
                    pName, pType);

            // Throw an exception.
            jniThrowException(pEnv, "java/lang/NoSuchFieldException", "unable to locate field");
        }
    }
}

void
videoEditJava_getObject(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                jobject                             object,
                jfieldID                            objectFieldId,
                jobject*                            pObject)
{
    // Only retrieve the array object and size if the previous action succeeded.
    if (*pResult)
    {
        // Log the function call.
        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
            "videoEditJava_getObject()");

        // Retrieve the object.
        (*pObject) = pEnv->GetObjectField(object, objectFieldId);

        // Clear any resulting exceptions.
        pEnv->ExceptionClear();
    }
}

void
videoEditJava_getArray(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                jobject                             object,
                jfieldID                            arrayFieldId,
                jobjectArray*                       pArray,
                jsize*                              pArraySize)
{
    // Only retrieve the array object and size if the previous action succeeded.
    if (*pResult)
    {
        // Log the function call.
        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", "videoEditJava_getArray()");

        // Retrieve the array object.
        jobjectArray array     = (jobjectArray)pEnv->GetObjectField(object, arrayFieldId);
        jsize        arraySize = 0;

        // Clear any resulting exceptions.
        pEnv->ExceptionClear();

        // Check if the array could be retrieved.
        if (NULL != array)
        {
            // Retrieve the array size.
            arraySize = pEnv->GetArrayLength(array);
        }

        // Return the array and its size.
        (*pArray)     = array;
        (*pArraySize) = arraySize;
    }
}

void*
videoEditJava_getString(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                jobject                             object,
                jfieldID                            stringFieldId,
                M4OSA_UInt32*                       pLength)
{
    void*        pString = M4OSA_NULL;
    jstring      string  = NULL;
    M4OSA_UInt32 length  = 0;
    M4OSA_Char*  pLocal  = M4OSA_NULL;
    M4OSA_ERR    result  = M4NO_ERROR;

    // Check if the previous action succeeded.
    if (*pResult)
    {
        // Log the function call.
        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", "videoEditJava_getString()");

        // Check if an object containing a string was specified.
        if (NULL != stringFieldId)
        {
            // Retrieve the string object.
            string = (jstring)pEnv->GetObjectField(object, stringFieldId);

            // Clear any resulting exceptions.
            pEnv->ExceptionClear();
        }
        else
        {
            // The string itself was specified.
            string = (jstring)object;
        }

        // Check if the string could be retrieved.
        if (NULL != string)
        {
            // Get a local copy of the string.
            pLocal = (M4OSA_Char*)pEnv->GetStringUTFChars(string, M4OSA_NULL);
            if (M4OSA_NULL != pLocal)
            {
                // Determine the length of the path
                // (add one extra character for the zero terminator).
                length = strlen((const char *)pLocal) + 1;

                // Allocate memory for the string.
                pString = videoEditOsal_alloc(pResult, pEnv, length, "String");
                if (*pResult)
                {
                    // Copy the string.
                    result = M4OSA_chrNCopy((M4OSA_Char*)pString, pLocal, length);

                    // Check if the copy succeeded.
                    videoEditJava_checkAndThrowRuntimeException(pResult, pEnv,
                     (M4NO_ERROR != result), result);

                    // Check if the string could not be copied.
                    if (!(*pResult))
                    {
                        // Free the allocated memory.
                        videoEditOsal_free(pString);
                        pString = M4OSA_NULL;
                    }
                }

                // Release the local copy of the string.
                pEnv->ReleaseStringUTFChars(string, (const char *)pLocal);
            }
        }

        // Check if the string was empty or could be copied.
        if (*pResult)
        {
            // Check if the length was requested.
            if (M4OSA_NULL != pLength)
            {
                // Return the length.
                (*pLength) = length;
            }
        }
    }

    // Return the string.
    return(pString);
}

void
videoEditJava_getStaticIntField(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                jclass                              clazz,
                const char*                         pName,
                int*                                pValue)
{
    // Only look for the class if locating the previous action succeeded.
    if (*pResult)
    {
        // Log the function call.
        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
                "videoEditJava_getStaticIntField(%s)", pName);

        // Look up the field id.
        jfieldID fieldId = pEnv->GetStaticFieldID(clazz, pName, "I");

        // Clear any resulting exceptions.
        pEnv->ExceptionClear();

        // Check if the field could be located.
        if (NULL != fieldId)
        {
            // Retrieve the field value.
            (*pValue) = pEnv->GetStaticIntField(clazz, fieldId);

            // Log the value.
            VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
                    "videoEditJava_getStaticIntField, %s = %d", pName, (*pValue));
        }
        else
        {
            // Reset the result flag.
            (*pResult) = false;

            // Log the error.
            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
                    "videoEditJava_getStaticIntField, error: unable to locate field %s", pName);

            // Throw an exception.
            jniThrowException(pEnv, "java/lang/NoSuchFieldException",
                    "unable to locate static field");
        }
    }
}

void
videoEditJava_initConstantClass(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                VideoEditJava_ConstantsClass*               pClass)
{
    bool   gotten = true;
    jclass clazz  = NULL;
    int    index  = 0;

    // Check if the previous action succeeded.
    if (*pResult)
    {
        // Log the function call.
        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
                "videoEditJava_initConstantClass(%s)", pClass->pName);

        // Only initialize the class once.
        if (!pClass->initialized)
        {
            // Look up the class.
            videoEditJava_getClass(pResult, pEnv, pClass->pName, &clazz);

            // Loop over the constants.
            for (index = 0; index < pClass->count; index++)
            {
                // Look up the constant.
                videoEditJava_getStaticIntField(pResult, pEnv, clazz,
                                        pClass->pConstants[index].pName,
                                        &pClass->pConstants[index].java);
            }

            // Check if all constants could be located.
            if (*pResult)
            {
                // Set the initialized flag.
                pClass->initialized = true;
            }
        }
    }
}

const char*
videoEditJava_getConstantClassName(
                const VideoEditJava_ConstantsClass*         pClass,
                int                                 value,
                VideoEditJava_UnknownConstant               unknown)
{
    const char* pName = M4OSA_NULL;
    int         index = 0;

    // Loop over the list with constants.
    for (index = 0;
         ((M4OSA_NULL == pName) && (index < pClass->count));
         index++)
    {
        // Check if the specified value matches the c value of the constant.
        if (value == pClass->pConstants[index].c)
        {
            // Set the name.
            pName = pClass->pConstants[index].pName;
        }
    }

    // Check if no constant was found.
    if (M4OSA_NULL == pName)
    {
        // Check if a function was specified to handle this case.
        if (M4OSA_NULL != unknown)
        {
            // Pass the constant to the specified unknown function.
            pName = unknown(value);
        }
        else
        {
            // Set the description to a default value.
            pName = "<unknown>";
        }
    }

    // Return the result.
    return(pName);
}

const char*
videoEditJava_getConstantClassString(
                const VideoEditJava_ConstantsClass*         pClass,
                int                                 value,
                VideoEditJava_UnknownConstant               unknown)
{
    const char* pString = M4OSA_NULL;
    int         index   = 0;

    // Loop over the list with constants.
    for (index = 0;
         ((M4OSA_NULL == pString) && (index < pClass->count));
         index++)
    {
        // Check if the specified value matches the c value of the constant.
        if (value == pClass->pConstants[index].c)
        {
            // Set the description.
            pString = pClass->pConstants[index].pDescription;
        }
    }

    // Check if no constant was found.
    if (M4OSA_NULL == pString)
    {
        // Check if a function was specified to handle this case.
        if (M4OSA_NULL != unknown)
        {
            // Pass the constant to the specified unknown function.
            pString = unknown(value);
        }
        else
        {
            // Set the description to a default value.
            pString = "<unknown>";
        }
    }

    // Return the result.
    return(pString);
}

int
videoEditJava_getConstantClassJavaToC(
                bool*                               pResult,
                const VideoEditJava_ConstantsClass*         pClass,
                int                                 value)
{
    bool gotten = false;
    int  index  = 0;

    // Check if the previous action succeeded.
    if (*pResult)
    {
        // Loop over the list with constants.
        for (index = 0; ((!gotten) && (index < pClass->count)); index++)
        {
            // Check if the specified value matches the java value of the constant.
            if (value == pClass->pConstants[index].java)
            {
                // Set the value to the c value.
                value = pClass->pConstants[index].c;

                // Set the gotten flag.
                gotten = true;
            }
        }

        // Check if the value was not found.
        if (!gotten)
        {
            (*pResult) = false;
        }
    }

    // Return the translated value.
    return(value);
}

int
videoEditJava_getConstantClassJavaToC(
                bool*                               pResult,
                const VideoEditJava_ConstantsClass*         pClass,
                int                                 value,
                int                                 unknown)
{
    bool gotten = false;
    int  index  = 0;

    // Check if the previous action succeeded.
    if (*pResult)
    {
        // Loop over the list with constants.
        for (index = 0; ((!gotten) && (index < pClass->count)); index++)
        {
            // Check if the specified value matches the java value of the constant.
            if (value == pClass->pConstants[index].java)
            {
                // Set the value to the c value.
                value = pClass->pConstants[index].c;

                // Set the gotten flag.
                gotten = true;
            }
        }

        // If the constant was not found, look for the specified unknown.
        if (!gotten)
        {
            // Set the value to the c value.
            value = unknown;
        }
    }

    // Return the translated value.
    return(value);
}

int
videoEditJava_getConstantClassCToJava(
                const VideoEditJava_ConstantsClass*         pClass,
                int                                 value)
{
    bool gotten = false;
    int  index  = 0;

    // Loop over the list with constants.
    for (index = 0; ((!gotten) && (index < pClass->count)); index++)
    {
        // Check if the specified value matches the c value of the constant.
        if (value == pClass->pConstants[index].c)
        {
            // Set the value to the java value.
            value = pClass->pConstants[index].java;

            // Set the gotten flag.
            gotten = true;
        }
    }

    // Return the translated value.
    return(value);
}

int
videoEditJava_getConstantClassCToJava(
                const VideoEditJava_ConstantsClass*         pClass,
                int                                 value,
                int                                 unknown)
{
    bool gotten = false;
    int  index  = 0;

    // Loop over the list with constants.
    for (index = 0; ((!gotten) && (index < pClass->count)); index++)
    {
        // Check if the specified value matches the c value of the constant.
        if (value == pClass->pConstants[index].c)
        {
            // Set the value to the java value.
            value = pClass->pConstants[index].java;

            // Set the gotten flag.
            gotten = true;
        }
    }

    // If the constant was not found, look for the specified unknown.
    if (!gotten)
    {
        // Loop over the list with constants.
        for (index = 0; ((!gotten) && (index < pClass->count)); index++)
        {
            // Check if the specified value matches the java value of the constant.
            if (unknown == pClass->pConstants[index].c)
            {
                // Set the value to the c value.
                value = pClass->pConstants[index].java;

                // Set the gotten flag.
                gotten = true;
            }
        }
    }

    // Return the translated value.
    return(value);
}

void
videoEditJava_initFieldClass(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                VideoEditJava_FieldsClass*                  pClass)
{
    bool   gotten = true;
    jclass clazz  = NULL;
    int    index  = 0;

    // Check if the previous action succeeded.
    if (*pResult)
    {
        // Log the function call.
        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
                "videoEditJava_initFieldClass(%s)", pClass->pName);

        // Only initialize the class once.
        if (!pClass->initialized)
        {
            // Look up the class.
            videoEditJava_getClass(pResult, pEnv, pClass->pName, &clazz);

            // Loop over the fields.
            for (index = 0; index < pClass->count; index++)
            {
                // Look up the field id.
                videoEditJava_getFieldId(
                        pResult,
                        pEnv,
                        clazz,
                        pClass->pFields[index].pName,
                        pClass->pFields[index].pType,
                        &pClass->pFields[index].fieldId);
            }

            // Check if all fields could be located.
            if (*pResult)
            {
                // Set the initialized flag.
                pClass->initialized = true;
            }
        }
    }
}

void
videoEditJava_fieldClassClass(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                const VideoEditJava_FieldsClass*            pClass,
                jclass*                             pClazz)
{
    // Check if the previous action succeeded.
    if (*pResult)
    {
        // Check if the class is initialized.
        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, (!pClass->initialized),
                "field class not initialized");

        // Get the class.
        videoEditJava_getClass(pResult, pEnv, pClass->pName, pClazz);
    }
}

void
videoEditJava_fieldClassFieldIds(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                const VideoEditJava_FieldsClass*            pClass,
                int                                 count,
                VideoEditJava_FieldIds*                     pIds)
{
    int index = 0;

    // Check if the previous action succeeded.
    if (*pResult)
    {
        // Check if the class is initialized.
        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, (!pClass->initialized),
                "field class not initialized");

        // Check if the number of fields matches.
        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
                (pClass->count != count),
                "field class type mismatch");

        // Check if the class and object are valid.
        if (*pResult)
        {
            // Loop over the class fields.
            for (index = 0; index < count; index++)
            {
                // Copy the field ids.
                pIds->fieldIds[index] = pClass->pFields[index].fieldId;
            }
        }
    }
}

void
videoEditJava_initMethodClass(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                VideoEditJava_MethodsClass*                 pClass)
{
    bool   gotten = true;
    jclass clazz  = NULL;
    int    index  = 0;

    // Check if the previous action succeeded.
    if (*pResult)
    {
        // Log the function call.
        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
                "videoEditJava_initMethodClass(%s)", pClass->pName);

        // Only initialize the class once.
        if (!pClass->initialized)
        {
            // Look up the class.
            videoEditJava_getClass(pResult, pEnv, pClass->pName, &clazz);

            // Loop over the methods.
            for (index = 0; index < pClass->count; index++)
            {
                // Look up the method id.
                videoEditJava_getMethodId(
                        pResult,
                        pEnv,
                        clazz,
                        pClass->pMethods[index].pName,
                        pClass->pMethods[index].pType,
                        &pClass->pMethods[index].methodId);
            }

            // Check if all methods could be located.
            if (*pResult)
            {
                // Set the initialized flag.
                pClass->initialized = true;
            }
        }
    }
}

void
videoEditJava_methodClassMethodIds(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                const VideoEditJava_MethodsClass*   pClass,
                int                                 count,
                VideoEditJava_MethodIds*            pIds)
{
    int index = 0;

    // Check if the previous action succeeded.
    if (*pResult)
    {
        // Check if the class is initialized.
        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, (!pClass->initialized),
                    "method class not initialized");

        // Check if the number of methods matches.
        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,\
                    (pClass->count != count),
                    "method class type mismatch");

        // Check if the class and object are valid.
        if (*pResult)
        {
            // Loop over the class methods.
            for (index = 0; index < count; index++)
            {
                // Copy the method ids.
                pIds->methodIds[index] = pClass->pMethods[index].methodId;
            }
        }
    }
}

