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

#include "gm.h"
#include "SkLightingShader.h"
#include "SkNormalSource.h"
#include "SkPoint3.h"
#include "SkShader.h"

// Create a hemispherical normal map
static SkBitmap make_hemi_normalmap(int texSize) {
    SkBitmap hemi;
    hemi.allocN32Pixels(texSize, texSize);

    sk_tool_utils::create_hemi_normal_map(&hemi, SkIRect::MakeWH(texSize, texSize));
    return hemi;
}

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

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

// Create a tetrahedral normal map
static SkBitmap make_tetra_normalmap(int texSize) {
    SkBitmap tetra;
    tetra.allocN32Pixels(texSize, texSize);

    sk_tool_utils::create_tetra_normal_map(&tetra, SkIRect::MakeWH(texSize, texSize));
    return tetra;
}

namespace skiagm {

// This GM exercises lighting shaders.
class LightingShaderGM : public GM {
public:
    LightingShaderGM() {
        this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));

        SkLights::Builder builder;

        builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f),
                                                     SkVector3::Make(SK_ScalarRoot2Over2,
                                                                     0.0f,
                                                                     SK_ScalarRoot2Over2)));
        builder.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f));

        fLights = builder.finish();
    }

protected:
    enum NormalMap {
        kHemi_NormalMap,
        kFrustum_NormalMap,
        kTetra_NormalMap,

        kLast_NormalMap = kTetra_NormalMap
    };

    static constexpr int kNormalMapCount = kLast_NormalMap+1;

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

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

    void onOnceBeforeDraw() override {
        fDiffuse = sk_tool_utils::create_checkerboard_bitmap(
                                                        kTexSize, kTexSize,
                                                        sk_tool_utils::color_to_565(0x0),
                                                        sk_tool_utils::color_to_565(0xFF804020),
                                                        8);

        fNormalMaps[kHemi_NormalMap]    = make_hemi_normalmap(kTexSize);
        fNormalMaps[kFrustum_NormalMap] = make_frustum_normalmap(kTexSize);
        fNormalMaps[kTetra_NormalMap]   = make_tetra_normalmap(kTexSize);
    }

    void drawRect(SkCanvas* canvas, const SkRect& r, NormalMap mapType) {

        SkRect bitmapBounds = SkRect::MakeIWH(fDiffuse.width(), fDiffuse.height());

        SkMatrix matrix;
        matrix.setRectToRect(bitmapBounds, r, SkMatrix::kFill_ScaleToFit);

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

        SkPaint paint;
        sk_sp<SkShader> diffuseShader = SkShader::MakeBitmapShader(fDiffuse,
                SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &matrix);
        sk_sp<SkShader> normalMap = SkShader::MakeBitmapShader(fNormalMaps[mapType],
                SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &matrix);
        sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeFromNormalMap(std::move(normalMap),
                                                                               ctm);
        paint.setShader(SkLightingShader::Make(std::move(diffuseShader), std::move(normalSource),
                                               fLights));

        canvas->drawRect(r, paint);
    }

    void onDraw(SkCanvas* canvas) override {
        SkMatrix m;
        SkRect r;

        {
            r = SkRect::MakeWH(SkIntToScalar(kTexSize), SkIntToScalar(kTexSize));
            this->drawRect(canvas, r, kHemi_NormalMap);

            canvas->save();
            m.setRotate(45.0f, r.centerX(), r.centerY());
            m.postTranslate(kGMSize/2.0f - kTexSize/2.0f, 0.0f);
            canvas->setMatrix(m);
            this->drawRect(canvas, r, kHemi_NormalMap);
            canvas->restore();
        }

        {
            r.offset(kGMSize - kTexSize, 0);
            this->drawRect(canvas, r, kFrustum_NormalMap);

            canvas->save();
            m.setRotate(45.0f, r.centerX(), r.centerY());
            m.postTranslate(0.0f, kGMSize/2.0f - kTexSize/2.0f);
            canvas->setMatrix(m);
            this->drawRect(canvas, r, kFrustum_NormalMap);
            canvas->restore();
        }

        {
            r.offset(0, kGMSize - kTexSize);
            this->drawRect(canvas, r, kTetra_NormalMap);

            canvas->save();
            m.setRotate(45.0f, r.centerX(), r.centerY());
            m.postTranslate(-kGMSize/2.0f + kTexSize/2.0f, 0.0f);
            canvas->setMatrix(m);
            this->drawRect(canvas, r, kTetra_NormalMap);
            canvas->restore();
        }

        {
            r.offset(kTexSize - kGMSize, 0);
            this->drawRect(canvas, r, kHemi_NormalMap);

            canvas->save();
            m.setRotate(45.0f, r.centerX(), r.centerY());
            m.postTranslate(0.0f, -kGMSize/2.0f + kTexSize/2.0f);
            canvas->setMatrix(m);
            this->drawRect(canvas, r, kHemi_NormalMap);
            canvas->restore();
        }
    }

private:
    static constexpr int kTexSize = 128;
    static constexpr int kGMSize  = 512;

    SkBitmap        fDiffuse;
    SkBitmap        fNormalMaps[kNormalMapCount];

    sk_sp<SkLights> fLights;

    typedef GM INHERITED;
};

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

DEF_GM(return new LightingShaderGM;)
}
