/*
 * 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"
#include "include/private/base/SkMalloc.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/base/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);
}
