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

#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkPoint.h"
#include "include/core/SkPoint3.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/private/SkShadowFlags.h"
#include "include/private/SkTArray.h"
#include "include/private/SkTDArray.h"
#include "include/utils/SkShadowUtils.h"

#include <initializer_list>

void draw_shadow(SkCanvas* canvas, const SkPath& path, SkScalar height, SkColor color,
                 SkPoint3 lightPos, SkScalar lightR, bool isAmbient, uint32_t flags) {
    SkScalar ambientAlpha = isAmbient ? .5f : 0.f;
    SkScalar spotAlpha = isAmbient ? 0.f : .5f;
    SkColor ambientColor = SkColorSetARGB(ambientAlpha*SkColorGetA(color), SkColorGetR(color),
                                          SkColorGetG(color), SkColorGetB(color));
    SkColor spotColor = SkColorSetARGB(spotAlpha*SkColorGetA(color), SkColorGetR(color),
                                       SkColorGetG(color), SkColorGetB(color));
    SkShadowUtils::DrawShadow(canvas, path, SkPoint3{ 0, 0, height}, lightPos, lightR,
                              ambientColor, spotColor, flags);
}

static constexpr int kW = 800;
static constexpr int kH = 960;

enum ShadowMode {
    kDebugColorNoOccluders,
    kDebugColorOccluders,
    kGrayscale
};

void draw_paths(SkCanvas* canvas, ShadowMode mode) {
    SkTArray<SkPath> paths;
    paths.push_back(SkPath::RRect(SkRect::MakeWH(50, 50), 10, 10.00002f));
    SkRRect oddRRect;
    oddRRect.setNinePatch(SkRect::MakeWH(50, 50), 9, 13, 6, 16);
    paths.push_back(SkPath::RRect(oddRRect));
    paths.push_back(SkPath::Rect(SkRect::MakeWH(50, 50)));
    paths.push_back(SkPath::Circle(25, 25, 25));
    paths.push_back(SkPathBuilder().cubicTo(100, 50, 20, 100, 0, 0).detach());
    paths.push_back(SkPath::Oval(SkRect::MakeWH(20, 60)));

    // star
    SkTArray<SkPath> concavePaths;
    concavePaths.push_back().moveTo(0.0f, -33.3333f);
    concavePaths.back().lineTo(9.62f, -16.6667f);
    concavePaths.back().lineTo(28.867f, -16.6667f);
    concavePaths.back().lineTo(19.24f, 0.0f);
    concavePaths.back().lineTo(28.867f, 16.6667f);
    concavePaths.back().lineTo(9.62f, 16.6667f);
    concavePaths.back().lineTo(0.0f, 33.3333f);
    concavePaths.back().lineTo(-9.62f, 16.6667f);
    concavePaths.back().lineTo(-28.867f, 16.6667f);
    concavePaths.back().lineTo(-19.24f, 0.0f);
    concavePaths.back().lineTo(-28.867f, -16.6667f);
    concavePaths.back().lineTo(-9.62f, -16.6667f);
    concavePaths.back().close();

    // dumbbell
    concavePaths.push_back().moveTo(50, 0);
    concavePaths.back().cubicTo(100, 25, 60, 50, 50, 0);
    concavePaths.back().cubicTo(0, -25, 40, -50, 50, 0);

    static constexpr SkScalar kPad = 15.f;
    static constexpr SkScalar kLightR = 100.f;
    static constexpr SkScalar kHeight = 50.f;

    // transform light position relative to canvas to handle tiling
    SkPoint lightXY = canvas->getTotalMatrix().mapXY(250, 400);
    SkPoint3 lightPos = { lightXY.fX, lightXY.fY, 500 };

    canvas->translate(3 * kPad, 3 * kPad);
    canvas->save();
    SkScalar x = 0;
    SkScalar dy = 0;
    SkTDArray<SkMatrix> matrices;
    matrices.push()->reset();
    SkMatrix* m = matrices.push();
    m->setRotate(33.f, 25.f, 25.f);
    m->postScale(1.2f, 0.8f, 25.f, 25.f);
    for (auto& m : matrices) {
        for (int flags : { kNone_ShadowFlag, kTransparentOccluder_ShadowFlag }) {
            int pathCounter = 0;
            for (const auto& path : paths) {
                SkRect postMBounds = path.getBounds();
                m.mapRect(&postMBounds);
                SkScalar w = postMBounds.width() + kHeight;
                SkScalar dx = w + kPad;
                if (x + dx > kW - 3 * kPad) {
                    canvas->restore();
                    canvas->translate(0, dy);
                    canvas->save();
                    x = 0;
                    dy = 0;
                }

                canvas->save();
                canvas->concat(m);

                // flip a couple of paths to test 180° rotation
                if (kTransparentOccluder_ShadowFlag == flags && 0 == pathCounter % 3) {
                    canvas->save();
                    canvas->rotate(180, 25, 25);
                }
                if (kDebugColorNoOccluders == mode || kDebugColorOccluders == mode) {
                    draw_shadow(canvas, path, kHeight, SK_ColorRED, lightPos, kLightR,
                                true, flags);
                    draw_shadow(canvas, path, kHeight, SK_ColorBLUE, lightPos, kLightR,
                                false, flags);
                } else if (kGrayscale == mode) {
                    SkColor ambientColor = SkColorSetARGB(0.1f * 255, 0, 0, 0);
                    SkColor spotColor = SkColorSetARGB(0.25f * 255, 0, 0, 0);
                    SkShadowUtils::DrawShadow(canvas, path, SkPoint3{0, 0, kHeight}, lightPos,
                                              kLightR, ambientColor, spotColor, flags);
                }

                SkPaint paint;
                paint.setAntiAlias(true);
                if (kDebugColorNoOccluders == mode) {
                    // Draw the path outline in green on top of the ambient and spot shadows.
                    if (SkToBool(flags & kTransparentOccluder_ShadowFlag)) {
                        paint.setColor(SK_ColorCYAN);
                    } else {
                        paint.setColor(SK_ColorGREEN);
                    }
                    paint.setStyle(SkPaint::kStroke_Style);
                    paint.setStrokeWidth(0);
                } else {
                    paint.setColor(kDebugColorOccluders == mode ? SK_ColorLTGRAY : SK_ColorWHITE);
                    if (SkToBool(flags & kTransparentOccluder_ShadowFlag)) {
                        paint.setAlphaf(0.5f);
                    }
                    paint.setStyle(SkPaint::kFill_Style);
                }
                canvas->drawPath(path, paint);
                if (kTransparentOccluder_ShadowFlag == flags && 0 == pathCounter % 3) {
                    canvas->restore();
                }
                canvas->restore();

                canvas->translate(dx, 0);
                x += dx;
                dy = std::max(dy, postMBounds.height() + kPad + kHeight);
                ++pathCounter;
            }
        }
    }

    // concave paths
    canvas->restore();
    canvas->translate(kPad, dy);
    canvas->save();
    x = kPad;
    dy = 0;
    for (auto& m : matrices) {
        // for the concave paths we are not clipping, so transparent and opaque are the same
        for (const auto& path : concavePaths) {
            SkRect postMBounds = path.getBounds();
            m.mapRect(&postMBounds);
            SkScalar w = postMBounds.width() + kHeight;
            SkScalar dx = w + kPad;

            canvas->save();
            canvas->concat(m);

            if (kDebugColorNoOccluders == mode || kDebugColorOccluders == mode) {
                draw_shadow(canvas, path, kHeight, SK_ColorRED, lightPos, kLightR,
                            true, kNone_ShadowFlag);
                draw_shadow(canvas, path, kHeight, SK_ColorBLUE, lightPos, kLightR,
                            false, kNone_ShadowFlag);
            } else if (kGrayscale == mode) {
                SkColor ambientColor = SkColorSetARGB(0.1f * 255, 0, 0, 0);
                SkColor spotColor = SkColorSetARGB(0.25f * 255, 0, 0, 0);
                SkShadowUtils::DrawShadow(canvas, path, SkPoint3{ 0, 0, kHeight }, lightPos,
                                          kLightR, ambientColor, spotColor, kNone_ShadowFlag);
            }

            SkPaint paint;
            paint.setAntiAlias(true);
            if (kDebugColorNoOccluders == mode) {
                // Draw the path outline in green on top of the ambient and spot shadows.
                paint.setColor(SK_ColorGREEN);
                paint.setStyle(SkPaint::kStroke_Style);
                paint.setStrokeWidth(0);
            } else {
                paint.setColor(kDebugColorOccluders == mode ? SK_ColorLTGRAY : SK_ColorWHITE);
                paint.setStyle(SkPaint::kFill_Style);
            }
            canvas->drawPath(path, paint);
            canvas->restore();

            canvas->translate(dx, 0);
            x += dx;
            dy = std::max(dy, postMBounds.height() + kPad + kHeight);
        }
    }

    // Show where the light is in x,y as a circle (specified in device space).
    SkMatrix invCanvasM = canvas->getTotalMatrix();
    if (invCanvasM.invert(&invCanvasM)) {
        canvas->save();
        canvas->concat(invCanvasM);
        SkPaint paint;
        paint.setColor(SK_ColorBLACK);
        paint.setAntiAlias(true);
        canvas->drawCircle(lightPos.fX, lightPos.fY, kLightR / 10.f, paint);
        canvas->restore();
    }
}

DEF_SIMPLE_GM(shadow_utils, canvas, kW, kH) {
    draw_paths(canvas, kDebugColorNoOccluders);
}

DEF_SIMPLE_GM(shadow_utils_occl, canvas, kW, kH) {
    draw_paths(canvas, kDebugColorOccluders);
}

DEF_SIMPLE_GM(shadow_utils_gray, canvas, kW, kH) {
    draw_paths(canvas, kGrayscale);
}

#include "include/effects/SkGradientShader.h"
#include "src/core/SkColorFilterPriv.h"

DEF_SIMPLE_GM(shadow_utils_gaussian_colorfilter, canvas, 512, 256) {
    const SkRect r = SkRect::MakeWH(256, 256);

    const SkColor colors[] = { 0, 0xFF000000 };
    auto sh = SkGradientShader::MakeRadial({r.centerX(), r.centerY()}, r.width(),
                                           colors, nullptr, SK_ARRAY_COUNT(colors),
                                           SkTileMode::kClamp);

    SkPaint redPaint;
    redPaint.setColor(SK_ColorRED);

    SkPaint paint;
    paint.setShader(sh);
    canvas->drawRect(r, redPaint);
    canvas->drawRect(r, paint);

    canvas->translate(256, 0);
    paint.setColorFilter(SkColorFilterPriv::MakeGaussian());
    canvas->drawRect(r, redPaint);
    canvas->drawRect(r, paint);
}

DEF_SIMPLE_GM(shadow_utils_directional, canvas, 256, 384) {
    static constexpr SkScalar kLightR = 1.f;
    static constexpr SkScalar kHeight = 12.f;

    SkPath rrect(SkPath::RRect(SkRect::MakeLTRB(-25, -25, 25, 25), 10, 10));
    SkPoint3 lightPos = { -45, -45, 77.9422863406f };

    SkColor ambientColor = SkColorSetARGB(0.02f * 255, 0, 0, 0);
    SkColor spotColor = SkColorSetARGB(0.35f * 255, 0, 0, 0);

    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setColor(SK_ColorWHITE);
    paint.setStyle(SkPaint::kFill_Style);

    // translation
    canvas->save();
    canvas->translate(35, 35);
    for (int i = 0; i < 3; ++i) {
        SkShadowUtils::DrawShadow(canvas, rrect, SkPoint3{ 0, 0, kHeight }, lightPos,
                                  kLightR, ambientColor, spotColor,
                                  kDirectionalLight_ShadowFlag);
        canvas->drawPath(rrect, paint);
        canvas->translate(80, 0);
    }
    canvas->restore();

    // rotation
    for (int i = 0; i < 3; ++i) {
        canvas->save();
        canvas->translate(35 + 80*i, 105);
        canvas->rotate(20.f*(i + 1));
        SkShadowUtils::DrawShadow(canvas, rrect, SkPoint3{ 0, 0, kHeight }, lightPos,
                                  kLightR, ambientColor, spotColor,
                                  kDirectionalLight_ShadowFlag);

        canvas->drawPath(rrect, paint);
        canvas->restore();
    }

    // scale
    for (int i = 0; i < 3; ++i) {
        canvas->save();
        SkScalar scaleFactor = sk_float_pow(2.0, -i);
        canvas->translate(35 + 80*i, 185);
        canvas->scale(scaleFactor, scaleFactor);
        SkShadowUtils::DrawShadow(canvas, rrect, SkPoint3{ 0, 0, kHeight }, lightPos,
                                  kLightR, ambientColor, spotColor,
                                  kDirectionalLight_ShadowFlag);

        canvas->drawPath(rrect, paint);
        canvas->restore();
    }

    // perspective
    for (int i = 0; i < 3; ++i) {
        canvas->save();
        SkMatrix mat;
        mat.reset();
        mat[SkMatrix::kMPersp1] = 0.005f;
        mat[SkMatrix::kMPersp2] = 1.005f;
        canvas->translate(35 + 80*i, 265);
        canvas->concat(mat);
        SkShadowUtils::DrawShadow(canvas, rrect, SkPoint3{ 0, 0, kHeight }, lightPos,
                                  kLightR, ambientColor, spotColor,
                                  kDirectionalLight_ShadowFlag);

        canvas->drawPath(rrect, paint);
        canvas->restore();
    }

}
