/*
 * Copyright 2011 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 "SkSurface.h"

static SkSurface* make_surface(SkCanvas* root, int N) {
    SkImageInfo info = SkImageInfo::MakeN32Premul(N, N);
    SkSurface* surface = root->newSurface(info);
    if (!surface) {
        surface = SkSurface::NewRaster(info);
    }
    return surface;
}

static SkImage* make_image(SkCanvas* root, SkIRect* center) {
    const int kFixed = 28;
    const int kStretchy = 8;
    const int kSize = 2*kFixed + kStretchy;

    SkAutoTUnref<SkSurface> surface(make_surface(root, kSize));
    SkCanvas* canvas = surface->getCanvas();

    SkRect r = SkRect::MakeWH(SkIntToScalar(kSize), SkIntToScalar(kSize));
    const SkScalar strokeWidth = SkIntToScalar(6);
    const SkScalar radius = SkIntToScalar(kFixed) - strokeWidth/2;

    center->setXYWH(kFixed, kFixed, kStretchy, kStretchy);

    SkPaint paint;
    paint.setAntiAlias(true);

    paint.setColor(0xFFFF0000);
    canvas->drawRoundRect(r, radius, radius, paint);
    r.setXYWH(SkIntToScalar(kFixed), 0, SkIntToScalar(kStretchy), SkIntToScalar(kSize));
    paint.setColor(0x8800FF00);
    canvas->drawRect(r, paint);
    r.setXYWH(0, SkIntToScalar(kFixed), SkIntToScalar(kSize), SkIntToScalar(kStretchy));
    paint.setColor(0x880000FF);
    canvas->drawRect(r, paint);

    return surface->newImageSnapshot();
}

static void image_to_bitmap(const SkImage* image, SkBitmap* bm) {
    SkImageInfo info = SkImageInfo::MakeN32Premul(image->width(), image->height());
    bm->allocPixels(info);
    image->readPixels(info, bm->getPixels(), bm->rowBytes(), 0, 0);
}

class NinePatchStretchGM : public skiagm::GM {
public:
    SkAutoTUnref<SkImage> fImage;
    SkBitmap    fBitmap;
    SkIRect     fCenter;

    NinePatchStretchGM() {}

protected:
    SkString onShortName() override {
        return SkString("ninepatch-stretch");
    }

    SkISize onISize() override {
        return SkISize::Make(760, 400);
    }

    void onDraw(SkCanvas* canvas) override {
        if (nullptr == fBitmap.pixelRef()) {
            fImage.reset(make_image(canvas, &fCenter));
            image_to_bitmap(fImage, &fBitmap);
        }

        // amount of bm that should not be stretched (unless we have to)
        const SkScalar fixed = SkIntToScalar(fBitmap.width() - fCenter.width());

        const SkTSize<SkScalar> size[] = {
            { fixed * 4 / 5, fixed * 4 / 5 },   // shrink in both axes
            { fixed * 4 / 5, fixed * 4 },       // shrink in X
            { fixed * 4,     fixed * 4 / 5 },   // shrink in Y
            { fixed * 4,     fixed * 4 }
        };

        canvas->drawBitmap(fBitmap, 10, 10, nullptr);

        SkScalar x = SkIntToScalar(100);
        SkScalar y = SkIntToScalar(100);

        SkPaint paint;
        paint.setFilterQuality(kLow_SkFilterQuality);

        for (int iy = 0; iy < 2; ++iy) {
            for (int ix = 0; ix < 2; ++ix) {
                int i = ix * 2 + iy;
                SkRect r = SkRect::MakeXYWH(x + ix * fixed, y + iy * fixed,
                                            size[i].width(), size[i].height());
                canvas->drawBitmapNine(fBitmap, fCenter, r, &paint);
                canvas->drawImageNine(fImage, fCenter, r.makeOffset(360, 0), &paint);

            }
        }
    }

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

