/*
 * 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 "SkBitmap.h"
#include "SkCanvas.h"
#include "SkColorPriv.h"
#include "SkGradientShader.h"
#include "SkRect.h"
#include "Test.h"

#include "sk_tool_utils.h"

// these are in the same order as the SkColorType enum
static const char* gColorTypeName[] = {
    "None", "A8", "565", "4444", "RGBA", "BGRA", "Index8"
};

/** Returns -1 on success, else the x coord of the first bad pixel, return its
    value in bad
 */
typedef int (*Proc)(const void*, int width, uint32_t expected, uint32_t* bad);

static int proc_32(const void* ptr, int w, uint32_t expected, uint32_t* bad) {
    const SkPMColor* addr = static_cast<const SkPMColor*>(ptr);
    for (int x = 0; x < w; x++) {
        if (addr[x] != expected) {
            *bad = addr[x];
            return x;
        }
    }
    return -1;
}

static int proc_16(const void* ptr, int w, uint32_t expected, uint32_t* bad) {
    const uint16_t* addr = static_cast<const uint16_t*>(ptr);
    for (int x = 0; x < w; x++) {
        if (addr[x] != expected) {
            *bad = addr[x];
            return x;
        }
    }
    return -1;
}

static int proc_8(const void* ptr, int w, uint32_t expected, uint32_t* bad) {
    const SkPMColor* addr = static_cast<const SkPMColor*>(ptr);
    for (int x = 0; x < w; x++) {
        if (SkGetPackedA32(addr[x]) != expected) {
            *bad = SkGetPackedA32(addr[x]);
            return x;
        }
    }
    return -1;
}

static int proc_bad(const void*, int, uint32_t, uint32_t* bad) {
    *bad = 0;
    return 0;
}

static Proc find_proc(const SkBitmap& bm, SkPMColor expect32, uint16_t expect16,
                      uint8_t expect8, uint32_t* expect) {
    switch (bm.colorType()) {
        case kN32_SkColorType:
            *expect = expect32;
            return proc_32;
        case kARGB_4444_SkColorType:
        case kRGB_565_SkColorType:
            *expect = expect16;
            return proc_16;
        case kAlpha_8_SkColorType:
            *expect = expect8;
            return proc_8;
        default:
            *expect = 0;
            return proc_bad;
    }
}

static bool check_color(const SkBitmap& bm, SkPMColor expect32,
                        uint16_t expect16, uint8_t expect8,
                        skiatest::Reporter* reporter) {
    uint32_t expect;
    Proc proc = find_proc(bm, expect32, expect16, expect8, &expect);
    for (int y = 0; y < bm.height(); y++) {
        uint32_t bad;
        int x = proc(bm.getAddr(0, y), bm.width(), expect, &bad);
        if (x >= 0) {
            ERRORF(reporter, "BlitRow colortype=%s [%d %d] expected %x got %x",
                   gColorTypeName[bm.colorType()], x, y, expect, bad);
            return false;
        }
    }
    return true;
}

// Make sure our blits always map src==0 to a noop, and src==FF to full opaque
static void test_00_FF(skiatest::Reporter* reporter) {
    static const int W = 256;

    static const SkColorType gDstColorType[] = {
        kN32_SkColorType,
        kRGB_565_SkColorType,
    };

    static const struct {
        SkColor     fSrc;
        SkColor     fDst;
        SkPMColor   fResult32;
        uint16_t    fResult16;
        uint8_t     fResult8;
    } gSrcRec[] = {
        { 0,            0,          0,                                    0,      0 },
        { 0,            0xFFFFFFFF, SkPackARGB32(0xFF, 0xFF, 0xFF, 0xFF), 0xFFFF, 0xFF },
        { 0xFFFFFFFF,   0,          SkPackARGB32(0xFF, 0xFF, 0xFF, 0xFF), 0xFFFF, 0xFF },
        { 0xFFFFFFFF,   0xFFFFFFFF, SkPackARGB32(0xFF, 0xFF, 0xFF, 0xFF), 0xFFFF, 0xFF },
    };

    SkPaint paint;

    SkBitmap srcBM;
    srcBM.allocN32Pixels(W, 1);

    for (size_t i = 0; i < SK_ARRAY_COUNT(gDstColorType); i++) {
        SkImageInfo info = SkImageInfo::Make(W, 1, gDstColorType[i],
                                             kPremul_SkAlphaType);
        SkBitmap dstBM;
        dstBM.allocPixels(info);

        SkCanvas canvas(dstBM);
        for (size_t j = 0; j < SK_ARRAY_COUNT(gSrcRec); j++) {
            srcBM.eraseColor(gSrcRec[j].fSrc);
            dstBM.eraseColor(gSrcRec[j].fDst);

            for (int k = 0; k < 4; k++) {
                bool dither = (k & 1) != 0;
                bool blend = (k & 2) != 0;
                if (gSrcRec[j].fSrc != 0 && blend) {
                    // can't make a numerical promise about blending anything
                    // but 0
                 //   continue;
                }
                paint.setDither(dither);
                paint.setAlpha(blend ? 0x80 : 0xFF);
                canvas.drawBitmap(srcBM, 0, 0, &paint);
                if (!check_color(dstBM, gSrcRec[j].fResult32, gSrcRec[j].fResult16,
                                 gSrcRec[j].fResult8, reporter)) {
                    SkDebugf("--- src index %d dither %d blend %d\n", j, dither, blend);
                }
            }
        }
    }
}

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

struct Mesh {
    SkPoint     fPts[4];

    Mesh(const SkBitmap& bm, SkPaint* paint) {
        const SkScalar w = SkIntToScalar(bm.width());
        const SkScalar h = SkIntToScalar(bm.height());
        fPts[0].set(0, 0);
        fPts[1].set(w, 0);
        fPts[2].set(w, h);
        fPts[3].set(0, h);
        paint->setShader(SkShader::MakeBitmapShader(bm, SkShader::kClamp_TileMode,
                                                    SkShader::kClamp_TileMode));
    }

    void draw(SkCanvas* canvas, SkPaint* paint) {
        canvas->drawVertices(SkCanvas::kTriangleFan_VertexMode, 4, fPts, fPts,
                             nullptr, SkBlendMode::kModulate, nullptr, 0, *paint);
    }
};

#include "SkImageEncoder.h"
static void save_bm(const SkBitmap& bm, const char name[]) {
    sk_tool_utils::EncodeImageToFile(name, bm, SkEncodedImageFormat::kPNG, 100);
}

static bool gOnce;

// Make sure our blits are invariant with the width of the blit (i.e. that
// special case for 8 at a time have the same results as narrower blits)
static void test_diagonal(skiatest::Reporter* reporter) {
    static const int W = 64;
    static const int H = W;

    static const SkColorType gDstColorType[] = {
        kN32_SkColorType,
        kRGB_565_SkColorType,
    };

    static const SkColor gDstBG[] = { 0, 0xFFFFFFFF };
    const SkRect srcR = SkRect::MakeIWH(W, H);

    SkBitmap srcBM;
    srcBM.allocN32Pixels(W, H);
    SkImageInfo info = SkImageInfo::Make(W, H, kUnknown_SkColorType, kPremul_SkAlphaType);

    for (size_t i = 0; i < SK_ARRAY_COUNT(gDstColorType); i++) {
        info = info.makeColorType(gDstColorType[i]);

        SkBitmap dstBM0, dstBM1;
        dstBM0.allocPixels(info);
        dstBM1.allocPixels(info);

        SkCanvas canvas0(dstBM0);
        SkCanvas canvas1(dstBM1);
        SkColor bgColor;

        for (size_t j = 0; j < SK_ARRAY_COUNT(gDstBG); j++) {
            bgColor = gDstBG[j];

            for (int c = 0; c <= 0xFF; c++) {
                // cons up a mesh to draw the bitmap with
                SkPaint paint;
                srcBM.eraseARGB(0xFF, c, c, c);
                Mesh mesh(srcBM, &paint);

                for (int k = 0; k < 4; k++) {
                    bool dither = (k & 1) != 0;
                    uint8_t alpha = (k & 2) ? 0x80 : 0xFF;
                    paint.setDither(dither);
                    paint.setAlpha(alpha);

                    dstBM0.eraseColor(bgColor);
                    dstBM1.eraseColor(bgColor);

                    canvas0.drawRect(srcR, paint);
                    mesh.draw(&canvas1, &paint);

                    if (!gOnce && false) {
                        save_bm(dstBM0, "drawBitmap.png");
                        save_bm(dstBM1, "drawMesh.png");
                        gOnce = true;
                    }

                    if (memcmp(dstBM0.getPixels(), dstBM1.getPixels(), dstBM0.getSize())) {
                        ERRORF(reporter, "Diagonal colortype=%s bg=0x%x dither=%d"
                               " alpha=0x%x src=0x%x",
                               gColorTypeName[gDstColorType[i]], bgColor, dither,
                               alpha, c);
                    }
                }
            }
        }
    }
}

DEF_TEST(BlitRow, reporter) {
    test_00_FF(reporter);
    test_diagonal(reporter);
}
