/*
 * 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_checkAndThrowIllegalArgumentExceptionFunc(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                bool                                condition,
                const char*                         pMessage,
                const char*                         pFile,
                int                                 lineNo)
{
    // 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 (%s:%d)",
                    pMessage, pFile, lineNo);

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

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

void
videoEditJava_checkAndThrowRuntimeExceptionFunc(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                bool                                condition,
                M4OSA_ERR                           result,
                const char*                         pFile,
                int                                 lineNo
                )
{
    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 (%s:%d)",
                    pMessage, pFile, lineNo);

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

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

void
videoEditJava_checkAndThrowIllegalStateExceptionFunc(
                bool*                               pResult,
                JNIEnv*                             pEnv,
                bool                                condition,
                const char*                         pMessage,
                const char*                         pFile,
                int                                 lineNo
                )
{
    // 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 (%s:%d)",
                    pMessage, pFile, lineNo);

            // 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;
            }
        }

        // Delete local references to avoid memory leaks
        pEnv->DeleteLocalRef(string);
    }

    // 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;
            }
        }
    }
}

