/*
 * 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/SkPixmap.h"
#include "include/core/SkRasterHandleAllocator.h"
#include "include/core/SkSurface.h"

class GraphicsPort {
protected:
    SkCanvas* fCanvas;

public:
    GraphicsPort(SkCanvas* canvas) : fCanvas(canvas) {}
    virtual ~GraphicsPort() {}

    void save() { fCanvas->save(); }
    void saveLayer(const SkRect& bounds, SkAlpha alpha) {
        fCanvas->saveLayerAlpha(&bounds, alpha);
    }
    void restore() { fCanvas->restore(); }

    void translate(float x, float y) { fCanvas->translate(x, y); }
    void scale(float s) { fCanvas->scale(s, s); }
    void clip(const SkRect& r) { fCanvas->clipRect(r); }

    void drawOval(const SkRect& r, SkColor c) {
        SkPaint p;
        p.setColor(c);
        fCanvas->drawOval(r, p);
    }

    virtual void drawRect(const SkRect& r, SkColor c) {
        SkPaint p;
        p.setColor(c);
        fCanvas->drawRect(r, p);
    }

    SkCanvas* peekCanvas() const { return fCanvas; }
};

class SkiaGraphicsPort : public GraphicsPort {
public:
    SkiaGraphicsPort(SkCanvas* canvas) : GraphicsPort(canvas) {}

    void drawRect(const SkRect& r, SkColor c) override {
        SkCanvas* canvas = (SkCanvas*)fCanvas->accessTopRasterHandle();
        canvas->drawRect(r, SkPaint(SkColor4f::FromColor(c)));
    }
};

class SkiaAllocator : public SkRasterHandleAllocator {
public:
    SkiaAllocator() {}

    bool allocHandle(const SkImageInfo& info, Rec* rec) override {
        sk_sp<SkSurface> surface = SkSurface::MakeRaster(info);
        if (!surface) {
            return false;
        }
        SkCanvas* canvas = surface->getCanvas();
        SkPixmap pixmap;
        canvas->peekPixels(&pixmap);

        rec->fReleaseProc = [](void* pixels, void* ctx){ SkSafeUnref((SkSurface*)ctx); };
        rec->fReleaseCtx = surface.release();
        rec->fPixels = pixmap.writable_addr();
        rec->fRowBytes = pixmap.rowBytes();
        rec->fHandle = canvas;
        canvas->save();    // balanced each time updateHandle is called
        return true;
    }

    void updateHandle(Handle hndl, const SkMatrix& ctm, const SkIRect& clip) override {
        SkCanvas* canvas = (SkCanvas*)hndl;
        canvas->restore();
        canvas->save();
        canvas->clipRect(SkRect::Make(clip));
        canvas->concat(ctm);
    }
};

#ifdef SK_BUILD_FOR_MAC

#include "include/utils/mac/SkCGUtils.h"
class CGGraphicsPort : public GraphicsPort {
public:
    CGGraphicsPort(SkCanvas* canvas) : GraphicsPort(canvas) {}

    void drawRect(const SkRect& r, SkColor c) override {
        CGContextRef cg = (CGContextRef)fCanvas->accessTopRasterHandle();

        CGColorRef color = CGColorCreateGenericRGB(SkColorGetR(c)/255.f,
                                                   SkColorGetG(c)/255.f,
                                                   SkColorGetB(c)/255.f,
                                                   SkColorGetA(c)/255.f);

        CGContextSetFillColorWithColor(cg, color);
        CGContextFillRect(cg, CGRectMake(r.x(), r.y(), r.width(), r.height()));
    }
};

static CGAffineTransform matrix_to_transform(CGContextRef cg, const SkMatrix& ctm) {
    SkMatrix matrix;
    matrix.setScale(1, -1);
    matrix.postTranslate(0, SkIntToScalar(CGBitmapContextGetHeight(cg)));
    matrix.preConcat(ctm);

    return CGAffineTransformMake(matrix[SkMatrix::kMScaleX],
                                 matrix[SkMatrix::kMSkewY],
                                 matrix[SkMatrix::kMSkewX],
                                 matrix[SkMatrix::kMScaleY],
                                 matrix[SkMatrix::kMTransX],
                                 matrix[SkMatrix::kMTransY]);
}

class CGAllocator : public SkRasterHandleAllocator {
public:
    CGAllocator() {}

    bool allocHandle(const SkImageInfo& info, Rec* rec) override {
        // let CG allocate the pixels
        CGContextRef cg = SkCreateCGContext(SkPixmap(info, nullptr, 0));
        if (!cg) {
            return false;
        }
        rec->fReleaseProc = [](void* pixels, void* ctx){ CGContextRelease((CGContextRef)ctx); };
        rec->fReleaseCtx = cg;
        rec->fPixels = CGBitmapContextGetData(cg);
        rec->fRowBytes = CGBitmapContextGetBytesPerRow(cg);
        rec->fHandle = cg;
        CGContextSaveGState(cg);    // balanced each time updateHandle is called
        return true;
    }

    void updateHandle(Handle hndl, const SkMatrix& ctm, const SkIRect& clip) override {
        CGContextRef cg = (CGContextRef)hndl;

        CGContextRestoreGState(cg);
        CGContextSaveGState(cg);
        CGContextClipToRect(cg, CGRectMake(clip.x(), clip.y(), clip.width(), clip.height()));
        CGContextConcatCTM(cg, matrix_to_transform(cg, ctm));
    }
};

using MyPort = CGGraphicsPort;
using MyAllocator = CGAllocator;

#elif defined(SK_BUILD_FOR_WIN)

#include "src/core/SkLeanWindows.h"

static RECT toRECT(const SkIRect& r) {
    return { r.left(), r.top(), r.right(), r.bottom() };
}

class GDIGraphicsPort : public GraphicsPort {
public:
    GDIGraphicsPort(SkCanvas* canvas) : GraphicsPort(canvas) {}

    void drawRect(const SkRect& r, SkColor c) override {
        HDC hdc = (HDC)fCanvas->accessTopRasterHandle();

        COLORREF cr = RGB(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c));// SkEndian_Swap32(c) >> 8;
        RECT rounded = toRECT(r.round());
        FillRect(hdc, &rounded, CreateSolidBrush(cr));

        // Assuming GDI wrote zeros for alpha, this will or-in 0xFF for alpha
        SkPaint paint;
        paint.setBlendMode(SkBlendMode::kDstATop);
        fCanvas->drawRect(r, paint);
    }
};

// We use this static factory function instead of the regular constructor so
// that we can create the pixel data before calling the constructor. This is
// required so that we can call the base class' constructor with the pixel
// data.
static bool Create(int width, int height, bool is_opaque, SkRasterHandleAllocator::Rec* rec) {
    BITMAPINFOHEADER hdr;
    memset(&hdr, 0, sizeof(hdr));
    hdr.biSize = sizeof(BITMAPINFOHEADER);
    hdr.biWidth = width;
    hdr.biHeight = -height;  // Minus means top-down bitmap.
    hdr.biPlanes = 1;
    hdr.biBitCount = 32;
    hdr.biCompression = BI_RGB;  // No compression.
    hdr.biSizeImage = 0;
    hdr.biXPelsPerMeter = 1;
    hdr.biYPelsPerMeter = 1;
    void* pixels;
    HBITMAP hbitmap = CreateDIBSection(nullptr, (const BITMAPINFO*)&hdr, 0, &pixels, 0, 0);
    if (!hbitmap) {
        return false;
    }

    size_t row_bytes = width * sizeof(SkPMColor);
    sk_bzero(pixels, row_bytes * height);

    HDC hdc = CreateCompatibleDC(nullptr);
    if (!hdc) {
        DeleteObject(hbitmap);
        return false;
    }
    SetGraphicsMode(hdc, GM_ADVANCED);
    HGDIOBJ origBitmap = SelectObject(hdc, hbitmap);

    struct ReleaseContext {
        HDC hdc;
        HGDIOBJ hbitmap;
    };
    rec->fReleaseProc = [](void*, void* context) {
        ReleaseContext* ctx = static_cast<ReleaseContext*>(context);
        HBITMAP hbitmap = static_cast<HBITMAP>(SelectObject(ctx->hdc, ctx->hbitmap));
        DeleteObject(hbitmap);
        DeleteDC(ctx->hdc);
        delete ctx;
    };
    rec->fReleaseCtx = new ReleaseContext{hdc, origBitmap};
    rec->fPixels = pixels;
    rec->fRowBytes = row_bytes;
    rec->fHandle = hdc;
    return true;
}

/**
*  Subclass of SkRasterHandleAllocator that returns an HDC as its "handle".
*/
class GDIAllocator : public SkRasterHandleAllocator {
public:
    GDIAllocator() {}

    bool allocHandle(const SkImageInfo& info, Rec* rec) override {
        SkASSERT(info.colorType() == kN32_SkColorType);
        return Create(info.width(), info.height(), info.isOpaque(), rec);
    }

    void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
        HDC hdc = static_cast<HDC>(handle);

        XFORM xf;
        xf.eM11 = ctm[SkMatrix::kMScaleX];
        xf.eM21 = ctm[SkMatrix::kMSkewX];
        xf.eDx = ctm[SkMatrix::kMTransX];
        xf.eM12 = ctm[SkMatrix::kMSkewY];
        xf.eM22 = ctm[SkMatrix::kMScaleY];
        xf.eDy = ctm[SkMatrix::kMTransY];
        SetWorldTransform(hdc, &xf);

        RECT clip_bounds_RECT = toRECT(clip_bounds);
        HRGN hrgn = CreateRectRgnIndirect(&clip_bounds_RECT);
        [[maybe_unused]] int result = SelectClipRgn(hdc, hrgn);
        SkASSERT(result != ERROR);
        result = DeleteObject(hrgn);
        SkASSERT(result != 0);
    }
};

using MyPort = GDIGraphicsPort;
using MyAllocator = GDIAllocator;

#else

using MyPort = SkiaGraphicsPort;
using MyAllocator = SkiaAllocator;

#endif

DEF_SIMPLE_GM(rasterallocator, canvas, 600, 300) {
    auto doDraw = [](GraphicsPort* port) {
        SkAutoCanvasRestore acr(port->peekCanvas(), true);

        port->drawRect({0, 0, 256, 256}, SK_ColorRED);
        port->save();
        port->translate(30, 30);
        port->drawRect({0, 0, 30, 30}, SK_ColorBLUE);
        port->drawOval({10, 10, 20, 20}, SK_ColorWHITE);
        port->restore();

        port->saveLayer({50, 50, 100, 100}, 0x80);
        port->drawRect({55, 55, 95, 95}, SK_ColorGREEN);
        port->restore();

        port->clip({150, 50, 200, 200});
        port->drawRect({0, 0, 256, 256}, 0xFFCCCCCC);
    };

    // TODO: this common code fails pic-8888 and serialize-8888
    //GraphicsPort skiaPort(canvas);
    //doDraw(&skiaPort);

    const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
    std::unique_ptr<SkCanvas> nativeCanvas =
        SkRasterHandleAllocator::MakeCanvas(std::make_unique<MyAllocator>(), info);
    MyPort nativePort(nativeCanvas.get());
    doDraw(&nativePort);

    SkPixmap pm;
    nativeCanvas->peekPixels(&pm);
    canvas->drawImage(SkImage::MakeRasterCopy(pm), 280, 0);
}
