/*
 * 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();
    matrices.push()->setRotate(33.f, 25.f, 25.f).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();
    }

}
