/*
 * 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.h"
#include "SkLightingShader.h"
#include "SkNormalSource.h"
#include "SkPath.h"
#include "SkPoint3.h"
#include "SkShader.h"


namespace skiagm {

// This GM exercises lighting shaders when used with bevel SkNormalSource objects.
class LightingShaderBevelGM : public GM {
public:
    LightingShaderBevelGM() {
        this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
    }

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

    SkISize onISize() override {
        return SkISize::Make(SkScalarCeilToInt(GRID_NUM_COLUMNS * GRID_CELL_WIDTH),
                             SkScalarCeilToInt(GRID_NUM_ROWS    * GRID_CELL_WIDTH));
    }

    void onOnceBeforeDraw() override {
        SkLights::Builder builder;
        const SkVector3 kLightFromUpperRight = SkVector3::Make(0.788f, 0.394f, 0.473f);

        builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f),
                                    kLightFromUpperRight));
        builder.add(SkLights::Light(SkColor3f::Make(0.2f, 0.2f, 0.2f)));
        fLights = builder.finish();

        // fRect is assumed to be square throughout this file
        fRect = SkRect::MakeIWH(kTexSize, kTexSize);
        SkMatrix matrix;
        SkRect bitmapBounds = SkRect::MakeIWH(kTexSize, kTexSize);
        matrix.setRectToRect(bitmapBounds, fRect, SkMatrix::kFill_ScaleToFit);

        SkBitmap diffuseMap = sk_tool_utils::create_checkerboard_bitmap(
                kTexSize, kTexSize,
                sk_tool_utils::color_to_565(0x0),
                sk_tool_utils::color_to_565(0xFF804020),
                8);
        fDiffuse = SkShader::MakeBitmapShader(diffuseMap, SkShader::kClamp_TileMode,
                                              SkShader::kClamp_TileMode, &matrix);

        fConvexPath.moveTo(fRect.width() / 2.0f, 0.0f);
        fConvexPath.lineTo(0.0f, fRect.height());
        fConvexPath.lineTo(fRect.width(), fRect.height());
        fConvexPath.close();

        // Creating concave path
        {
            SkScalar x = 0.0f;
            SkScalar y = fRect.height() / 2.0f;

            const int NUM_SPIKES = 8;

            const SkScalar x0 = x;
            const SkScalar dx = fRect.width() / (NUM_SPIKES * 2);
            const SkScalar dy = SK_Scalar1 * 10;


            fConcavePath.moveTo(x, y + dy);
            for (int i = 0; i < NUM_SPIKES; i++) {
                x += dx;
                fConcavePath.lineTo(x, y - dy);
                x += dx;
                fConcavePath.lineTo(x, y + dy);
            }
            fConcavePath.lineTo(x, y + (2 * dy));
            fConcavePath.lineTo(x0, y + (2 * dy));
            fConcavePath.close();
        }
    }

    // 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);
    }

    enum Shape {
        kCircle_Shape,
        kRect_Shape,
        kRRect_Shape,
        kConvexPath_Shape,
        kConcavePath_Shape,

        kLast_Shape = kConcavePath_Shape
    };
    void drawShape(enum Shape shape, SkCanvas* canvas, SkScalar scaleX, SkScalar scaleY,
                   SkScalar rotate, SkNormalSource::BevelType bevelType, SkScalar bevelHeight) {
        canvas->save();

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

        SkPaint paint;

        SkScalar bevelWidth = 10.0f;
        sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeBevel(bevelType, bevelWidth,
                                                                       bevelHeight);

        paint.setShader(SkLightingShader::Make(fDiffuse, std::move(normalSource), fLights));
        paint.setAntiAlias(true);
        switch(shape) {
            case kCircle_Shape:
                canvas->drawCircle(fRect.centerX(), fRect.centerY(), fRect.width()/2.0f, paint);
                break;
            case kRect_Shape:
                canvas->drawRect(fRect, paint);
                break;
            case kRRect_Shape:
                canvas->drawRoundRect(fRect, 5.0f, 5.0f, paint);
                break;
            case kConvexPath_Shape:
                canvas->drawPath(fConvexPath, paint);
                break;
            case kConcavePath_Shape:
                canvas->drawPath(fConcavePath, paint);
                break;
            default:
                SkDEBUGFAIL("Invalid shape enum for drawShape");
        }

        canvas->restore();
    }

    void onDraw(SkCanvas* canvas) override {
        SkPaint labelPaint;
        labelPaint.setTypeface(sk_tool_utils::create_portable_typeface("sans-serif",
                                                                       SkFontStyle()));
        labelPaint.setAntiAlias(true);
        labelPaint.setTextSize(LABEL_SIZE);

        int gridNum = 0;

        // Running through all possible parameter combinations
        for (auto bevelType : {SkNormalSource::BevelType::kLinear,
                               SkNormalSource::BevelType::kRoundedIn,
                               SkNormalSource::BevelType::kRoundedOut}) {
            for (SkScalar bevelHeight: {-7.0f, 7.0f}) {
                for (int shapeInt = 0; shapeInt < NUM_SHAPES; shapeInt++) {
                    Shape shape = (Shape)shapeInt;

                    // Determining position
                    SkScalar xPos = (gridNum / GRID_NUM_ROWS) * GRID_CELL_WIDTH;
                    SkScalar yPos = (gridNum % GRID_NUM_ROWS) * GRID_CELL_WIDTH;

                    canvas->save();

                    canvas->translate(xPos, yPos);
                    this->drawShape(shape, canvas, 1.0f, 1.0f, 0.f, bevelType, bevelHeight);
                    // Drawing labels
                    canvas->translate(0.0f, SkIntToScalar(kTexSize));
                    {
                        canvas->translate(0.0f, LABEL_SIZE);
                        SkString label;
                        label.append("bevelType: ");
                        switch (bevelType) {
                            case SkNormalSource::BevelType::kLinear:
                                label.append("linear");
                                break;
                            case SkNormalSource::BevelType::kRoundedIn:
                                label.append("roundedIn");
                                break;
                            case SkNormalSource::BevelType::kRoundedOut:
                                label.append("roundedOut");
                                break;
                        }
                        canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint);
                    }
                    {
                        canvas->translate(0.0f, LABEL_SIZE);
                        SkString label;
                        label.appendf("bevelHeight: %.1f", bevelHeight);
                        canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint);
                    }

                    canvas->restore();

                    gridNum++;
                }
            }
        }

        // Testing rotation
        for (int shapeInt = 0; shapeInt < NUM_SHAPES; shapeInt++) {
            Shape shape = (Shape)shapeInt;

            // Determining position
            SkScalar xPos = (gridNum / GRID_NUM_ROWS) * GRID_CELL_WIDTH;
            SkScalar yPos = (gridNum % GRID_NUM_ROWS) * GRID_CELL_WIDTH;

            canvas->save();

            canvas->translate(xPos, yPos);
            this->drawShape(shape, canvas, SK_ScalarRoot2Over2, SK_ScalarRoot2Over2, 45.0f,
                            SkNormalSource::BevelType::kLinear, 7.0f);

            // Drawing labels
            canvas->translate(0.0f, SkIntToScalar(kTexSize));
            {
                canvas->translate(0.0f, LABEL_SIZE);
                SkString label;
                label.appendf("bevelType: linear");
                canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint);
            }
            {
                canvas->translate(0.0f, LABEL_SIZE);
                SkString label;
                label.appendf("bevelHeight: %.1f", 7.0f);
                canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint);
            }
            {
                canvas->translate(0.0f, LABEL_SIZE);
                SkString label;
                label.appendf("rotated");
                canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint);
            }

            canvas->restore();

            gridNum++;
        }

        // Making sure NUM_COMBINATIONS_PER_SHAPE is set correctly
        SkASSERT(gridNum == (NUM_COMBINATIONS_PER_SHAPE*NUM_SHAPES));
    }

private:
    static constexpr int kTexSize = 96;
    static constexpr int NUM_SHAPES = kLast_Shape + 1;
    static constexpr int NUM_COMBINATIONS_PER_SHAPE = 7;
    static constexpr int GRID_NUM_ROWS = NUM_SHAPES;
    static constexpr int GRID_NUM_COLUMNS = NUM_COMBINATIONS_PER_SHAPE;
    static constexpr SkScalar LABEL_SIZE = 10.0f;
    static constexpr int NUM_LABELS_PER_CELL = 3;
    static constexpr SkScalar GRID_CELL_WIDTH = kTexSize + 10.0f + NUM_LABELS_PER_CELL * LABEL_SIZE;

    sk_sp<SkShader> fDiffuse;

    SkRect fRect;
    SkPath fConvexPath;
    SkPath fConcavePath;
    sk_sp<SkLights> fLights;

    typedef GM INHERITED;
};

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

DEF_GM(return new LightingShaderBevelGM;)
}
