/*
 * 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.h"
#include "SkCanvas.h"
#include "SkBlurImageFilter.h"
#include "SkColorFilterImageFilter.h"
#include "SkModeColorFilter.h"
#include "SkMorphologyImageFilter.h"
#include "SkOffsetImageFilter.h"
#include "SkSurface.h"
#include "sk_tool_utils.h"

static sk_sp<SkImage> make_image(SkCanvas* rootCanvas) {
    SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
    auto surface(sk_tool_utils::makeSurface(rootCanvas, info));

    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setColor(SK_ColorRED);
    surface->getCanvas()->drawCircle(50, 50, 50, paint);
    return surface->makeImageSnapshot();
}

static void show_image(SkCanvas* canvas, SkImage* image, sk_sp<SkImageFilter> filter) {
    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);
    SkRect r = SkRect::MakeIWH(image->width(), image->height()).makeOutset(SK_ScalarHalf,
                                                                           SK_ScalarHalf);
    canvas->drawRect(r, paint);

    paint.setStyle(SkPaint::kFill_Style);
    paint.setImageFilter(filter);
    canvas->drawImage(image, 0, 0, &paint);
}

typedef sk_sp<SkImageFilter> (*ImageFilterFactory)();

// +[]{...} did not work on windows (VS)
// (ImageFilterFactory)[]{...} did not work on linux (gcc)
// hence this cast function
template <typename T> ImageFilterFactory IFCCast(T arg) { return arg; }

// Show the effect of localmatriximagefilter with various matrices, on various filters
DEF_SIMPLE_GM(localmatriximagefilter, canvas, 640, 640) {
    sk_sp<SkImage> image0(make_image(canvas));

    const ImageFilterFactory factories[] = {
        IFCCast([]{ return SkBlurImageFilter::Make(8, 8, nullptr); }),
        IFCCast([]{ return SkDilateImageFilter::Make(8, 8, nullptr); }),
        IFCCast([]{ return SkErodeImageFilter::Make(8, 8, nullptr); }),
        IFCCast([]{ return SkOffsetImageFilter::Make(8, 8, nullptr); }),
    };

    const SkMatrix matrices[] = {
        SkMatrix::MakeScale(SK_ScalarHalf, SK_ScalarHalf),
        SkMatrix::MakeScale(2, 2),
        SkMatrix::MakeTrans(10, 10)
    };

    const SkScalar spacer = image0->width() * 3.0f / 2;

    canvas->translate(40, 40);
    for (auto&& factory : factories) {
        sk_sp<SkImageFilter> filter(factory());

        canvas->save();
        show_image(canvas, image0.get(), filter);
        for (const auto& matrix : matrices) {
            sk_sp<SkImageFilter> localFilter(filter->makeWithLocalMatrix(matrix));
            canvas->translate(spacer, 0);
            show_image(canvas, image0.get(), std::move(localFilter));
        }
        canvas->restore();
        canvas->translate(0, spacer);
    }
}
