#ifndef _ANDROID_GRAPHICS_GRAPHICS_JNI_H_
#define _ANDROID_GRAPHICS_GRAPHICS_JNI_H_

#include <cutils/compiler.h>
#include <hwui/Bitmap.h>
#include <hwui/Canvas.h>

#include "BRDAllocator.h"
#include "Bitmap.h"
#include "SkBitmap.h"
#include "SkCodec.h"
#include "SkColorSpace.h"
#include "SkMallocPixelRef.h"
#include "SkPixelRef.h"
#include "SkPoint.h"
#include "SkRect.h"
#include "graphics_jni_helpers.h"

class SkCanvas;
struct SkFontMetrics;

namespace android {
class BitmapRegionDecoderWrapper;
class Canvas;
class Paint;
struct Typeface;
}

class GraphicsJNI {
public:
    // This enum must keep these int values, to match the int values
    // in the java Bitmap.Config enum.
    enum LegacyBitmapConfig {
        kNo_LegacyBitmapConfig = 0,
        kA8_LegacyBitmapConfig = 1,
        kIndex8_LegacyBitmapConfig = 2,
        kRGB_565_LegacyBitmapConfig = 3,
        kARGB_4444_LegacyBitmapConfig = 4,
        kARGB_8888_LegacyBitmapConfig = 5,
        kRGBA_16F_LegacyBitmapConfig = 6,
        kHardware_LegacyBitmapConfig = 7,
        kRGBA_1010102_LegacyBitmapConfig = 8,

        kLastEnum_LegacyBitmapConfig = kRGBA_1010102_LegacyBitmapConfig
    };

    static void setJavaVM(JavaVM* javaVM);

    /**
     * returns a pointer to the JavaVM provided when we initialized the module
     * DEPRECATED: Objects should know the JavaVM that created them
     */
    static JavaVM* getJavaVM() { return mJavaVM; }

    /**
     * return a pointer to the JNIEnv for this thread
     * DEPRECATED: Objects should know the JavaVM that created them
     */
    static JNIEnv* getJNIEnv();

    /** create a JNIEnv* for this thread or assert if one already exists */
    static JNIEnv* attachJNIEnv(const char* envName);

    /** detach the current thread from the JavaVM */
    static void detachJNIEnv();

    // returns true if an exception is set (and dumps it out to the Log)
    static bool hasException(JNIEnv*);

    static void get_jrect(JNIEnv*, jobject jrect, int* L, int* T, int* R, int* B);
    static void set_jrect(JNIEnv*, jobject jrect, int L, int T, int R, int B);

    static SkIRect* jrect_to_irect(JNIEnv*, jobject jrect, SkIRect*);
    static void irect_to_jrect(const SkIRect&, JNIEnv*, jobject jrect);

    static SkRect* jrectf_to_rect(JNIEnv*, jobject jrectf, SkRect*);
    static SkRect* jrect_to_rect(JNIEnv*, jobject jrect, SkRect*);
    static void rect_to_jrectf(const SkRect&, JNIEnv*, jobject jrectf);

    static void set_cluster_count_to_run_info(JNIEnv* env, jobject runInfo, jint clusterCount);

    static void set_jpoint(JNIEnv*, jobject jrect, int x, int y);

    static SkIPoint* jpoint_to_ipoint(JNIEnv*, jobject jpoint, SkIPoint* point);
    static void ipoint_to_jpoint(const SkIPoint& point, JNIEnv*, jobject jpoint);

    static SkPoint* jpointf_to_point(JNIEnv*, jobject jpointf, SkPoint* point);
    static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);

    ANDROID_API static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas);
    static android::Bitmap* getNativeBitmap(JNIEnv*, jobject bitmap);
    static SkImageInfo getBitmapInfo(JNIEnv*, jobject bitmap, uint32_t* outRowBytes,
                                     bool* isHardware);
    static SkRegion* getNativeRegion(JNIEnv*, jobject region);

    /**
     * Set SkFontMetrics to Java Paint.FontMetrics.
     * Do nothing if metrics is nullptr.
     */
    static void set_metrics(JNIEnv*, jobject metrics, const SkFontMetrics& skmetrics);
    /**
     * Set SkFontMetrics to Java Paint.FontMetricsInt and return recommended interline space.
     * Do nothing if metrics is nullptr.
     */
    static int set_metrics_int(JNIEnv*, jobject metrics, const SkFontMetrics& skmetrics);

    /*
     *  LegacyBitmapConfig is the old enum in Skia that matched the enum int values
     *  in Bitmap.Config. Skia no longer supports this config, but has replaced it
     *  with SkColorType. These routines convert between the two.
     */
    static SkColorType legacyBitmapConfigToColorType(jint legacyConfig);
    static jint colorTypeToLegacyBitmapConfig(SkColorType colorType);

    /** Return the corresponding native colorType from the java Config enum,
        or kUnknown_SkColorType if the java object is null.
    */
    static SkColorType getNativeBitmapColorType(JNIEnv*, jobject jconfig);
    static AndroidBitmapFormat getFormatFromConfig(JNIEnv* env, jobject jconfig);
    static jobject getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format);

    static bool isHardwareConfig(JNIEnv* env, jobject jconfig);
    static jint hardwareLegacyBitmapConfig();

    static jobject createRegion(JNIEnv* env, SkRegion* region);

    static jobject createBitmapRegionDecoder(JNIEnv* env,
                                             android::BitmapRegionDecoderWrapper* bitmap);

    /** Copy the colors in colors[] to the bitmap, convert to the correct
        format along the way.
        Whether to use premultiplied pixels is determined by dstBitmap's alphaType.
    */
    static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset,
            int srcStride, int x, int y, int width, int height,
            SkBitmap* dstBitmap);

    /**
     * Convert the native SkColorSpace retrieved from ColorSpace.Rgb.getNativeInstance().
     *
     * This will never throw an Exception. If the ColorSpace is one that Skia cannot
     * use, ColorSpace.Rgb.getNativeInstance() would have thrown an Exception. It may,
     * however, be nullptr, which may be acceptable.
     */
    static sk_sp<SkColorSpace> getNativeColorSpace(jlong colorSpaceHandle);

    /**
     * Return the android.graphics.ColorSpace Java object that corresponds to decodeColorSpace
     * and decodeColorType.
     *
     * This may create a new object if none of the Named ColorSpaces match.
     */
    static jobject getColorSpace(JNIEnv* env, SkColorSpace* decodeColorSpace,
            SkColorType decodeColorType);

    /**
     * Convert from a Java @ColorLong to an SkColor4f that Skia can use directly.
     *
     * This ignores the encoded ColorSpace, besides checking to see if it is sRGB,
     * which is encoded differently. The color space should be passed down separately
     * via ColorSpace#getNativeInstance(), and converted with getNativeColorSpace(),
     * above.
     */
    static SkColor4f convertColorLong(jlong color);

private:
    /* JNI JavaVM pointer */
    static JavaVM* mJavaVM;
};

class HeapAllocator : public android::skia::BRDAllocator {
public:
   HeapAllocator() { };
    ~HeapAllocator() { };

    virtual bool allocPixelRef(SkBitmap* bitmap) override;

    /**
     * Fetches the backing allocation object. Must be called!
     */
    android::Bitmap* getStorageObjAndReset() {
        return mStorage.release();
    };

    SkCodec::ZeroInitialized zeroInit() const override { return SkCodec::kYes_ZeroInitialized; }
private:
    sk_sp<android::Bitmap> mStorage;
};

/**
 *  Allocator to handle reusing bitmaps for BitmapRegionDecoder.
 *
 *  The BitmapRegionDecoder documentation states that, if it is
 *  provided, the recycled bitmap will always be reused, clipping
 *  the decoded output to fit in the recycled bitmap if necessary.
 *  This allocator implements that behavior.
 *
 *  Skia's BitmapRegionDecoder expects the memory that
 *  is allocated to be large enough to decode the entire region
 *  that is requested.  It will decode directly into the memory
 *  that is provided.
 *
 *  FIXME: BUG:25465958
 *  If the recycled bitmap is not large enough for the decode
 *  requested, meaning that a clip is required, we will allocate
 *  enough memory for Skia to perform the decode, and then copy
 *  from the decoded output into the recycled bitmap.
 *
 *  If the recycled bitmap is large enough for the decode requested,
 *  we will provide that memory for Skia to decode directly into.
 *
 *  This allocator should only be used for a single allocation.
 *  After we reuse the recycledBitmap once, it is dangerous to
 *  reuse it again, given that it still may be in use from our
 *  first allocation.
 */
class RecyclingClippingPixelAllocator : public android::skia::BRDAllocator {
public:
    RecyclingClippingPixelAllocator(android::Bitmap* recycledBitmap,
                                    bool mustMatchColorType = true);

    ~RecyclingClippingPixelAllocator();

    virtual bool allocPixelRef(SkBitmap* bitmap) override;

    /**
     *  Must be called!
     *
     *  In the event that the recycled bitmap is not large enough for
     *  the allocation requested, we will allocate memory on the heap
     *  instead.  As a final step, once we are done using this memory,
     *  we will copy the contents of the heap memory into the recycled
     *  bitmap's memory, clipping as necessary.
     */
    void copyIfNecessary();

    /**
     *  Indicates that this allocator does not allocate zero initialized
     *  memory.
     */
    SkCodec::ZeroInitialized zeroInit() const override { return SkCodec::kNo_ZeroInitialized; }

private:
    android::Bitmap* mRecycledBitmap;
    const size_t     mRecycledBytes;
    SkBitmap*        mSkiaBitmap;
    bool             mNeedsCopy;
    const bool mMustMatchColorType;
};

class AshmemPixelAllocator : public SkBitmap::Allocator {
public:
    explicit AshmemPixelAllocator(JNIEnv* env);
    ~AshmemPixelAllocator() { };
    virtual bool allocPixelRef(SkBitmap* bitmap);
    android::Bitmap* getStorageObjAndReset() {
        return mStorage.release();
    };

private:
    JavaVM* mJavaVM;
    sk_sp<android::Bitmap> mStorage;
};


enum JNIAccess {
    kRO_JNIAccess,
    kRW_JNIAccess
};

class AutoJavaFloatArray {
public:
    AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
                       int minLength = 0, JNIAccess = kRW_JNIAccess);
    ~AutoJavaFloatArray();

    float* ptr() const { return fPtr; }
    int    length() const { return fLen; }

private:
    JNIEnv*     fEnv;
    jfloatArray fArray;
    float*      fPtr;
    int         fLen;
    int         fReleaseMode;
};

class AutoJavaIntArray {
public:
    AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0);
    ~AutoJavaIntArray();

    jint* ptr() const { return fPtr; }
    int    length() const { return fLen; }

private:
    JNIEnv*     fEnv;
    jintArray fArray;
    jint*      fPtr;
    int         fLen;
};

class AutoJavaShortArray {
public:
    AutoJavaShortArray(JNIEnv* env, jshortArray array,
                       int minLength = 0, JNIAccess = kRW_JNIAccess);
    ~AutoJavaShortArray();

    jshort* ptr() const { return fPtr; }
    int    length() const { return fLen; }

private:
    JNIEnv*     fEnv;
    jshortArray fArray;
    jshort*      fPtr;
    int         fLen;
    int         fReleaseMode;
};

class AutoJavaByteArray {
public:
    AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0);
    ~AutoJavaByteArray();

    jbyte* ptr() const { return fPtr; }
    int    length() const { return fLen; }

private:
    JNIEnv*     fEnv;
    jbyteArray fArray;
    jbyte*      fPtr;
    int         fLen;
};

class JGlobalRefHolder {
public:
    JGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm), mObject(object) {}

    virtual ~JGlobalRefHolder() {
        env()->DeleteGlobalRef(mObject);
        mObject = nullptr;
    }

    jobject object() { return mObject; }
    JavaVM* vm() { return mVm; }

    JNIEnv* env() {
        JNIEnv* env;
        if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
            LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", mVm);
        }
        return env;
    }

private:
    JGlobalRefHolder(const JGlobalRefHolder&) = delete;
    void operator=(const JGlobalRefHolder&) = delete;

    JavaVM* mVm;
    jobject mObject;
};

void doThrowNPE(JNIEnv* env);
void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception
void doThrowIAE(JNIEnv* env, const char* msg = NULL);   // Illegal Argument
void doThrowRE(JNIEnv* env, const char* msg = NULL);   // Runtime
void doThrowISE(JNIEnv* env, const char* msg = NULL);   // Illegal State
void doThrowOOME(JNIEnv* env, const char* msg = NULL);   // Out of memory
void doThrowIOE(JNIEnv* env, const char* msg = NULL);   // IO Exception

#define NPE_CHECK_RETURN_ZERO(env, object)    \
    do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0)

#define NPE_CHECK_RETURN_VOID(env, object)    \
    do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0)

#endif  // _ANDROID_GRAPHICS_GRAPHICS_JNI_H_
