/* libs/android_runtime/android/graphics/PathMeasure.cpp
**
** Copyright 2007, 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 "GraphicsJNI.h"

#include "SkMatrix.h"
#include "SkPath.h"
#include "SkPathMeasure.h"
#include "SkPoint.h"
#include "SkScalar.h"

/*  We declare an explicit pair, so that we don't have to rely on the java
    client to be sure not to edit the path while we have an active measure
    object associated with it.
 
    This costs us the copy of the path, for the sake of not allowing a bad
    java client to randomly crash (since we can't detect the case where the
    native path has been modified).
 
    The C side does have this risk, but it chooses for speed over safety. If it
    later changes this, and is internally safe from changes to the path, then
    we can remove this explicit copy from our JNI code.
 
    Note that we do not have a reference on the java side to the java path.
    Were we to not need the native copy here, we would want to add a java
    reference, so that the java path would not get GD'd while the measure object
    was still alive.
*/
struct PathMeasurePair {
    PathMeasurePair() {}
    PathMeasurePair(const SkPath& path, bool forceClosed)
        : fPath(path), fMeasure(fPath, forceClosed) {}

    SkPath          fPath;      // copy of the user's path
    SkPathMeasure   fMeasure;   // this guy points to fPath
};

namespace android {
    
class SkPathMeasureGlue {
public:

    static jlong create(JNIEnv* env, jobject clazz, jlong pathHandle,
                        jboolean forceClosedHandle) {
        const SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
        bool forceClosed = (forceClosedHandle == JNI_TRUE);
        PathMeasurePair* pair;
        if(path)
            pair = new PathMeasurePair(*path, forceClosed);
        else
            pair = new PathMeasurePair;
        return reinterpret_cast<jlong>(pair);
    }

    static void setPath(JNIEnv* env, jobject clazz, jlong pairHandle,
                        jlong pathHandle, jboolean forceClosedHandle) {
        PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
        const SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
        bool forceClosed = (forceClosedHandle == JNI_TRUE);

        if (NULL == path) {
            pair->fPath.reset();
        } else {
            pair->fPath = *path;
        }
        pair->fMeasure.setPath(&pair->fPath, forceClosed);
    }

    static jfloat getLength(JNIEnv* env, jobject clazz, jlong pairHandle) {
        PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
        return static_cast<jfloat>(SkScalarToFloat(pair->fMeasure.getLength()));
    }

    static void convertTwoElemFloatArray(JNIEnv* env, jfloatArray array, const SkScalar src[2]) {
        AutoJavaFloatArray autoArray(env, array, 2);
        jfloat* ptr = autoArray.ptr();
        ptr[0] = SkScalarToFloat(src[0]);
        ptr[1] = SkScalarToFloat(src[1]);
    }

    static jboolean getPosTan(JNIEnv* env, jobject clazz, jlong pairHandle, jfloat dist, jfloatArray pos, jfloatArray tan) {
        PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
        SkScalar    tmpPos[2], tmpTan[2];
        SkScalar*   posPtr = pos ? tmpPos : NULL;
        SkScalar*   tanPtr = tan ? tmpTan : NULL;
        
        if (!pair->fMeasure.getPosTan(dist, (SkPoint*)posPtr, (SkVector*)tanPtr)) {
            return JNI_FALSE;
        }
    
        if (pos) {
            convertTwoElemFloatArray(env, pos, tmpPos);
        }
        if (tan) {
            convertTwoElemFloatArray(env, tan, tmpTan);
        }
        return JNI_TRUE;
    }

    static jboolean getMatrix(JNIEnv* env, jobject clazz, jlong pairHandle, jfloat dist,
                          jlong matrixHandle, jint flags) {
        PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
        SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
        bool result = pair->fMeasure.getMatrix(dist, matrix, (SkPathMeasure::MatrixFlags)flags);
        return result ? JNI_TRUE : JNI_FALSE;
    }

    static jboolean getSegment(JNIEnv* env, jobject clazz, jlong pairHandle, jfloat startF,
                               jfloat stopF, jlong dstHandle, jboolean startWithMoveTo) {
        PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
        SkPath* dst = reinterpret_cast<SkPath*>(dstHandle);
        bool result = pair->fMeasure.getSegment(startF, stopF, dst, startWithMoveTo);
        return result ? JNI_TRUE : JNI_FALSE;
    }

    static jboolean isClosed(JNIEnv* env, jobject clazz, jlong pairHandle) {
        PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
        bool result = pair->fMeasure.isClosed();
        return result ? JNI_TRUE : JNI_FALSE;
    }

    static jboolean nextContour(JNIEnv* env, jobject clazz, jlong pairHandle) {
        PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
        bool result = pair->fMeasure.nextContour();
        return result ? JNI_TRUE : JNI_FALSE;
    }

    static void destroy(JNIEnv* env, jobject clazz, jlong pairHandle) {
        PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
        delete pair;
    } 
};

static const JNINativeMethod methods[] = {
    {"native_create",       "(JZ)J",        (void*) SkPathMeasureGlue::create      },
    {"native_setPath",      "(JJZ)V",       (void*) SkPathMeasureGlue::setPath     },
    {"native_getLength",    "(J)F",         (void*) SkPathMeasureGlue::getLength   },
    {"native_getPosTan",    "(JF[F[F)Z",    (void*) SkPathMeasureGlue::getPosTan   },
    {"native_getMatrix",    "(JFJI)Z",      (void*) SkPathMeasureGlue::getMatrix   },
    {"native_getSegment",   "(JFFJZ)Z",     (void*) SkPathMeasureGlue::getSegment  },
    {"native_isClosed",     "(J)Z",         (void*) SkPathMeasureGlue::isClosed    },
    {"native_nextContour",  "(J)Z",         (void*) SkPathMeasureGlue::nextContour },
    {"native_destroy",      "(J)V",         (void*) SkPathMeasureGlue::destroy     }
};

int register_android_graphics_PathMeasure(JNIEnv* env) {
    return RegisterMethodsOrDie(env, "android/graphics/PathMeasure", methods, NELEM(methods));
}

}
