/*
 * 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/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkImage.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"

namespace skiagm {

// This GM exercises anisotropic image scaling.
class AnisotropicGM : public GM {
public:
    enum class Mode { kLinear, kMip, kAniso };

    AnisotropicGM(Mode mode) : fMode(mode) {
        switch (fMode) {
            case Mode::kLinear:
                fSampling = SkSamplingOptions(SkFilterMode::kLinear);
                break;
            case Mode::kMip:
                fSampling = SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear);
                break;
            case Mode::kAniso:
                fSampling = SkSamplingOptions::Aniso(16);
                break;
        }
        this->setBGColor(0xFFCCCCCC);
    }

protected:
    SkString onShortName() override {
        SkString name("anisotropic_image_scale_");
        switch (fMode) {
            case Mode::kLinear:
                name += "linear";
                break;
            case Mode::kMip:
                name += "mip";
                break;
            case Mode::kAniso:
                name += "aniso";
                break;
        }
        return name;
    }

    SkISize onISize() override {
        return SkISize::Make(2*kImageSize + 3*kSpacer,
                             kNumVertImages*kImageSize + (kNumVertImages+1)*kSpacer);
    }

    // Create an image consisting of lines radiating from its center
    void onOnceBeforeDraw() override {
        constexpr int kNumLines = 100;
        constexpr SkScalar kAngleStep = 360.0f / kNumLines;
        constexpr int kInnerOffset = 10;

        auto info = SkImageInfo::MakeN32(kImageSize, kImageSize, kOpaque_SkAlphaType);
        auto surf = SkSurface::MakeRaster(info);
        auto canvas = surf->getCanvas();

        canvas->clear(SK_ColorWHITE);

        SkPaint p;
        p.setAntiAlias(true);

        SkScalar angle = 0.0f, sin, cos;

        canvas->translate(kImageSize/2.0f, kImageSize/2.0f);
        for (int i = 0; i < kNumLines; ++i, angle += kAngleStep) {
            sin = SkScalarSin(angle);
            cos = SkScalarCos(angle);
            canvas->drawLine(cos * kInnerOffset, sin * kInnerOffset,
                             cos * kImageSize/2, sin * kImageSize/2, p);
        }
        fImage = surf->makeImageSnapshot();
    }

    void draw(SkCanvas* canvas, int x, int y, int xSize, int ySize) {
        SkRect r = SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y),
                                    SkIntToScalar(xSize), SkIntToScalar(ySize));
        canvas->drawImageRect(fImage, r, fSampling);
    }

    void onDraw(SkCanvas* canvas) override {
        SkScalar gScales[] = { 0.9f, 0.8f, 0.75f, 0.6f, 0.5f, 0.4f, 0.25f, 0.2f, 0.1f };

        SkASSERT(kNumVertImages-1 == (int)std::size(gScales)/2);

        // Minimize vertically
        for (int i = 0; i < (int)std::size(gScales); ++i) {
            int height = SkScalarFloorToInt(fImage->height() * gScales[i]);

            int yOff;
            if (i <= (int)std::size(gScales)/2) {
                yOff = kSpacer + i * (fImage->height() + kSpacer);
            } else {
                // Position the more highly squashed images with their less squashed counterparts
                yOff = (std::size(gScales) - i) * (fImage->height() + kSpacer) - height;
            }

            this->draw(canvas, kSpacer, yOff, fImage->width(), height);
        }

        // Minimize horizontally
        for (int i = 0; i < (int)std::size(gScales); ++i) {
            int width = SkScalarFloorToInt(fImage->width() * gScales[i]);

            int xOff, yOff;
            if (i <= (int)std::size(gScales)/2) {
                xOff = fImage->width() + 2*kSpacer;
                yOff = kSpacer + i * (fImage->height() + kSpacer);
            } else {
                // Position the more highly squashed images with their less squashed counterparts
                xOff = fImage->width() + 2*kSpacer + fImage->width() - width;
                yOff = kSpacer + (std::size(gScales) - i - 1) * (fImage->height() + kSpacer);
            }

            this->draw(canvas, xOff, yOff, width, fImage->height());
        }
    }

private:
    inline static constexpr int kImageSize     = 256;
    inline static constexpr int kSpacer        = 10;
    inline static constexpr int kNumVertImages = 5;

    sk_sp<SkImage>    fImage;
    SkSamplingOptions fSampling;
    Mode              fMode;

    using INHERITED = GM;
};

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

DEF_GM(return new AnisotropicGM(AnisotropicGM::Mode::kLinear);)
DEF_GM(return new AnisotropicGM(AnisotropicGM::Mode::kMip);)
DEF_GM(return new AnisotropicGM(AnisotropicGM::Mode::kAniso);)

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

class AnisoMipsGM : public GM {
public:
    AnisoMipsGM() = default;

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

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

    sk_sp<SkImage> updateImage(SkSurface* surf, SkColor color) {
        surf->getCanvas()->clear(color);
        SkPaint paint;
        paint.setColor(~color | 0xFF000000);
        surf->getCanvas()->drawRect(SkRect::MakeLTRB(surf->width() *2/5.f,
                                                     surf->height()*2/5.f,
                                                     surf->width() *3/5.f,
                                                     surf->height()*3/5.f),
                                    paint);
        return surf->makeImageSnapshot()->withDefaultMipmaps();
    }

    void onDraw(SkCanvas* canvas) override {
        auto ct = canvas->imageInfo().colorType() == kUnknown_SkColorType
                          ? kRGBA_8888_SkColorType
                          : canvas->imageInfo().colorType();
        auto ii = SkImageInfo::Make(kImageSize,
                                    kImageSize,
                                    ct,
                                    kPremul_SkAlphaType,
                                    canvas->imageInfo().refColorSpace());
        // In GPU mode we want a surface that is created with mipmaps to ensure that we exercise the
        // case where the SkSurface and SkImage share a texture. If the surface texture isn't
        // created with MIPs then asking for a mipmapped image will cause a copy to a mipped
        // texture.
        sk_sp<SkSurface> surface;
        if (auto rc = canvas->recordingContext()) {
            surface = SkSurface::MakeRenderTarget(rc,
                                                  SkBudgeted::kYes,
                                                  ii,
                                                  1,
                                                  kTopLeft_GrSurfaceOrigin,
                                                  /*surfaceProps=*/nullptr,
                                                  /*shouldCreateWithMips=*/true);
            if (!surface) {
                // We could be in an abandoned context situation.
                return;
            }
        } else {
            surface = canvas->makeSurface(ii);
            if (!surface) {  // could be a recording canvas.
                surface = SkSurface::MakeRaster(ii);
            }
        }

        static constexpr float kScales[] = {1.f, 0.5f, 0.25f, 0.125f};
        SkColor kColors[] = {0xFFF0F0F0, SK_ColorBLUE, SK_ColorGREEN, SK_ColorRED};
        static const SkSamplingOptions kSampling = SkSamplingOptions::Aniso(16);

        for (bool shader : {false, true}) {
            int c = 0;
            canvas->save();
            for (float sy : kScales) {
                canvas->save();
                for (float sx : kScales) {
                    canvas->save();
                    canvas->scale(sx, sy);
                    auto image = this->updateImage(surface.get(), kColors[c]);
                    if (shader) {
                        SkPaint paint;
                        paint.setShader(image->makeShader(kSampling));
                        canvas->drawRect(SkRect::Make(image->dimensions()), paint);
                    } else {
                        canvas->drawImage(image, 0, 0, kSampling);
                    }
                    canvas->restore();
                    canvas->translate(ii.width() * sx + kPad, 0);
                    c = (c + 1) % std::size(kColors);
                }
                canvas->restore();
                canvas->translate(0, ii.width() * sy + kPad);
            }
            canvas->restore();
            for (float sx : kScales) {
                canvas->translate(ii.width() * sx + kPad, 0);
            }
        }
    }

private:
    inline static constexpr int kImageSize = 128;
    inline static constexpr int kPad = 5;

    using INHERITED = GM;
};

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

DEF_GM(return new AnisoMipsGM();)

}  // namespace skiagm
