/*
 * 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 "include/core/SkColorFilter.h"
#include "include/core/SkPaint.h"
#include "include/core/SkShader.h"
#include "include/effects/SkImageFilters.h"

namespace {

static jlong Paint_Create(JNIEnv*, jobject) {
    return reinterpret_cast<jlong>(new SkPaint);
}

static void Paint_Release(JNIEnv*, jobject, jlong native_paint) {
    delete reinterpret_cast<SkPaint*>(native_paint);
}

static void Paint_SetColor(JNIEnv*, jobject, jlong native_paint,
                           float r, float g, float b, float a) {
    if (auto* paint = reinterpret_cast<SkPaint*>(native_paint)) {
        paint->setColor4f({r, g, b, a});
    }
}

static void Paint_SetStroke(JNIEnv*, jobject, jlong native_paint, jboolean stroke) {
    if (auto* paint = reinterpret_cast<SkPaint*>(native_paint)) {
        paint->setStroke(stroke);
    }
}

static void Paint_SetStrokeWidth(JNIEnv*, jobject, jlong native_paint, jfloat width) {
    if (auto* paint = reinterpret_cast<SkPaint*>(native_paint)) {
        paint->setStrokeWidth(width);
    }
}

static void Paint_SetStrokeCap(JNIEnv* env, jobject, jlong native_paint, jint native_cap) {
    if (auto* paint = reinterpret_cast<SkPaint*>(native_paint)) {
        switch (native_cap)
        {
        case 0:
            paint->setStrokeCap(SkPaint::kButt_Cap);
            break;
        case 1:
            paint->setStrokeCap(SkPaint::kRound_Cap);
            break;
        case 2:
            paint->setStrokeCap(SkPaint::kSquare_Cap);
            break;
        default:
            break;
        }
    }
}

static void Paint_SetStrokeJoin(JNIEnv* env, jobject, jlong native_paint, jint native_join) {
    if (auto* paint = reinterpret_cast<SkPaint*>(native_paint)) {
        switch (native_join)
        {
        case 0:
            paint->setStrokeJoin(SkPaint::kMiter_Join);
            break;
        case 1:
            paint->setStrokeJoin(SkPaint::kRound_Join);
            break;
        case 2:
            paint->setStrokeJoin(SkPaint::kBevel_Join);
            break;
        default:
            break;
        }
    }
}

static void Paint_SetStrokeMiter(JNIEnv* env, jobject, jlong native_paint, jfloat limit) {
    if (auto* paint = reinterpret_cast<SkPaint*>(native_paint)) {
        paint->setStrokeMiter(limit);
    }
}

static void Paint_SetColorFilter(JNIEnv*, jobject, jlong native_paint, jlong native_cf) {
    if (auto* paint = reinterpret_cast<SkPaint*>(native_paint)) {
        paint->setColorFilter(sk_ref_sp(reinterpret_cast<SkColorFilter*>(native_cf)));
    }
}

static void Paint_SetShader(JNIEnv*, jobject, jlong native_paint, jlong native_shader) {
    if (auto* paint = reinterpret_cast<SkPaint*>(native_paint)) {
        paint->setShader(sk_ref_sp(reinterpret_cast<SkShader*>(native_shader)));
    }
}

static void Paint_SetImageFilter(JNIEnv*, jobject, jlong native_paint, jlong native_filter) {
    if (auto* paint = reinterpret_cast<SkPaint*>(native_paint)) {
        paint->setImageFilter(sk_ref_sp(reinterpret_cast<SkImageFilter*>(native_filter)));
    }
}

}  // namespace

int register_jetski_Paint(JNIEnv* env) {
    static const JNINativeMethod methods[] = {
        {"nCreate"         , "()J"     , reinterpret_cast<void*>(Paint_Create)},
        {"nRelease"        , "(J)V"    , reinterpret_cast<void*>(Paint_Release)},
        {"nSetColor"       , "(JFFFF)V", reinterpret_cast<void*>(Paint_SetColor)},
        {"nSetStroke"      , "(JZ)V"   , reinterpret_cast<void*>(Paint_SetStroke)},
        {"nSetStrokeWidth" , "(JF)V"   , reinterpret_cast<void*>(Paint_SetStrokeWidth)},
        {"nSetStrokeCap"   , "(JI)V"   , reinterpret_cast<void*>(Paint_SetStrokeCap)},
        {"nSetStrokeJoin"  , "(JI)V"   , reinterpret_cast<void*>(Paint_SetStrokeJoin)},
        {"nSetStrokeMiter" , "(JF)V"   , reinterpret_cast<void*>(Paint_SetStrokeMiter)},
        {"nSetColorFilter" , "(JJ)V"   , reinterpret_cast<void*>(Paint_SetColorFilter)},
        {"nSetShader"      , "(JJ)V"   , reinterpret_cast<void*>(Paint_SetShader)},
        {"nSetImageFilter" , "(JJ)V"   , reinterpret_cast<void*>(Paint_SetImageFilter)},
    };

    const auto clazz = env->FindClass("org/skia/jetski/Paint");
    return clazz
        ? env->RegisterNatives(clazz, methods, std::size(methods))
        : JNI_ERR;
}
