#include "jni.h"
#include <android_runtime/AndroidRuntime.h>

#include "GraphicsJNI.h"
#include "SkStream.h"
#include "SkTypeface.h"
#include <android_runtime/android_util_AssetManager.h>
#include <androidfw/AssetManager.h>

using namespace android;

class AutoJavaStringToUTF8 {
public:
    AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str)
    {
        fCStr = env->GetStringUTFChars(str, NULL);
    }
    ~AutoJavaStringToUTF8()
    {
        fEnv->ReleaseStringUTFChars(fJStr, fCStr);
    }
    const char* c_str() const { return fCStr; }

private:
    JNIEnv*     fEnv;
    jstring     fJStr;
    const char* fCStr;
};

static jlong Typeface_create(JNIEnv* env, jobject, jstring name,
                             jint styleHandle) {
    SkTypeface::Style style = static_cast<SkTypeface::Style>(styleHandle);
    SkTypeface* face = NULL;

    if (NULL != name) {
        AutoJavaStringToUTF8    str(env, name);
        face = SkTypeface::CreateFromName(str.c_str(), style);
        // Try to find the closest matching font, using the standard heuristic
        if (NULL == face) {
            face = SkTypeface::CreateFromName(str.c_str(), (SkTypeface::Style)(style ^ SkTypeface::kItalic));
        }
        for (int i = 0; NULL == face && i < 4; i++) {
            face = SkTypeface::CreateFromName(str.c_str(), (SkTypeface::Style)i);
        }
    }

    // return the default font at the best style if no exact match exists
    if (NULL == face) {
        face = SkTypeface::CreateFromName(NULL, style);
    }
    return reinterpret_cast<jlong>(face);
}

static jlong Typeface_createFromTypeface(JNIEnv* env, jobject, jlong familyHandle, jint style) {
    SkTypeface* family = reinterpret_cast<SkTypeface*>(familyHandle);
    SkTypeface* face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)style);
    // Try to find the closest matching font, using the standard heuristic
    if (NULL == face) {
        face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)(style ^ SkTypeface::kItalic));
    }
    for (int i = 0; NULL == face && i < 4; i++) {
        face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)i);
    }
    if (NULL == face) {
        face = SkTypeface::CreateFromName(NULL, (SkTypeface::Style)style);
    }
    return reinterpret_cast<jlong>(face);
}

static void Typeface_unref(JNIEnv* env, jobject obj, jlong faceHandle) {
    SkTypeface* face = reinterpret_cast<SkTypeface*>(faceHandle);
    SkSafeUnref(face);
}

static jint Typeface_getStyle(JNIEnv* env, jobject obj, jlong faceHandle) {
    SkTypeface* face = reinterpret_cast<SkTypeface*>(faceHandle);
    return static_cast<jint>(face->style());
}

class AssetStream : public SkStream {
public:
    AssetStream(Asset* asset, bool hasMemoryBase) : fAsset(asset)
    {
        fMemoryBase = hasMemoryBase ? fAsset->getBuffer(false) : NULL;
    }

    virtual ~AssetStream()
    {
        delete fAsset;
    }

    virtual const void* getMemoryBase()
    {
        return fMemoryBase;
    }

	virtual bool rewind()
    {
        off64_t pos = fAsset->seek(0, SEEK_SET);
        return pos != (off64_t)-1;
    }

	virtual size_t read(void* buffer, size_t size)
    {
        ssize_t amount;

        if (NULL == buffer)
        {
            if (0 == size)  // caller is asking us for our total length
                return fAsset->getLength();

            // asset->seek returns new total offset
            // we want to return amount that was skipped

            off64_t oldOffset = fAsset->seek(0, SEEK_CUR);
            if (-1 == oldOffset)
                return 0;
            off64_t newOffset = fAsset->seek(size, SEEK_CUR);
            if (-1 == newOffset)
                return 0;

            amount = newOffset - oldOffset;
        }
        else
        {
            amount = fAsset->read(buffer, size);
        }

        if (amount < 0)
            amount = 0;
        return amount;
    }

private:
    Asset*      fAsset;
    const void* fMemoryBase;
};

static jlong Typeface_createFromAsset(JNIEnv* env, jobject,
                                      jobject jassetMgr,
                                      jstring jpath) {

    NPE_CHECK_RETURN_ZERO(env, jassetMgr);
    NPE_CHECK_RETURN_ZERO(env, jpath);

    AssetManager* mgr = assetManagerForJavaObject(env, jassetMgr);
    if (NULL == mgr) {
        return NULL;
    }

    AutoJavaStringToUTF8    str(env, jpath);
    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
    if (NULL == asset) {
        return NULL;
    }

    SkStream* stream = new AssetStream(asset, true);
    SkTypeface* face = SkTypeface::CreateFromStream(stream);
    // SkTypeFace::CreateFromStream calls ref() on the stream, so we
    // need to unref it here or it won't be freed later on
    stream->unref();

    return reinterpret_cast<jlong>(face);
}

static jlong Typeface_createFromFile(JNIEnv* env, jobject, jstring jpath) {
    NPE_CHECK_RETURN_ZERO(env, jpath);

    AutoJavaStringToUTF8 str(env, jpath);

    return reinterpret_cast<jlong>(SkTypeface::CreateFromFile(str.c_str()));
}

///////////////////////////////////////////////////////////////////////////////

static JNINativeMethod gTypefaceMethods[] = {
    { "nativeCreate",        "(Ljava/lang/String;I)J", (void*)Typeface_create },
    { "nativeCreateFromTypeface", "(JI)J", (void*)Typeface_createFromTypeface },
    { "nativeUnref",              "(J)V",  (void*)Typeface_unref },
    { "nativeGetStyle",           "(J)I",  (void*)Typeface_getStyle },
    { "nativeCreateFromAsset",    "(Landroid/content/res/AssetManager;Ljava/lang/String;)J",
                                           (void*)Typeface_createFromAsset },
    { "nativeCreateFromFile",     "(Ljava/lang/String;)J",
                                           (void*)Typeface_createFromFile },
};

int register_android_graphics_Typeface(JNIEnv* env)
{
    return android::AndroidRuntime::registerNativeMethods(env,
                                                       "android/graphics/Typeface",
                                                       gTypefaceMethods,
                                                       SK_ARRAY_COUNT(gTypefaceMethods));
}
