/*
 * 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.setAlpha(64);
    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);
}

}
