/*
 * 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 "sk_tool_utils.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::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f),
                                                     kLightFromUpperRight));
        builder.setAmbientLightColor(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->drawString(label, 0.0f, 0.0f, labelPaint);
                    }
                    {
                        canvas->translate(0.0f, LABEL_SIZE);
                        SkString label;
                        label.appendf("bevelHeight: %.1f", bevelHeight);
                        canvas->drawString(label, 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->drawString(label, 0.0f, 0.0f, labelPaint);
            }
            {
                canvas->translate(0.0f, LABEL_SIZE);
                SkString label;
                label.appendf("bevelHeight: %.1f", 7.0f);
                canvas->drawString(label, 0.0f, 0.0f, labelPaint);
            }
            {
                canvas->translate(0.0f, LABEL_SIZE);
                SkString label;
                label.appendf("rotated");
                canvas->drawString(label, 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;)
}
