/*
 * 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/SkImageSource.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->getTotalMatrix().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(SkImageFilter::MakeMatrixFilter(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(
                SkImageSource::Make(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:
    typedef GM INHERITED;
};

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

DEF_GM(return new ResizeGM; )

}
