/*
 * 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 "SkBlurImageFilter.h"
#include "SkCanvas.h"
#include "SkColorFilter.h"
#include "SkColorFilterImageFilter.h"
#include "SkDropShadowImageFilter.h"
#include "SkSurface.h"

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

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

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

    for (size_t i = 0; i < SK_ARRAY_COUNT(rects); ++i) {
        paint.setColor(colors[i]);
        canvas->drawRect(SkRect::Make(rects[i]), paint);
    }
}

// In this GM, we're going to feed the inner portion of a 100x100 checkboard
// (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.
class ImageMakeWithFilterGM : public skiagm::GM {
public:
    ImageMakeWithFilterGM () {}

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

    SkISize onISize() override { return SkISize::Make(440, 530); }

    void onDraw(SkCanvas* canvas) override {
        auto cf = SkColorFilter::MakeModeFilter(SK_ColorGREEN, SkBlendMode::kSrc);
        sk_sp<SkImageFilter> filters[] = {
            SkColorFilterImageFilter::Make(std::move(cf), nullptr),
            SkBlurImageFilter::Make(2.0f, 2.0f, nullptr),
            SkDropShadowImageFilter::Make(
                10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE,
                SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
                nullptr),
        };

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

        SkImageInfo info = SkImageInfo::MakeN32(100, 100, kPremul_SkAlphaType);
        SkScalar MARGIN = SkIntToScalar(40);
        SkScalar DX = info.width() + MARGIN;
        SkScalar DY = info.height() + MARGIN;

        canvas->translate(MARGIN, MARGIN);

        sk_sp<SkSurface> surface = canvas->makeSurface(info);
        if (!surface) {
            surface = SkSurface::MakeRaster(info);
        }
        sk_tool_utils::draw_checkerboard(surface->getCanvas());
        sk_sp<SkImage> source = surface->makeImageSnapshot();

        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;
                SkIPoint offset;
                sk_sp<SkImage> result = source->makeWithFilter(filters[i].get(), subset, clipBound,
                                                               &outSubset, &offset);
                SkASSERT(result);
                SkASSERT(source->isTextureBacked() == result->isTextureBacked());
                result = result->makeSubset(outSubset);
                canvas->drawImage(result.get(), SkIntToScalar(offset.fX), SkIntToScalar(offset.fY));
                show_bounds(canvas, SkIRect::MakeXYWH(offset.x(), offset.y(), outSubset.width(),
                                                      outSubset.height()), clipBound);
                canvas->translate(DX, 0);
            }
            canvas->restore();
            canvas->translate(0, DY);
        }
    }

private:
    typedef GM INHERITED;
};
DEF_GM( return new ImageMakeWithFilterGM; )
