/*
 * Copyright 2017 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 "SkAutoPixmapStorage.h"
#include "SkColorPriv.h"
#include "SkImage.h"
#include "SkPath.h"
#include "SkSurface.h"

namespace skiagm {

skiagm::DrawResult draw_diff(SkCanvas* canvas, SkImage* imgA, SkImage* imgB, SkString* errorMsg) {
    SkASSERT(imgA->dimensions() == imgB->dimensions());

    int w = imgA->width(), h = imgA->height();

    // First, draw the two images faintly overlaid
    SkPaint paint;
    paint.setAlphaf(0.25f);
    paint.setBlendMode(SkBlendMode::kPlus);
    canvas->drawImage(imgA, 0, 0, &paint);
    canvas->drawImage(imgB, 0, 0, &paint);

    // Next, read the pixels back, figure out if there are any differences
    SkImageInfo info = SkImageInfo::MakeN32Premul(w, h);
    SkAutoPixmapStorage pmapA;
    SkAutoPixmapStorage pmapB;
    pmapA.alloc(info);
    pmapB.alloc(info);
    if (!imgA->readPixels(pmapA, 0, 0) || !imgB->readPixels(pmapB, 0, 0)) {
        *errorMsg = "Failed to read pixels.";
        return skiagm::DrawResult::kFail;
    }

    int maxDiffX = 0, maxDiffY = 0, maxDiff = 0;
    SkBitmap highlight;
    highlight.allocN32Pixels(w, h);
    highlight.eraseColor(SK_ColorTRANSPARENT);

    for (int y = 0; y < h; ++y) {
        for (int x = 0; x < w; ++x) {
            uint32_t pixelA = *pmapA.addr32(x, y);
            uint32_t pixelB = *pmapB.addr32(x, y);
            if (pixelA != pixelB) {
                int diff =
                    SkTAbs((int)(SkColorGetR(pixelA) - SkColorGetR(pixelB))) +
                    SkTAbs((int)(SkColorGetG(pixelA) - SkColorGetG(pixelB))) +
                    SkTAbs((int)(SkColorGetB(pixelA) - SkColorGetB(pixelB))) +
                    SkTAbs((int)(SkColorGetA(pixelA) - SkColorGetA(pixelB)));
                if (diff > maxDiff) {
                    maxDiffX = x;
                    maxDiffY = y;
                    maxDiff = diff;
                }
                *highlight.getAddr32(x, y) = SkPackARGB32(0xA0, 0xA0, 0x00, 0x00);
            }
        }
    }

    SkPaint outline;
    outline.setStyle(SkPaint::kStroke_Style);
    outline.setColor(maxDiff == 0 ? 0xFF007F00 : 0xFF7F0000);

    if (maxDiff > 0) {
        // Call extra attention to the region we're going to zoom
        SkPMColor yellow = SkPackARGB32(0xFF, 0xFF, 0xFF, 0x00);
        *highlight.getAddr32(maxDiffX, maxDiffY) = yellow;
        *highlight.getAddr32(SkTMax(maxDiffX - 1, 0), maxDiffY) = yellow;
        *highlight.getAddr32(maxDiffX, SkTMax(maxDiffY - 1, 0)) = yellow;
        *highlight.getAddr32(SkTMin(maxDiffX + 1, w - 1), maxDiffY) = yellow;
        *highlight.getAddr32(maxDiffX, SkTMin(maxDiffY + 1, h - 1)) = yellow;

        // Draw the overlay
        canvas->drawBitmap(highlight, 0, 0);

        // Draw zoom of largest pixel diff
        SkBitmap bmpA, bmpB;
        SkAssertResult(bmpA.installPixels(pmapA));
        SkAssertResult(bmpB.installPixels(pmapB));
        canvas->drawBitmapRect(bmpA, SkRect::MakeXYWH(maxDiffX - 5, maxDiffY - 5, 10, 10),
                               SkRect::MakeXYWH(w, 0, w, h), nullptr);
        canvas->drawBitmapRect(bmpB, SkRect::MakeXYWH(maxDiffX - 5, maxDiffY - 5, 10, 10),
                               SkRect::MakeXYWH(2 * w, 0, w, h), nullptr);

        // Add lines to separate zoom boxes
        canvas->drawLine(w, 0, w, h, outline);
        canvas->drawLine(2 * w, 0, 2 * w, h, outline);
    }

    // Draw outline of whole test region
    canvas->drawRect(SkRect::MakeWH(3 * w, h), outline);
    return skiagm::DrawResult::kOk;
}

namespace {
typedef std::function<void(SkCanvas*, const SkRect&, const SkPaint&)> ShapeDrawFunc;
}

/**
 *  Iterates over a variety of rect shapes, paint parameters, and matrices, calling two different
 *  user-supplied draw callbacks. Produces a grid clearly showing if the two callbacks produce the
 *  same visual results in all cases.
 */
static skiagm::DrawResult draw_rect_geom_diff_grid(SkCanvas* canvas, ShapeDrawFunc f1,
                                                   ShapeDrawFunc f2, SkString* errorMsg) {
    // Variables:
    // - Fill, hairline, wide stroke
    // - Axis aligned, rotated, scaled, scaled negative, perspective
    // - Source geometry (normal, collapsed, inverted)
    //
    // Things not (yet?) tested:
    // - AntiAlias on/off
    // - StrokeAndFill
    // - Cap/join
    // - Anything even more elaborate...

    const SkRect kRects[] = {
        SkRect::MakeXYWH(10, 10, 30, 30),  // Normal
        SkRect::MakeXYWH(10, 25, 30, 0),   // Collapsed
        SkRect::MakeXYWH(10, 40, 30, -30), // Inverted
    };

    const struct { SkPaint::Style fStyle; SkScalar fStrokeWidth; } kStyles[] = {
        { SkPaint::kFill_Style, 0 },   // Filled
        { SkPaint::kStroke_Style, 0 }, // Hairline
        { SkPaint::kStroke_Style, 5 }, // Wide stroke
    };

    SkMatrix mI = SkMatrix::I();
    SkMatrix mRot;
    mRot.setRotate(30, 25, 25);
    SkMatrix mScale;
    mScale.setScaleTranslate(0.5f, 1, 12.5f, 0);
    SkMatrix mFlipX;
    mFlipX.setScaleTranslate(-1, 1, 50, 0);
    SkMatrix mFlipY;
    mFlipY.setScaleTranslate(1, -1, 0, 50);
    SkMatrix mFlipXY;
    mFlipXY.setScaleTranslate(-1, -1, 50, 50);
    SkMatrix mPersp;
    mPersp.setIdentity();
    mPersp.setPerspY(0.002f);

    const SkMatrix* kMatrices[] = { &mI, &mRot, &mScale, &mFlipX, &mFlipY, &mFlipXY, &mPersp, };

    canvas->translate(10, 10);

    SkImageInfo info = canvas->imageInfo().makeWH(50, 50);
    auto surface = canvas->makeSurface(info);
    if (!surface) {
        surface = SkSurface::MakeRasterN32Premul(50, 50);
    }

    for (const SkRect& rect : kRects) {
        for (const auto& style : kStyles) {
            canvas->save();

            for (const SkMatrix* mat : kMatrices) {
                SkPaint paint;
                paint.setColor(SK_ColorWHITE);
                paint.setAntiAlias(true);
                paint.setStyle(style.fStyle);
                paint.setStrokeWidth(style.fStrokeWidth);

                // Do first draw
                surface->getCanvas()->clear(SK_ColorBLACK);
                surface->getCanvas()->save();
                surface->getCanvas()->concat(*mat);
                f1(surface->getCanvas(), rect, paint);
                surface->getCanvas()->restore();
                auto imgA = surface->makeImageSnapshot();

                // Do second draw
                surface->getCanvas()->clear(SK_ColorBLACK);
                surface->getCanvas()->save();
                surface->getCanvas()->concat(*mat);
                f2(surface->getCanvas(), rect, paint);
                surface->getCanvas()->restore();
                auto imgB = surface->makeImageSnapshot();

                skiagm::DrawResult drawResult = draw_diff(canvas, imgA.get(), imgB.get(), errorMsg);
                if (skiagm::DrawResult::kOk != drawResult) {
                    return drawResult;
                }
                canvas->translate(160, 0);
            }
            canvas->restore();
            canvas->translate(0, 60);
        }
    }
    return skiagm::DrawResult::kOk;
}

static const int kNumRows = 9;
static const int kNumColumns = 7;
static const int kTotalWidth = kNumColumns * 160 + 10;
static const int kTotalHeight = kNumRows * 60 + 10;

DEF_SIMPLE_GM_BG_CAN_FAIL(rects_as_paths, canvas, errorMsg, kTotalWidth, kTotalHeight,
                          SK_ColorBLACK) {
    // Drawing a rect vs. adding it to a path and drawing the path, should produce same results.
    auto rectDrawFunc = [](SkCanvas* canvas, const SkRect& rect, const SkPaint& paint) {
        canvas->drawRect(rect, paint);
    };
    auto pathDrawFunc = [](SkCanvas* canvas, const SkRect& rect, const SkPaint& paint) {
        SkPath path;
        path.addRect(rect);
        canvas->drawPath(path, paint);
    };

    return draw_rect_geom_diff_grid(canvas, rectDrawFunc, pathDrawFunc, errorMsg);
}

DEF_SIMPLE_GM_BG_CAN_FAIL(ovals_as_paths, canvas, errorMsg, kTotalWidth, kTotalHeight,
                          SK_ColorBLACK) {
    // Drawing an oval vs. adding it to a path and drawing the path, should produce same results.
    auto ovalDrawFunc = [](SkCanvas* canvas, const SkRect& rect, const SkPaint& paint) {
        canvas->drawOval(rect, paint);
    };
    auto pathDrawFunc = [](SkCanvas* canvas, const SkRect& rect, const SkPaint& paint) {
        SkPath path;
        path.addOval(rect);
        canvas->drawPath(path, paint);
    };

    return draw_rect_geom_diff_grid(canvas, ovalDrawFunc, pathDrawFunc, errorMsg);
}

DEF_SIMPLE_GM_BG_CAN_FAIL(arcs_as_paths, canvas, errorMsg, kTotalWidth, kTotalHeight,
                          SK_ColorBLACK) {
    // Drawing an arc vs. adding it to a path and drawing the path, should produce same results.
    auto arcDrawFunc = [](SkCanvas* canvas, const SkRect& rect, const SkPaint& paint) {
        canvas->drawArc(rect, 10, 200, false, paint);
    };
    auto pathDrawFunc = [](SkCanvas* canvas, const SkRect& rect, const SkPaint& paint) {
        SkPath path;
        path.addArc(rect, 10, 200);
        canvas->drawPath(path, paint);
    };

    return draw_rect_geom_diff_grid(canvas, arcDrawFunc, pathDrawFunc, errorMsg);
}

}
