/*
 * Copyright 2012 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/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint3.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/effects/SkImageFilters.h"
#include "tools/ToolUtils.h"
#include "tools/timer/TimeUtils.h"

#define WIDTH 660
#define HEIGHT 660

namespace skiagm {

class ImageLightingGM : public GM {
public:
    ImageLightingGM()
        : fAzimuth(SkIntToScalar(kStartAzimuth)) {
        this->setBGColor(0xFF000000);
    }

protected:

    SkString onShortName() override {
        return SkString("lighting");
    }

    SkISize onISize() override {
        return SkISize::Make(WIDTH, HEIGHT);
    }

    void drawClippedBitmap(SkCanvas* canvas, const SkPaint& paint, int x, int y) {
        canvas->save();
        canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
        canvas->clipIRect(fBitmap.bounds());
        canvas->drawImage(fBitmap.asImage(), 0, 0, SkSamplingOptions(), &paint);
        canvas->restore();
    }

    void onOnceBeforeDraw() override {
        fBitmap = ToolUtils::create_string_bitmap(100, 100, 0xFFFFFFFF, 20, 70, 96, "e");
    }

    void onDraw(SkCanvas* canvas) override {
        canvas->clear(0xFF101010);
        SkPaint checkPaint;
        checkPaint.setColor(0xFF202020);
        for (int y = 0; y < HEIGHT; y += 16) {
          for (int x = 0; x < WIDTH; x += 16) {
            canvas->save();
            canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
            canvas->drawRect(SkRect::MakeXYWH(8, 0, 8, 8), checkPaint);
            canvas->drawRect(SkRect::MakeXYWH(0, 8, 8, 8), checkPaint);
            canvas->restore();
          }
        }
        SkScalar sinAzimuth = SkScalarSin(SkDegreesToRadians(fAzimuth)),
                 cosAzimuth = SkScalarCos(SkDegreesToRadians(fAzimuth));

        SkPoint3 spotTarget = SkPoint3::Make(SkIntToScalar(40), SkIntToScalar(40), 0);
        SkPoint3 spotLocation = SkPoint3::Make(spotTarget.fX + 70.7214f * cosAzimuth,
                                               spotTarget.fY + 70.7214f * sinAzimuth,
                                               spotTarget.fZ + SkIntToScalar(20));
        SkScalar spotExponent1 = SK_Scalar1;
        SkScalar spotExponent10 = SkIntToScalar(10);
        SkScalar cutoffAngleSmall = SkIntToScalar(15);
        SkScalar cutoffAngleNone = SkIntToScalar(180);

        SkPoint3 pointLocation = SkPoint3::Make(spotTarget.fX + 50 * cosAzimuth,
                                                spotTarget.fY + 50 * sinAzimuth,
                                                SkIntToScalar(10));
        SkScalar elevationRad = SkDegreesToRadians(SkIntToScalar(5));

        SkPoint3 distantDirection = SkPoint3::Make(cosAzimuth * SkScalarCos(elevationRad),
                                                   sinAzimuth * SkScalarCos(elevationRad),
                                                   SkScalarSin(elevationRad));
        SkScalar kd = SkIntToScalar(2);
        SkScalar ks = SkIntToScalar(1);
        SkScalar shininess = SkIntToScalar(8);
        SkScalar surfaceScale = SkIntToScalar(1);
        SkScalar surfaceScaleSmall = 0.1f;
        SkColor greenYellow = SkColorSetARGB(255, 173, 255, 47);
        SkPaint paint;

        SkIRect cropRect = SkIRect::MakeXYWH(20, 10, 60, 65);
        SkIRect fullSizeCropRect = SkIRect::MakeXYWH(0, 0, 100, 100);
        sk_sp<SkImageFilter> noopCropped(SkImageFilters::Offset(0, 0, nullptr, &cropRect));

        int y = 0;
        for (int i = 0; i < 3; i++) {
            const SkIRect* cr = (i == 1) ? &cropRect : (i == 2) ? &fullSizeCropRect : nullptr;
            sk_sp<SkImageFilter> input = (i == 2) ? noopCropped : nullptr;
            // Basic point, distant and spot lights with diffuse lighting
            paint.setImageFilter(SkImageFilters::PointLitDiffuse(
                    pointLocation, SK_ColorWHITE, surfaceScale, kd, input, cr));
            drawClippedBitmap(canvas, paint, 0, y);

            paint.setImageFilter(SkImageFilters::DistantLitDiffuse(
                    distantDirection, SK_ColorWHITE, surfaceScale, kd, input, cr));
            drawClippedBitmap(canvas, paint, 110, y);

            paint.setImageFilter(SkImageFilters::SpotLitDiffuse(
                    spotLocation, spotTarget, spotExponent1, cutoffAngleSmall, SK_ColorWHITE,
                    surfaceScale, kd, input, cr));
            drawClippedBitmap(canvas, paint, 220, y);

            // Spot light with no angle cutoff
            paint.setImageFilter(SkImageFilters::SpotLitDiffuse(
                    spotLocation, spotTarget, spotExponent10, cutoffAngleNone, SK_ColorWHITE,
                    surfaceScale, kd,  input, cr));
            drawClippedBitmap(canvas, paint, 330, y);

            // Spot light with falloff exponent
            paint.setImageFilter(SkImageFilters::SpotLitDiffuse(
                    spotLocation, spotTarget, spotExponent1, cutoffAngleNone, SK_ColorWHITE,
                    surfaceScaleSmall, kd, input, cr));
            drawClippedBitmap(canvas, paint, 440, y);

            // Large constant to show oversaturation
            paint.setImageFilter(SkImageFilters::DistantLitDiffuse(
                    distantDirection, greenYellow, surfaceScale, 4.f * kd, input, cr));
            drawClippedBitmap(canvas, paint, 550, y);

            y += 110;

            // Basic point, distant and spot lights with specular lighting
            paint.setImageFilter(SkImageFilters::PointLitSpecular(
                    pointLocation, SK_ColorWHITE, surfaceScale, ks, shininess, input, cr));
            drawClippedBitmap(canvas, paint, 0, y);

            paint.setImageFilter(SkImageFilters::DistantLitSpecular(
                    distantDirection, SK_ColorWHITE, surfaceScale, ks, shininess, input, cr));
            drawClippedBitmap(canvas, paint, 110, y);

            paint.setImageFilter(SkImageFilters::SpotLitSpecular(
                    spotLocation, spotTarget, spotExponent1, cutoffAngleSmall, SK_ColorWHITE,
                    surfaceScale, ks, shininess, input, cr));
            drawClippedBitmap(canvas, paint, 220, y);

            // Spot light with no angle cutoff
            paint.setImageFilter(SkImageFilters::SpotLitSpecular(
                    spotLocation, spotTarget, spotExponent10, cutoffAngleNone, SK_ColorWHITE,
                    surfaceScale, ks,  shininess, input, cr));
            drawClippedBitmap(canvas, paint, 330, y);

            // Spot light with falloff exponent
            paint.setImageFilter(SkImageFilters::SpotLitSpecular(
                    spotLocation, spotTarget, spotExponent1, cutoffAngleNone, SK_ColorWHITE,
                    surfaceScaleSmall, ks, shininess, input, cr));
            drawClippedBitmap(canvas, paint, 440, y);

            // Large constant to show oversaturation
            paint.setImageFilter(SkImageFilters::DistantLitSpecular(
                    distantDirection, greenYellow, surfaceScale, 4.f * ks, shininess, input, cr));
            drawClippedBitmap(canvas, paint, 550, y);

            y += 110;
        }
    }

    bool onAnimate(double nanos) override {
        constexpr SkScalar kDesiredDurationSecs = 15.0f;

        fAzimuth = kStartAzimuth + TimeUtils::Scaled(1e-9 * nanos, 360.0f/kDesiredDurationSecs, 360.0f);
        return true;
    }

private:
    inline static constexpr int kStartAzimuth = 225;

    SkBitmap fBitmap;
    SkScalar fAzimuth;

    using INHERITED = GM;
};

//////////////////////////////////////////////////////////////////////////////

DEF_GM(return new ImageLightingGM;)
}  // namespace skiagm
