/*
 * Copyright 2021 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <jni.h>

#include <string>
#include "include/core/SkBlendMode.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkTileMode.h"

namespace jetski {
namespace utils {

// RAII helper for jstring -> cstring conversions
class CString {
public:
    CString(JNIEnv* env, const jstring& jstr)
        : fEnv(env)
        , fJString(jstr)
        , fCString(env->GetStringUTFChars(jstr, nullptr))
    {}

    ~CString() {
        fEnv->ReleaseStringUTFChars(fJString, fCString);
    }

    const char* str() const { return fCString; }
    operator const char*() const { return fCString; }

private:
    JNIEnv*        fEnv;
    const jstring& fJString;
    const char*    fCString;

    CString(CString&&) = delete;
    CString(const CString&) = delete;
    CString& operator=(CString&&) = delete;
    CString& operator=(const CString&) = delete;
};

// RAII helper for jstring -> u16String conversions
class U16String {
public:
    U16String(JNIEnv* env, const jstring& jstr)
        : fEnv(env)
        , fJString(jstr)
        , fU16String(env->GetStringChars(jstr, nullptr))
    {}

    ~U16String() {
        fEnv->ReleaseStringChars(fJString, fU16String);
    }

    operator const char16_t*() const { return reinterpret_cast<const char16_t*>(fU16String); }

private:
    JNIEnv*        fEnv;
    const jstring& fJString;
    const jchar*   fU16String;


    U16String(U16String&&) = delete;
    U16String(const U16String&) = delete;
    U16String& operator=(U16String&&) = delete;
    U16String& operator=(const U16String&) = delete;
};

// RAII helper for float array access
class CFloats {
public:
    CFloats(JNIEnv* env, const jfloatArray& jfloats)
        : fEnv(env)
        , fJFloats(jfloats)
        , fCFloats(env->GetFloatArrayElements(jfloats, nullptr))
    {}

    ~CFloats() {
        fEnv->ReleaseFloatArrayElements(fJFloats, fCFloats, 0);
    }

    operator const float*() const { return fCFloats; }

private:
    JNIEnv*            fEnv;
    const jfloatArray& fJFloats;
    float*             fCFloats;


    CFloats(CFloats&&) = delete;
    CFloats(const CFloats&) = delete;
    CFloats& operator=(CFloats&&) = delete;
    CFloats& operator=(const CFloats&) = delete;
};

SkSamplingOptions SamplingOptions(jint, jfloat, jfloat);
SkTileMode TileMode(jint);
SkBlendMode BlendMode(jint);

} // namespace utils
} // namespace jetski
