
/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "include/core/SkCanvas.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkPath.h"
#include "include/core/SkPoint3.h"
#include "include/core/SkRRect.h"
#include "include/pathops/SkPathOps.h"
#include "include/utils/SkCamera.h"
#include "include/utils/SkShadowUtils.h"
#include "src/base/SkUTF.h"
#include "src/core/SkBlurMask.h"
#include "tools/ToolUtils.h"
#include "tools/timer/TimeUtils.h"
#include "tools/viewer/Slide.h"

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

class MaterialShadowsSlide : public Slide {
    SkPath    fCirclePath;
    SkPath    fCapsulePath;
    SkPath    fLargeRRPath;
    SkPath    fSmallRRPath;

    SkPoint3  fLightPos;

public:
    MaterialShadowsSlide() { fName = "MaterialShadows"; }

    void load(SkScalar w, SkScalar h) override {
        fCirclePath.addCircle(0, 0, 56/2);
        fCapsulePath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-64, -24, 128, 48), 24, 24));
        fLargeRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-64, -64, 128, 128), 4, 4));
        fSmallRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-40, -40, 80, 80), 4, 4));

        fLightPos = SkPoint3::Make(0, -700, 700);
    }

    void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
                          const SkPoint3& zPlaneParams,
                          const SkPaint& paint, SkScalar ambientAlpha,
                          const SkPoint3& lightPos, SkScalar lightRadius, SkScalar spotAlpha) {
        uint32_t flags = 0;
        flags |= SkShadowFlags::kDirectionalLight_ShadowFlag;

        SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0);
        SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
        SkShadowUtils::DrawShadow(canvas, path, zPlaneParams, lightPos, lightRadius,
                                  ambientColor, spotColor, flags);

        canvas->drawPath(path, paint);
    }

    void draw(SkCanvas* canvas) override {
        canvas->drawColor(0xFFFFFFFF);

        const SkScalar kLightRadius = 1.1f;
        const SkScalar kAmbientAlpha = 0.05f;
        const SkScalar kSpotAlpha = 0.35f;

        const SkScalar elevations[] = { 1, 3, 6, 8, 12, 24 };

        SkPaint paint;
        paint.setAntiAlias(true);

        SkPoint3 lightPos = fLightPos;
        SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, 0);

        paint.setColor(SK_ColorWHITE);
        canvas->save();
        canvas->translate(80, 80);
        for (unsigned int i = 0; i < std::size(elevations); ++i) {
            zPlaneParams.fZ = elevations[i];
            this->drawShadowedPath(canvas, fCirclePath, zPlaneParams, paint, kAmbientAlpha,
                                   lightPos, kLightRadius, kSpotAlpha);
            canvas->translate(80, 0);
        }
        canvas->restore();

        canvas->save();
        canvas->translate(120, 175);
        for (unsigned int i = 0; i < std::size(elevations); ++i) {
            zPlaneParams.fZ = elevations[i];
            this->drawShadowedPath(canvas, fCapsulePath, zPlaneParams, paint, kAmbientAlpha,
                                   lightPos, kLightRadius, kSpotAlpha);
            canvas->translate(160, 0);
        }
        canvas->restore();

        canvas->save();
        canvas->translate(120, 320);
        for (unsigned int i = 0; i < std::size(elevations); ++i) {
            zPlaneParams.fZ = elevations[i];
            this->drawShadowedPath(canvas, fLargeRRPath, zPlaneParams, paint, kAmbientAlpha,
                                   lightPos, kLightRadius, kSpotAlpha);
            canvas->translate(160, 0);
        }
        canvas->restore();

        canvas->save();
        canvas->translate(100, 475);
        for (unsigned int i = 0; i < std::size(elevations); ++i) {
            zPlaneParams.fZ = elevations[i];
            this->drawShadowedPath(canvas, fSmallRRPath, zPlaneParams, paint, kAmbientAlpha,
                                   lightPos, kLightRadius, kSpotAlpha);
            canvas->translate(160, 0);
        }
        canvas->restore();

        canvas->save();
        canvas->translate(100, 600);
        for (unsigned int i = 0; i < std::size(elevations); ++i) {
            canvas->save();
            zPlaneParams.fZ = elevations[i];
            canvas->rotate(10);
            this->drawShadowedPath(canvas, fSmallRRPath, zPlaneParams, paint, kAmbientAlpha,
                                   lightPos, kLightRadius, kSpotAlpha);
            canvas->restore();
            canvas->translate(160, 0);
        }
        canvas->restore();

        canvas->save();
        canvas->translate(100, 725);
        for (unsigned int i = 0; i < std::size(elevations); ++i) {
            canvas->save();
            zPlaneParams.fZ = elevations[i];
            canvas->rotate(45);
            this->drawShadowedPath(canvas, fSmallRRPath, zPlaneParams, paint, kAmbientAlpha,
                                   lightPos, kLightRadius, kSpotAlpha);
            canvas->restore();
            canvas->translate(160, 0);
        }
        canvas->restore();

    }
};

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

DEF_SLIDE( return new MaterialShadowsSlide(); )
