/*
 * 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/gm.h"

#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkPoint3.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkRegion.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"

#include "include/effects/SkAlphaThresholdFilter.h"
#include "include/effects/SkArithmeticImageFilter.h"
#include "include/effects/SkBlurImageFilter.h"
#include "include/effects/SkColorFilterImageFilter.h"
#include "include/effects/SkDisplacementMapEffect.h"
#include "include/effects/SkDropShadowImageFilter.h"
#include "include/effects/SkImageSource.h"
#include "include/effects/SkLightingImageFilter.h"
#include "include/effects/SkMatrixConvolutionImageFilter.h"
#include "include/effects/SkMergeImageFilter.h"
#include "include/effects/SkMorphologyImageFilter.h"
#include "include/effects/SkOffsetImageFilter.h"
#include "include/effects/SkTileImageFilter.h"
#include "include/effects/SkXfermodeImageFilter.h"

#include "include/gpu/GrContext.h"

#include "tools/Resources.h"
#include "tools/ToolUtils.h"

#include <utility>

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

static void show_bounds(SkCanvas* canvas, const SkIRect* clip, const SkIRect* inSubset,
                        const SkIRect* outSubset) {
    const SkIRect* rects[] { clip, inSubset, outSubset };
    SkColor colors[] { SK_ColorBLUE, SK_ColorYELLOW, SK_ColorRED };

    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);

    for (size_t i = 0; i < SK_ARRAY_COUNT(rects); ++i) {
        // Skip null bounds rects, since not all methods have subsets
        if (rects[i]) {
            paint.setColor(colors[i]);
            canvas->drawRect(SkRect::Make(*(rects[i])), paint);
        }
    }
}

// Factories for creating image filters, either with or without a cropRect
// (this could go away if there was a SkImageFilter::makeWithCropRect() function, but that seems
//  less generally useful).
typedef sk_sp<SkImageFilter> (*FilterFactory)(sk_sp<SkImage> auxImage, const SkIRect* cropRect);

SkImageFilter::CropRect make_crop(const SkIRect* cropRect) {
    if (cropRect) {
        return SkImageFilter::CropRect(SkRect::Make(*cropRect));
    } else {
        return SkImageFilter::CropRect(SkRect(), 0x0 /* no edge flags */);
    }
}

static sk_sp<SkImageFilter> color_filter_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
    // The color filter uses kSrcIn so that it respects the transparency introduced by clamping;
    // using kSrc would just turn the entire out rect to green regardless.
    auto cf = SkColorFilters::Blend(SK_ColorGREEN, SkBlendMode::kSrcIn);
    auto crop = make_crop(cropRect);
    return SkColorFilterImageFilter::Make(std::move(cf), nullptr, &crop);
}

static sk_sp<SkImageFilter> blur_filter_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
    auto crop = make_crop(cropRect);
    return SkBlurImageFilter::Make(2.0f, 2.0f, nullptr, &crop);
}

static sk_sp<SkImageFilter> drop_shadow_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
    auto crop = make_crop(cropRect);
    return SkDropShadowImageFilter::Make(
            10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE,
            SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
            nullptr, &crop);
}

static sk_sp<SkImageFilter> offset_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
    auto crop = make_crop(cropRect);
    return SkOffsetImageFilter::Make(10.f, 5.f, nullptr, &crop);
}

static sk_sp<SkImageFilter> dilate_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
    auto crop = make_crop(cropRect);
    return SkDilateImageFilter::Make(10.f, 5.f, nullptr, &crop);
}

static sk_sp<SkImageFilter> erode_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
    auto crop = make_crop(cropRect);
    return SkErodeImageFilter::Make(10.f, 5.f, nullptr, &crop);
}

static sk_sp<SkImageFilter> displacement_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
    auto crop = make_crop(cropRect);

    sk_sp<SkImageFilter> displacement = SkImageSource::Make(std::move(auxImage));
    return SkDisplacementMapEffect::Make(
            SkDisplacementMapEffect::kR_ChannelSelectorType,
            SkDisplacementMapEffect::kG_ChannelSelectorType,
            40.f, std::move(displacement), nullptr, &crop);
}

static sk_sp<SkImageFilter> arithmetic_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
    auto crop = make_crop(cropRect);

    sk_sp<SkImageFilter> background = SkImageSource::Make(std::move(auxImage));
    return SkArithmeticImageFilter::Make(0.0f, .6f, 1.f, 0.f, false, std::move(background),
                                         nullptr, &crop);
}

static sk_sp<SkImageFilter> xfermode_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
    auto crop = make_crop(cropRect);

    sk_sp<SkImageFilter> background = SkImageSource::Make(std::move(auxImage));
    return SkXfermodeImageFilter::Make(
            SkBlendMode::kModulate, std::move(background), nullptr, &crop);
}

static sk_sp<SkImageFilter> convolution_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
    auto crop = make_crop(cropRect);

    SkISize kernelSize = SkISize::Make(3, 3);
    SkIPoint kernelOffset = SkIPoint::Make(1, 1);
    // A Laplacian edge detector, ee https://en.wikipedia.org/wiki/Kernel_(image_processing)
    SkScalar kernel[9] = {-1.f, -1.f, -1.f,
                          -1.f, 8.f, -1.f,
                          -1.f, -1.f, -1.f};
    return SkMatrixConvolutionImageFilter::Make(
            kernelSize, kernel, 1.f, 0.f, kernelOffset,
            SkMatrixConvolutionImageFilter::kClamp_TileMode, false, nullptr, &crop);
}

static sk_sp<SkImageFilter> matrix_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
    SkMatrix matrix = SkMatrix::I();
    matrix.setRotate(45.f, 50.f, 50.f);

    // This doesn't support a cropRect
    return SkImageFilter::MakeMatrixFilter(matrix, kLow_SkFilterQuality, nullptr);
}

static sk_sp<SkImageFilter> alpha_threshold_factory(sk_sp<SkImage> auxImage,
                                                    const SkIRect* cropRect) {
    auto crop = make_crop(cropRect);

    // Centered cross with higher opacity
    SkRegion region(SkIRect::MakeLTRB(30, 45, 70, 55));
    region.op(SkIRect::MakeLTRB(45, 30, 55, 70), SkRegion::kUnion_Op);

    return SkAlphaThresholdFilter::Make(region, 1.f, .2f, nullptr, &crop);
}

static sk_sp<SkImageFilter> lighting_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
    auto crop = make_crop(cropRect);

    // Must convert the RGB values of the source to alpha, since that is what the lighting filters
    // use to estimate their normals. This color matrix changes the color to white and the alpha
    // to be equal to the approx. luminance of the original color.
    static const float kMatrix[20] = {
        0.f, 0.f, 0.f, 0.f, 1.f,
        0.f, 0.f, 0.f, 0.f, 1.f,
        0.f, 0.f, 0.f, 0.f, 1.f,
        0.2126f, 0.7152f, 0.0722f, 0.f, 0.f
    };
    sk_sp<SkImageFilter> srcToAlpha = SkColorFilterImageFilter::Make(
            SkColorFilters::Matrix(kMatrix), nullptr);

    // Combine both specular and diffuse into a single DAG since they use separate internal filter
    // implementations.
    SkScalar sinAzimuth = SkScalarSin(SkDegreesToRadians(225.f)),
             cosAzimuth = SkScalarCos(SkDegreesToRadians(225.f));

    SkPoint3 spotTarget = SkPoint3::Make(SkIntToScalar(40), SkIntToScalar(40), 0);
    SkPoint3 diffLocation = SkPoint3::Make(spotTarget.fX + 50 * cosAzimuth,
                                           spotTarget.fY + 50 * sinAzimuth,
                                           SkIntToScalar(10));
    SkPoint3 specLocation = SkPoint3::Make(spotTarget.fX - 50 * sinAzimuth,
                                           spotTarget.fY + 50 * cosAzimuth,
                                           SkIntToScalar(10));
    sk_sp<SkImageFilter> diffuse = SkLightingImageFilter::MakePointLitDiffuse(
            diffLocation, SK_ColorWHITE, /* scale */ 1.f, /* kd */ 2.f, srcToAlpha, &crop);
    sk_sp<SkImageFilter> specular = SkLightingImageFilter::MakePointLitSpecular(
            specLocation, SK_ColorRED, /* scale */ 1.f, /* ks */ 1.f, /* shine */ 8.f,
            srcToAlpha, &crop);
    return SkMergeImageFilter::Make(std::move(diffuse), std::move(specular), &crop);
}

static sk_sp<SkImageFilter> tile_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
    // Tile the subset over a large region
    return SkTileImageFilter::Make(SkRect::MakeLTRB(25, 25, 75, 75), SkRect::MakeWH(100, 100),
                                   nullptr);
}

namespace {
    enum class Strategy {
        // Uses makeWithFilter, passing in subset and clip directly
        kMakeWithFilter,
        // Uses saveLayer after clipRect() to filter on the restore (i.e. reference image)
        kSaveLayer
    };
};

// In this GM, we're going to feed the inner portion of a 100x100 mandrill (i.e., strip off a
// 25-wide border) through the makeWithFilter method. We'll then draw the appropriate subset of the
// result to the screen at the given offset. Some filters rely on a secondary image, which will be a
// 100x100 checkerboard. The original image is drawn in the background so that alignment is clear
// when drawing the result at its reported offset.
class ImageMakeWithFilterGM : public skiagm::GM {
public:
    ImageMakeWithFilterGM (Strategy strategy, bool filterWithCropRect = false)
            : fStrategy(strategy)
            , fFilterWithCropRect(filterWithCropRect)
            , fMainImage(nullptr)
            , fAuxImage(nullptr) {}

protected:
    SkString onShortName() override {
        SkString name = SkString("imagemakewithfilter");

        if (fFilterWithCropRect) {
            name.append("_crop");
        }
        if (fStrategy == Strategy::kSaveLayer) {
            name.append("_ref");
        }
        return name;
    }

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

    void onOnceBeforeDraw() override {
        SkImageInfo info = SkImageInfo::MakeN32(100, 100, kUnpremul_SkAlphaType);
        auto surface = SkSurface::MakeRaster(info, nullptr);

        sk_sp<SkImage> colorImage = GetResourceAsImage("images/mandrill_128.png");
        // Resize to 100x100
        surface->getCanvas()->drawImageRect(
                colorImage, SkRect::MakeWH(colorImage->width(), colorImage->height()),
                SkRect::MakeWH(info.width(), info.height()), nullptr);
        fMainImage = surface->makeImageSnapshot();

        ToolUtils::draw_checkerboard(surface->getCanvas());
        fAuxImage = surface->makeImageSnapshot();
    }

    void onDraw(SkCanvas* canvas) override {
        FilterFactory filters[] = {
            color_filter_factory,
            blur_filter_factory,
            drop_shadow_factory,
            offset_factory,
            dilate_factory,
            erode_factory,
            displacement_factory,
            arithmetic_factory,
            xfermode_factory,
            convolution_factory,
            matrix_factory,
            alpha_threshold_factory,
            lighting_factory,
            tile_factory
        };
        const char* filterNames[] = {
            "Color",
            "Blur",
            "Drop Shadow",
            "Offset",
            "Dilate",
            "Erode",
            "Displacement",
            "Arithmetic",
            "Xfer Mode",
            "Convolution",
            "Matrix Xform",
            "Alpha Threshold",
            "Lighting",
            "Tile"
        };
        static_assert(SK_ARRAY_COUNT(filters) == SK_ARRAY_COUNT(filterNames), "filter name length");

        SkIRect clipBounds[] {
            { -20, -20, 100, 100 },
            {   0,   0,  75,  75 },
            {  20,  20, 100, 100 },
            { -20, -20,  50,  50 },
            {  20,  20,  50,  50 },
            {  30,  30,  75,  75 }
        };

        // These need to be GPU-backed when on the GPU to ensure that the image filters use the GPU
        // code paths (otherwise they may choose to do CPU filtering then upload)
        sk_sp<SkImage> mainImage, auxImage;
        if (canvas->getGrContext()) {
            if (canvas->getGrContext()->abandoned()) {
                return;
            }
            mainImage = fMainImage->makeTextureImage(canvas->getGrContext(), nullptr);
            auxImage = fAuxImage->makeTextureImage(canvas->getGrContext(), nullptr);
        } else {
            mainImage = fMainImage;
            auxImage = fAuxImage;
        }
        SkASSERT(mainImage && (mainImage->isTextureBacked() || !canvas->getGrContext()));
        SkASSERT(auxImage && (auxImage->isTextureBacked() || !canvas->getGrContext()));

        SkScalar MARGIN = SkIntToScalar(40);
        SkScalar DX = mainImage->width() + MARGIN;
        SkScalar DY = auxImage->height() + MARGIN;

        // Header hinting at what the filters do
        SkPaint textPaint;
        textPaint.setAntiAlias(true);
        SkFont font(nullptr, 12);
        for (size_t i = 0; i < SK_ARRAY_COUNT(filterNames); ++i) {
            canvas->drawString(filterNames[i], DX * i + MARGIN, 15, font, textPaint);
        }

        canvas->translate(MARGIN, MARGIN);

        for (auto clipBound : clipBounds) {
            canvas->save();
            for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
                SkIRect subset = SkIRect::MakeXYWH(25, 25, 50, 50);
                SkIRect outSubset;

                // Draw the original image faintly so that it aids in checking alignment of the
                // filtered result.
                SkPaint alpha;
                alpha.setAlphaf(0.3f);
                canvas->drawImage(mainImage, 0, 0, &alpha);

                this->drawImageWithFilter(canvas, mainImage, auxImage, filters[i], clipBound,
                                          subset, &outSubset);

                // Draw outlines to highlight what was subset, what was cropped, and what was output
                // (no output subset is displayed for kSaveLayer since that information isn't avail)
                SkIRect* outSubsetBounds = nullptr;
                if (fStrategy != Strategy::kSaveLayer) {
                    outSubsetBounds = &outSubset;
                }
                show_bounds(canvas, &clipBound, &subset, outSubsetBounds);

                canvas->translate(DX, 0);
            }
            canvas->restore();
            canvas->translate(0, DY);
        }
    }

private:
    Strategy fStrategy;
    bool fFilterWithCropRect;
    sk_sp<SkImage> fMainImage;
    sk_sp<SkImage> fAuxImage;

    void drawImageWithFilter(SkCanvas* canvas, sk_sp<SkImage> mainImage, sk_sp<SkImage> auxImage,
                             FilterFactory filterFactory, const SkIRect& clip,
                             const SkIRect& subset, SkIRect* dstRect) {
        // When creating the filter with a crop rect equal to the clip, we should expect to see no
        // difference from a filter without a crop rect. However, if the CTM isn't managed properly
        // by makeWithFilter, then the final result will be the incorrect intersection of the clip
        // and the transformed crop rect.
        sk_sp<SkImageFilter> filter = filterFactory(auxImage,
                                                    fFilterWithCropRect ? &clip : nullptr);

        if (fStrategy == Strategy::kSaveLayer) {
            SkAutoCanvasRestore acr(canvas, true);

            // Clip before the saveLayer with the filter
            canvas->clipRect(SkRect::Make(clip));

            // Put the image filter on the layer
            SkPaint paint;
            paint.setImageFilter(filter);
            canvas->saveLayer(nullptr, &paint);

            // Draw the original subset of the image
            canvas->drawImageRect(mainImage, subset, SkRect::Make(subset), nullptr);

            *dstRect = subset;
        } else {
            sk_sp<SkImage> result;
            SkIRect outSubset;
            SkIPoint offset;

            result = mainImage->makeWithFilter(filter.get(), subset, clip, &outSubset, &offset);

            SkASSERT(result);
            SkASSERT(mainImage->isTextureBacked() == result->isTextureBacked());

            *dstRect = SkIRect::MakeXYWH(offset.x(), offset.y(),
                                         outSubset.width(), outSubset.height());
            canvas->drawImageRect(result, outSubset, SkRect::Make(*dstRect), nullptr);
        }
    }

    typedef GM INHERITED;
};
// The different strategies should all look the same, with the exception of filters that affect
// transparent black (i.e. the lighting filter). In the save layer case, the filter affects the
// transparent pixels outside of the drawn subset, whereas the makeWithFilter is restricted. This
// works as intended.
DEF_GM( return new ImageMakeWithFilterGM(Strategy::kMakeWithFilter); )
DEF_GM( return new ImageMakeWithFilterGM(Strategy::kSaveLayer); )
// Test with crop rects on the image filters; should look identical to above if working correctly
DEF_GM( return new ImageMakeWithFilterGM(Strategy::kMakeWithFilter, true); )
DEF_GM( return new ImageMakeWithFilterGM(Strategy::kSaveLayer, true); )
