/*
 * 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 = M4OSA_chrLength(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;
            }
        }
    }
}

