/*
 * Copyright 2013 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/SkFilterQuality.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/effects/SkImageFilters.h"

#include <utility>

namespace skiagm {

class ResizeGM : public GM {
public:
    ResizeGM() {
        this->setBGColor(0x00000000);
    }

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

    void draw(SkCanvas* canvas,
              const SkRect& rect,
              const SkSize& deviceSize,
              SkFilterQuality filterQuality,
              sk_sp<SkImageFilter> input) {
        SkRect dstRect;
        canvas->getLocalToDeviceAs3x3().mapRect(&dstRect, rect);
        canvas->save();
        SkScalar deviceScaleX = deviceSize.width() / dstRect.width();
        SkScalar deviceScaleY = deviceSize.height() / dstRect.height();
        canvas->translate(rect.x(), rect.y());
        canvas->scale(deviceScaleX, deviceScaleY);
        canvas->translate(-rect.x(), -rect.y());
        SkMatrix matrix;
        matrix.setScale(SkScalarInvert(deviceScaleX), SkScalarInvert(deviceScaleY));
        sk_sp<SkImageFilter> filter(SkImageFilters::MatrixTransform(matrix,
                                                                    filterQuality,
                                                                    std::move(input)));
        SkPaint filteredPaint;
        filteredPaint.setImageFilter(std::move(filter));
        canvas->saveLayer(&rect, &filteredPaint);
        SkPaint paint;
        paint.setColor(0xFF00FF00);
        SkRect ovalRect = rect;
        ovalRect.inset(SkIntToScalar(4), SkIntToScalar(4));
        canvas->drawOval(ovalRect, paint);
        canvas->restore(); // for saveLayer
        canvas->restore();
    }

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

    void onDraw(SkCanvas* canvas) override {
        canvas->clear(SK_ColorBLACK);

        const SkRect srcRect = SkRect::MakeWH(96, 96);
        const SkSize deviceSize = SkSize::Make(16, 16);

        this->draw(canvas, srcRect, deviceSize, kNone_SkFilterQuality, nullptr);

        canvas->translate(srcRect.width() + SkIntToScalar(10), 0);
        this->draw(canvas, srcRect, deviceSize, kLow_SkFilterQuality, nullptr);

        canvas->translate(srcRect.width() + SkIntToScalar(10), 0);
        this->draw(canvas, srcRect, deviceSize, kMedium_SkFilterQuality, nullptr);

        canvas->translate(srcRect.width() + SkIntToScalar(10), 0);
        this->draw(canvas, srcRect, deviceSize, kHigh_SkFilterQuality, nullptr);

        {
            sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(16, 16));
            SkCanvas* surfaceCanvas = surface->getCanvas();
            surfaceCanvas->clear(0x000000);
            {
                SkPaint paint;
                paint.setColor(0xFF00FF00);
                SkRect ovalRect = SkRect::MakeWH(16, 16);
                ovalRect.inset(SkIntToScalar(2)/3, SkIntToScalar(2)/3);
                surfaceCanvas->drawOval(ovalRect, paint);
            }
            sk_sp<SkImage> image(surface->makeImageSnapshot());
            SkRect inRect = SkRect::MakeXYWH(-4, -4, 20, 20);
            SkRect outRect = SkRect::MakeXYWH(-24, -24, 120, 120);
            sk_sp<SkImageFilter> source(
                SkImageFilters::Image(std::move(image), inRect, outRect, kHigh_SkFilterQuality));
            canvas->translate(srcRect.width() + SkIntToScalar(10), 0);
            this->draw(canvas, srcRect, deviceSize, kHigh_SkFilterQuality, std::move(source));
        }
    }

private:
    using INHERITED = GM;
};

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

DEF_GM(return new ResizeGM; )

}  // namespace skiagm
