/*
 * 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/gm.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorPriv.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkData.h"
#include "include/core/SkEncodedImageFormat.h"
#include "include/core/SkFont.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageEncoder.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkPixmap.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/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GrDirectContext.h"
#include "include/private/base/SkMalloc.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkWriteBuffer.h"
#include "tools/ToolUtils.h"

#include <functional>
#include <utility>

const SkSamplingOptions gSamplings[] = {
    SkSamplingOptions(SkFilterMode::kNearest),
    SkSamplingOptions(SkFilterMode::kLinear),
    SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear),
    SkSamplingOptions(SkCubicResampler::Mitchell()),
};

static void draw_contents(SkSurface* surface, SkColor fillC) {
    SkSize size = SkSize::Make(SkIntToScalar(surface->width()),
                               SkIntToScalar(surface->height()));
    SkCanvas* canvas = surface->getCanvas();

    SkScalar stroke = size.fWidth / 10;
    SkScalar radius = (size.fWidth - stroke) / 2;

    SkPaint paint;

    paint.setAntiAlias(true);
    paint.setColor(fillC);
    canvas->drawCircle(size.fWidth/2, size.fHeight/2, radius, paint);

    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(stroke);
    paint.setColor(SK_ColorBLACK);
    canvas->drawCircle(size.fWidth/2, size.fHeight/2, radius, paint);
}

static void test_surface(SkCanvas* canvas, SkSurface* surf, bool usePaint) {
    draw_contents(surf, SK_ColorRED);
    sk_sp<SkImage> imgR = surf->makeImageSnapshot();

    if (true) {
        sk_sp<SkImage> imgR2 = surf->makeImageSnapshot();
        SkASSERT(imgR == imgR2);
    }

    imgR = ToolUtils::MakeTextureImage(canvas, std::move(imgR));
    draw_contents(surf, SK_ColorGREEN);
    sk_sp<SkImage> imgG = ToolUtils::MakeTextureImage(canvas, surf->makeImageSnapshot());

    // since we've drawn after we snapped imgR, imgG will be a different obj unless the
    // gpu context has been abandoned (in which case they will both be null)
    SkASSERT(imgR != imgG || (!imgR && !imgG));

    draw_contents(surf, SK_ColorBLUE);

    SkSamplingOptions sampling;
    SkPaint paint;

    canvas->drawImage(imgR, 0, 0, sampling, usePaint ? &paint : nullptr);
    canvas->drawImage(imgG, 0, 80, sampling, usePaint ? &paint : nullptr);
    surf->draw(canvas, 0, 160, SkSamplingOptions(), usePaint ? &paint : nullptr);

    SkRect src1, src2, src3;
    src1.setIWH(surf->width(), surf->height());
    src2.setLTRB(SkIntToScalar(-surf->width() / 2), SkIntToScalar(-surf->height() / 2),
                 SkIntToScalar(surf->width()),       SkIntToScalar(surf->height()));
    src3.setIWH(surf->width() / 2, surf->height() / 2);

    SkRect dst1, dst2, dst3, dst4;
    dst1.setLTRB(0, 240, 65, 305);
    dst2.setLTRB(0, 320, 65, 385);
    dst3.setLTRB(0, 400, 65, 465);
    dst4.setLTRB(0, 480, 65, 545);

    canvas->drawImageRect(imgR, src1, dst1, sampling, usePaint ? &paint : nullptr,
                          SkCanvas::kStrict_SrcRectConstraint);
    canvas->drawImageRect(imgG, src2, dst2, sampling, usePaint ? &paint : nullptr,
                          SkCanvas::kStrict_SrcRectConstraint);
    canvas->drawImageRect(imgR, src3, dst3, sampling, usePaint ? &paint : nullptr,
                          SkCanvas::kStrict_SrcRectConstraint);
    canvas->drawImageRect(imgG, dst4, sampling, usePaint ? &paint : nullptr);
}

class ImageGM : public skiagm::GM {
    void*   fBuffer;
    size_t  fBufferSize;
    SkSize  fSize;
    enum {
        W = 64,
        H = 64,
        RB = W * 4 + 8,
    };
public:
    ImageGM() {
        fBufferSize = RB * H;
        fBuffer = sk_malloc_throw(fBufferSize);
        fSize.set(SkIntToScalar(W), SkIntToScalar(H));
    }

    ~ImageGM() override {
        sk_free(fBuffer);
    }

protected:
    SkString onShortName() override {
        return SkString("image-surface");
    }

    SkISize onISize() override {
        return SkISize::Make(960, 1200);
    }

    void onDraw(SkCanvas* canvas) override {
        canvas->scale(2, 2);

        SkFont font(ToolUtils::create_portable_typeface(), 8);

        canvas->drawString("Original Img",  10,  60, font, SkPaint());
        canvas->drawString("Modified Img",  10, 140, font, SkPaint());
        canvas->drawString("Cur Surface",   10, 220, font, SkPaint());
        canvas->drawString("Full Crop",     10, 300, font, SkPaint());
        canvas->drawString("Over-crop",     10, 380, font, SkPaint());
        canvas->drawString("Upper-left",    10, 460, font, SkPaint());
        canvas->drawString("No Crop",       10, 540, font, SkPaint());

        canvas->drawString("Pre-Alloc Img", 80,  10, font, SkPaint());
        canvas->drawString("New Alloc Img", 160, 10, font, SkPaint());
        canvas->drawString( "GPU",          265, 10, font, SkPaint());

        canvas->translate(80, 20);

        // since we draw into this directly, we need to start fresh
        sk_bzero(fBuffer, fBufferSize);

        SkImageInfo info = SkImageInfo::MakeN32Premul(W, H);
        sk_sp<SkSurface> surf0(SkSurface::MakeRasterDirect(info, fBuffer, RB));
        sk_sp<SkSurface> surf1(SkSurface::MakeRaster(info));
        sk_sp<SkSurface> surf2(SkSurface::MakeRenderTarget(
                canvas->recordingContext(), skgpu::Budgeted::kNo, info));

        test_surface(canvas, surf0.get(), true);
        canvas->translate(80, 0);
        test_surface(canvas, surf1.get(), true);
        if (surf2) {
            canvas->translate(80, 0);
            test_surface(canvas, surf2.get(), true);
        }
    }

private:
    using INHERITED = skiagm::GM;
};
DEF_GM( return new ImageGM; )

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

static void draw_pixmap(SkCanvas* canvas, const SkPixmap& pmap) {
    SkBitmap bitmap;
    bitmap.installPixels(pmap);
    canvas->drawImage(bitmap.asImage(), 0, 0);
}

static void show_scaled_pixels(SkCanvas* canvas, SkImage* image) {
    SkAutoCanvasRestore acr(canvas, true);

    canvas->drawImage(image, 0, 0);
    canvas->translate(110, 10);

    const SkImageInfo info = SkImageInfo::MakeN32Premul(40, 40);
    SkAutoPixmapStorage storage;
    storage.alloc(info);

    const SkImage::CachingHint chints[] = {
        SkImage::kAllow_CachingHint, SkImage::kDisallow_CachingHint,
    };

    for (auto ch : chints) {
        canvas->save();
        for (auto s : gSamplings) {
            if (image->scalePixels(storage, s, ch)) {
                draw_pixmap(canvas, storage);
            }
            canvas->translate(70, 0);
        }
        canvas->restore();
        canvas->translate(0, 45);
    }
}

static void draw_contents(SkCanvas* canvas) {
    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(20);
    canvas->drawCircle(50, 50, 35, paint);
}

static sk_sp<SkImage> make_raster(const SkImageInfo& info,
                                  GrRecordingContext*,
                                  void (*draw)(SkCanvas*)) {
    auto surface(SkSurface::MakeRaster(info));
    draw(surface->getCanvas());
    return surface->makeImageSnapshot();
}

static sk_sp<SkImage> make_picture(const SkImageInfo& info,
                                   GrRecordingContext*,
                                   void (*draw)(SkCanvas*)) {
    SkPictureRecorder recorder;
    draw(recorder.beginRecording(SkRect::MakeIWH(info.width(), info.height())));
    return SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(),
                                    info.dimensions(), nullptr, nullptr, SkImage::BitDepth::kU8,
                                    SkColorSpace::MakeSRGB());
}

static sk_sp<SkImage> make_codec(const SkImageInfo& info,
                                 GrRecordingContext*,
                                 void (*draw)(SkCanvas*)) {
    sk_sp<SkImage> image(make_raster(info, nullptr, draw));
    return SkImage::MakeFromEncoded(image->encodeToData());
}

static sk_sp<SkImage> make_gpu(const SkImageInfo& info,
                               GrRecordingContext* ctx,
                               void (*draw)(SkCanvas*)) {
    if (!ctx) {
        return nullptr;
    }

    auto surface(SkSurface::MakeRenderTarget(ctx, skgpu::Budgeted::kNo, info));
    if (!surface) {
        return nullptr;
    }

    draw(surface->getCanvas());
    return surface->makeImageSnapshot();
}

typedef sk_sp<SkImage> (*ImageMakerProc)(const SkImageInfo&,
                                         GrRecordingContext*,
                                         void (*)(SkCanvas*));

class ScalePixelsGM : public skiagm::GM {
public:
    ScalePixelsGM() {}

protected:
    SkString onShortName() override {
        return SkString("scale-pixels");
    }

    SkISize onISize() override {
        return SkISize::Make(960, 1200);
    }

    void onDraw(SkCanvas* canvas) override {
        const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);

        const ImageMakerProc procs[] = {
            make_codec, make_raster, make_picture, make_codec, make_gpu,
        };
        for (auto& proc : procs) {
            sk_sp<SkImage> image(proc(info, canvas->recordingContext(), draw_contents));
            if (image) {
                show_scaled_pixels(canvas, image.get());
            }
            canvas->translate(0, 120);
        }
    }

private:
    using INHERITED = skiagm::GM;
};
DEF_GM( return new ScalePixelsGM; )

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

DEF_SIMPLE_GM_CAN_FAIL(new_texture_image, canvas, errorMsg, 280, 115) {

    GrDirectContext* dContext = GrAsDirectContext(canvas->recordingContext());
    bool isGPU = SkToBool(dContext);

#if defined(SK_GRAPHITE)
    skgpu::graphite::Recorder* recorder = canvas->recorder();
    isGPU = isGPU || SkToBool(recorder);
#endif

    if (!isGPU) {
        *errorMsg = skiagm::GM::kErrorMsg_DrawSkippedGpuOnly;
        return skiagm::DrawResult::kSkip;
    }

    auto render_image = [](SkCanvas* canvas) {
        canvas->clear(SK_ColorBLUE);
        SkPaint paint;
        paint.setColor(SK_ColorRED);
        canvas->drawRect(SkRect::MakeXYWH(10.f,10.f,10.f,10.f), paint);
        paint.setColor(SK_ColorGREEN);
        canvas->drawRect(SkRect::MakeXYWH(30.f,10.f,10.f,10.f), paint);
        paint.setColor(SK_ColorYELLOW);
        canvas->drawRect(SkRect::MakeXYWH(10.f,30.f,10.f,10.f), paint);
        paint.setColor(SK_ColorCYAN);
        canvas->drawRect(SkRect::MakeXYWH(30.f,30.f,10.f,10.f), paint);
    };

    static constexpr int kSize = 50;
    SkImageInfo ii = SkImageInfo::Make(kSize, kSize,
                                       kRGBA_8888_SkColorType, kPremul_SkAlphaType,
                                       SkColorSpace::MakeSRGB());
    SkBitmap bmp;
    bmp.allocPixels(ii);
    SkCanvas bmpCanvas(bmp);
    render_image(&bmpCanvas);

    std::function<sk_sp<SkImage>()> imageFactories[] = {
            // Create sw raster image.
            [&] { return bmp.asImage(); },
            // Create encoded image.
            [&] {
                auto src = SkEncodeBitmap(bmp, SkEncodedImageFormat::kPNG, 100);
                return SkImage::MakeFromEncoded(std::move(src));
            },
            // Create YUV encoded image.
            [&] {
                auto src = SkEncodeBitmap(bmp, SkEncodedImageFormat::kJPEG, 100);
                return SkImage::MakeFromEncoded(std::move(src));
            },
            // Create a picture image.
            [&] {
                SkPictureRecorder recorder;
                SkCanvas* canvas =
                        recorder.beginRecording(SkIntToScalar(kSize), SkIntToScalar(kSize));
                render_image(canvas);
                sk_sp<SkColorSpace> srgbColorSpace = SkColorSpace::MakeSRGB();
                return SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(),
                                                SkISize::Make(kSize, kSize),
                                                nullptr,
                                                nullptr,
                                                SkImage::BitDepth::kU8,
                                                srgbColorSpace);
            },
            // Create a texture image
            [&]() -> sk_sp<SkImage> {
                sk_sp<SkSurface> surface;
                if (dContext) {
                    surface = SkSurface::MakeRenderTarget(dContext, skgpu::Budgeted::kYes, ii);
                } else {
#if defined(SK_GRAPHITE)
                    surface = SkSurface::MakeGraphite(recorder, ii);
#endif
                }

                if (!surface) {
                    return nullptr;
                }
                render_image(surface->getCanvas());
                return surface->makeImageSnapshot();
            }};

    constexpr SkScalar kPad = 5.f;
    canvas->translate(kPad, kPad);
    for (const auto& factory : imageFactories) {
        sk_sp<SkImage> image(factory());
        if (image) {
            for (auto mm : { false, true }) {
                sk_sp<SkImage> texImage;
                if (dContext) {
                    texImage = image->makeTextureImage(dContext,
                                                       mm ? GrMipmapped::kYes : GrMipmapped::kNo);
                } else {
#if defined(SK_GRAPHITE)
                    texImage = image->makeTextureImage(recorder,
                                                       { mm ? skgpu::Mipmapped::kYes
                                                            : skgpu::Mipmapped::kNo });
 #endif
                }
                if (texImage) {
                    canvas->drawImage(texImage, 0, mm ? kSize + kPad : 0);
                }
            }
        }
        canvas->translate(kSize + kPad, 0);
    }

    return skiagm::DrawResult::kOk;
}

static void draw_pixmap(SkCanvas* canvas, const SkPixmap& pm, SkScalar x, SkScalar y) {
    canvas->drawImage(SkImage::MakeRasterCopy(pm), x, y);
}

static void slam_ff(const SkPixmap& pm) {
    for (int y = 0; y < pm.height(); ++y) {
        for (int x = 0; x < pm.width(); ++x) {
            *pm.writable_addr32(x, y) = *pm.addr32(x, y) | SkPackARGB32(0xFF, 0, 0, 0);
        }
    }
}

DEF_SIMPLE_GM(scalepixels_unpremul, canvas, 1080, 280) {
    SkImageInfo info = SkImageInfo::MakeN32(16, 16, kUnpremul_SkAlphaType);
    SkAutoPixmapStorage pm;
    pm.alloc(info);
    for (int y = 0; y < 16; ++y) {
        for (int x = 0; x < 16; ++x) {
            *pm.writable_addr32(x, y) = SkPackARGB32NoCheck(0, (y << 4) | y, (x << 4) | x, 0xFF);
        }
    }
    SkAutoPixmapStorage pm2;
    pm2.alloc(SkImageInfo::MakeN32(256, 256, kUnpremul_SkAlphaType));

    for (auto s : gSamplings) {
        pm.scalePixels(pm2, s);
        slam_ff(pm2);
        draw_pixmap(canvas, pm2, 10, 10);
        canvas->translate(pm2.width() + 10.0f, 0);
    }
}

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

static sk_sp<SkImage> make_lazy_image() {
    sk_sp<SkPicture> picture;
    {
        SkPictureRecorder recorder;
        SkCanvas* canvas = recorder.beginRecording(SkRect::MakeIWH(200, 200));
        canvas->drawCircle(100, 100, 100, SkPaint());
        picture = recorder.finishRecordingAsPicture();
    }

    return SkImage::MakeFromPicture(std::move(picture), { 200, 200 },
                                    /* matrix= */ nullptr, /* paint= */ nullptr,
                                    SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB());
}

static sk_sp<SkImage> serial_deserial(SkImage* img) {
    if (!img) {
        return nullptr;
    }
    SkBinaryWriteBuffer writer;
    writer.writeImage(img);
    size_t length = writer.bytesWritten();
    auto data = SkData::MakeUninitialized(length);
    writer.writeToMemory(data->writable_data());

    SkReadBuffer reader(data->data(), length);
    return reader.readImage();
}

DEF_SIMPLE_GM_CAN_FAIL(image_subset, canvas, errorMsg, 440, 220) {
    auto img = make_lazy_image();
    if (!img) {
        *errorMsg = "Failed to make lazy image.";
        return skiagm::DrawResult::kFail;
    }

    GrDirectContext* dContext = GrAsDirectContext(canvas->recordingContext());
#if defined(SK_GRAPHITE)
    auto recorder = canvas->recorder();
#endif

    canvas->drawImage(img, 10, 10);

    sk_sp<SkImage> subset;

#if defined(SK_GRAPHITE)
    if (recorder) {
        subset = img->makeSubset({100, 100, 200, 200}, recorder);
    } else
#endif
    {
        subset = img->makeSubset({100, 100, 200, 200}, dContext);
    }

    canvas->drawImage(subset, 220, 10);
    subset = serial_deserial(subset.get());
    canvas->drawImage(subset, 220+110, 10);
    return skiagm::DrawResult::kOk;
}
