/*
 * Copyright 2017 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 "SkColorPriv.h"
#include "SkImageSource.h"
#include "SkMagnifierImageFilter.h"
#include "SkSurface.h"

static sk_sp<SkImage> make_image(GrContext* context, int size, GrSurfaceOrigin origin) {
    if (context) {
        SkImageInfo ii = SkImageInfo::Make(size, size, kN32_SkColorType, kPremul_SkAlphaType);
        sk_sp<SkSurface> surf(SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, ii, 0,
                                                          origin, nullptr));
        if (!surf) {
            return nullptr;
        }

        SkCanvas* canvas = surf->getCanvas();

        canvas->clear(SK_ColorRED);
        const struct {
            SkPoint fPt;
            SkColor fColor;
        } rec[] = {
            { { 1.5f, 1.5f }, SK_ColorGREEN },
            { { 2.5f, 1.5f }, SK_ColorBLUE },
            { { 1.5f, 2.5f }, SK_ColorCYAN },
            { { 2.5f, 2.5f }, SK_ColorGRAY },
        };
        SkPaint paint;
        for (const auto& r : rec) {
            paint.setColor(r.fColor);
            canvas->drawPoints(SkCanvas::kPoints_PointMode, 1, &r.fPt, paint);
        }
        return surf->makeImageSnapshot();
    } else {
        SkBitmap bm;
        bm.allocN32Pixels(size, size);
        bm.eraseColor(SK_ColorRED);
        *bm.getAddr32(1, 1) = SkPackARGB32(0xFF, 0x00, 0xFF, 0x00);
        *bm.getAddr32(2, 1) = SkPackARGB32(0xFF, 0x00, 0x00, 0xFF);
        *bm.getAddr32(1, 2) = SkPackARGB32(0xFF, 0x00, 0xFF, 0xFF);
        *bm.getAddr32(2, 2) = SkPackARGB32(0xFF, 0x88, 0x88, 0x88);

        return SkImage::MakeFromBitmap(bm);
    }
}

/*
 * This GM creates an image with a 2x2:
 *    Green | Blue
 *    ------------
 *    Cyan  | Gray
 * block of pixels in one corner of a 33x33 field. The 'srcRect' feature of the
 * SkMagnifierImageFilter is then used to blow it up with different inset border widths.
 *
 * In GPU-mode we wind up drawing 4 rects:
 *
 *     BottomLeft origin + 1-wide inset | TopLeft origin + 1-wide inset
 *     ----------------------------------------------------------------
 *     BottomLeft origin + 7-wide inset | TopLeft origin + 7-wide inset
 *
 * In Raster-mode the source origin isn't used.
 */
class SimpleMagnificationGM : public skiagm::GM {
public:
    SimpleMagnificationGM() {
        this->setBGColor(0xFFCCCCCC);
    }

protected:
    SkString onShortName() override {
        return SkString("simple-magnification");
    }

    SkISize onISize() override {
        return SkISize::Make(3*kPad+2*kImgSize, 3*kPad+2*kImgSize);
    }

    void draw(SkCanvas* canvas, sk_sp<SkImage> image, const SkIPoint& offset, int inset) {
        sk_sp<SkImageFilter> imgSrc(SkImageSource::Make(std::move(image)));

        SkRect srcRect = SkRect::MakeXYWH(1.0f, 1.0f, 2.0f, 2.0f);
        sk_sp<SkImageFilter> magFilter(SkMagnifierImageFilter::Make(srcRect, inset, imgSrc));

        SkPaint paint;
        paint.setImageFilter(std::move(magFilter));

        canvas->save();
        canvas->translate(offset.fX, offset.fY);
        SkRect rect = SkRect::MakeWH(kImgSize, kImgSize);
        canvas->drawRect(rect, paint);

        canvas->restore();
    }

    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
        GrContext* context = canvas->getGrContext();

        sk_sp<SkImage> bottomLImg = make_image(context, kImgSize, kBottomLeft_GrSurfaceOrigin);
        sk_sp<SkImage> topLImg = make_image(context, kImgSize, kTopLeft_GrSurfaceOrigin);
        if (!bottomLImg || !topLImg) {
            *errorMsg = "Could not load images. Did you forget to set the resourcePath?";
            return DrawResult::kFail;
        }

        int bigOffset = 2 * kPad + kImgSize;

        this->draw(canvas, bottomLImg, SkIPoint::Make(kPad, kPad), 1);
        this->draw(canvas, topLImg, SkIPoint::Make(bigOffset, kPad), 1);
        this->draw(canvas, bottomLImg, SkIPoint::Make(kPad, bigOffset), 7);
        this->draw(canvas, topLImg, SkIPoint::Make(bigOffset, bigOffset), 7);
        return DrawResult::kOk;
    }

private:
    static const int kImgSize = 33;
    static const int kPad = 2;

    typedef skiagm::GM INHERITED;
};

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

DEF_GM(return new SimpleMagnificationGM;)
