/*
 * Copyright 2016 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/SkFont.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkMatrix.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/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "src/core/SkNormalSource.h"
#include "src/shaders/SkLightingShader.h"
#include "src/shaders/SkLights.h"
#include "tools/ToolUtils.h"

#include <initializer_list>
#include <utility>

// Create a truncated pyramid normal map
static SkBitmap make_frustum_normalmap(int texSize) {
    SkBitmap frustum;
    frustum.allocN32Pixels(texSize, texSize);

    ToolUtils::create_frustum_normal_map(&frustum, SkIRect::MakeWH(texSize, texSize));
    return frustum;
}

namespace skiagm {

// This GM exercises lighting shaders. Specifically, nullptr arguments, scaling when using
// normal maps, paint transparency, zero directional lights, multiple directional lights.
class LightingShader2GM : public GM {
public:
    LightingShader2GM() : fRect(SkRect::MakeIWH(kTexSize, kTexSize)) {
        this->setBGColor(ToolUtils::color_to_565(0xFF0000CC));
    }

protected:
    SkString onShortName() override {
        return SkString("lightingshader2");
    }

    SkISize onISize() override {
        return SkISize::Make(600, 740);
    }

    void onOnceBeforeDraw() override {
        // The light direction is towards the light with +Z coming out of the screen
        const SkVector3 kLightFromUpperRight = SkVector3::Make(0.788f, 0.394f, 0.473f);
        const SkVector3 kLightFromUpperLeft = SkVector3::Make(-0.788f, 0.394f, 0.473f);

        // Standard set of lights
        {
            SkLights::Builder builder;
            builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f),
                                                         kLightFromUpperRight));
            builder.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f));
            fLights = builder.finish();
        }

        // No directional lights
        {
            SkLights::Builder builder;
            builder.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f));
            fLightsNoDir = builder.finish();
        }

        // Two directional lights
        {
            SkLights::Builder builder;
            builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 0.0f, 0.0f),
                                                         kLightFromUpperRight));
            builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(0.0f, 1.0f, 0.0f),
                                                         kLightFromUpperLeft));
            builder.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f));
            fLightsTwoDir = builder.finish();
        }

        SkMatrix matrix;
        SkRect bitmapBounds = SkRect::MakeIWH(kTexSize, kTexSize);
        matrix.setRectToRect(bitmapBounds, fRect, SkMatrix::kFill_ScaleToFit);

        SkBitmap opaqueDiffuseMap = ToolUtils::create_checkerboard_bitmap(
                kTexSize, kTexSize, SK_ColorBLACK, 0xFF808080, 8);
        fOpaqueDiffuse = opaqueDiffuseMap.makeShader(&matrix);

        SkBitmap translucentDiffuseMap =
                ToolUtils::create_checkerboard_bitmap(kTexSize,
                                                      kTexSize,
                                                      SkColorSetARGB(0x55, 0x00, 0x00, 0x00),
                                                      SkColorSetARGB(0x55, 0x80, 0x80, 0x80),
                                                      8);
        fTranslucentDiffuse = translucentDiffuseMap.makeShader(&matrix);

        SkBitmap normalMap = make_frustum_normalmap(kTexSize);
        fNormalMapShader = normalMap.makeShader(&matrix);

    }

    // Scales shape around origin, rotates shape around origin, then translates shape to origin
    void positionCTM(SkCanvas *canvas, SkScalar scaleX, SkScalar scaleY, SkScalar rotate) const {
        canvas->translate(kTexSize/2.0f, kTexSize/2.0f);
        canvas->scale(scaleX, scaleY);
        canvas->rotate(rotate);
        canvas->translate(-kTexSize/2.0f, -kTexSize/2.0f);
    }

    void drawRect(SkCanvas* canvas, SkScalar scaleX, SkScalar scaleY,
                  SkScalar rotate, bool useNormalSource, bool useDiffuseShader,
                  bool useTranslucentPaint, bool useTranslucentShader, sk_sp<SkLights> lights) {
        canvas->save();

        this->positionCTM(canvas, scaleX, scaleY, rotate);

        const SkMatrix& ctm = canvas->getTotalMatrix();

        SkPaint paint;
        sk_sp<SkNormalSource> normalSource = nullptr;
        sk_sp<SkShader> diffuseShader = nullptr;

        if (useNormalSource) {
            normalSource = SkNormalSource::MakeFromNormalMap(fNormalMapShader, ctm);
        }

        if (useDiffuseShader) {
            diffuseShader = (useTranslucentShader) ? fTranslucentDiffuse : fOpaqueDiffuse;
        } else {
            paint.setColor(SK_ColorGREEN);
        }

        if (useTranslucentPaint) {
            paint.setAlpha(0x99);
        }

        paint.setShader(SkLightingShader::Make(std::move(diffuseShader), std::move(normalSource),
                                               std::move(lights)));
        canvas->drawRect(fRect, paint);

        canvas->restore();
    }

    void onDraw(SkCanvas* canvas) override {
        SkPaint labelPaint;
        SkFont  font(ToolUtils::create_portable_typeface("sans-serif", SkFontStyle()), kLabelSize);

        int gridNum = 0;

        // Running through all possible bool parameter combinations
        for (bool useNormalSource : {true, false}) {
            for (bool useDiffuseShader : {true, false}) {
                for (bool useTranslucentPaint : {true, false}) {
                    for (bool useTranslucentShader : {true, false}) {

                        // Determining position
                        SkScalar xPos = (gridNum % kGridColumnNum) * kGridCellWidth;
                        SkScalar yPos = (gridNum / kGridColumnNum) * kGridCellWidth;

                        canvas->save();

                        canvas->translate(xPos, yPos);
                        this->drawRect(canvas, 1.0f, 1.0f, 0.f, useNormalSource, useDiffuseShader,
                                       useTranslucentPaint, useTranslucentShader, fLights);
                        // Drawing labels
                        canvas->translate(0.0f, SkIntToScalar(kTexSize));
                        {
                            canvas->translate(0.0f, kLabelSize);
                            SkString label;
                            label.appendf("useNormalSource: %d", useNormalSource);
                            canvas->drawString(label, 0.0f, 0.0f, font, labelPaint);
                        }
                        {
                            canvas->translate(0.0f, kLabelSize);
                            SkString label;
                            label.appendf("useDiffuseShader: %d", useDiffuseShader);
                            canvas->drawString(label, 0.0f, 0.0f, font, labelPaint);
                        }
                        {
                            canvas->translate(0.0f, kLabelSize);
                            SkString label;
                            label.appendf("useTranslucentPaint: %d", useTranslucentPaint);
                            canvas->drawString(label, 0.0f, 0.0f, font, labelPaint);
                        }
                        {
                            canvas->translate(0.0f, kLabelSize);
                            SkString label;
                            label.appendf("useTranslucentShader: %d", useTranslucentShader);
                            canvas->drawString(label, 0.0f, 0.0f, font, labelPaint);
                        }

                        canvas->restore();

                        gridNum++;
                    }
                }
            }
        }


        // Rotation/scale test
        {
            SkScalar xPos = (gridNum % kGridColumnNum) * kGridCellWidth;
            SkScalar yPos = (gridNum / kGridColumnNum) * kGridCellWidth;

            canvas->save();
            canvas->translate(xPos, yPos);
            this->drawRect(canvas, 0.6f, 0.6f, 45.0f, true, true, true, true, fLights);
            canvas->restore();

            gridNum++;
        }

        // Anisotropic scale test
        {
            SkScalar xPos = (gridNum % kGridColumnNum) * kGridCellWidth;
            SkScalar yPos = (gridNum / kGridColumnNum) * kGridCellWidth;

            canvas->save();
            canvas->translate(xPos, yPos);
            this->drawRect(canvas, 0.6f, 0.4f, 30.0f, true, true, true, true, fLights);
            canvas->restore();

            gridNum++;
        }

        // No directional lights test
        {
            SkScalar xPos = (gridNum % kGridColumnNum) * kGridCellWidth;
            SkScalar yPos = (gridNum / kGridColumnNum) * kGridCellWidth;

            canvas->save();
            canvas->translate(xPos, yPos);
            this->drawRect(canvas, 1.0f, 1.0f, 0.0f, true, true, false, false, fLightsNoDir);
            canvas->restore();

            gridNum++;
        }

        // Two directional lights test
        {
            SkScalar xPos = (gridNum % kGridColumnNum) * kGridCellWidth;
            SkScalar yPos = (gridNum / kGridColumnNum) * kGridCellWidth;

            canvas->save();
            canvas->translate(xPos, yPos);
            this->drawRect(canvas, 1.0f, 1.0f, 0.0f, true, true, false, false, fLightsTwoDir);
            canvas->restore();

            gridNum++;
        }
    }

private:
    static constexpr int kTexSize = 96;
    static constexpr int kNumBooleanParams = 4;
    static constexpr SkScalar kLabelSize = 10.0f;
    static constexpr int kGridColumnNum = 4;
    static constexpr SkScalar kGridCellWidth = kTexSize + 20.0f + kNumBooleanParams * kLabelSize;

    sk_sp<SkShader> fOpaqueDiffuse;
    sk_sp<SkShader> fTranslucentDiffuse;
    sk_sp<SkShader> fNormalMapShader;

    const SkRect    fRect;
    sk_sp<SkLights> fLights;
    sk_sp<SkLights> fLightsNoDir;
    sk_sp<SkLights> fLightsTwoDir;

    typedef GM INHERITED;
};

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

DEF_GM(return new LightingShader2GM;)
}
