/*
 * Copyright 2015 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/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorPriv.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GrDirectContext.h"
#include "include/utils/SkParsePath.h"
#include "src/core/SkAutoPixmapStorage.h"

// GM to test combinations of stroking zero length paths with different caps and other settings
// Variables:
// * Antialiasing: On, Off
// * Caps: Butt, Round, Square
// * Stroke width: 0, 0.9, 1, 1.1, 15, 25
// * Path form: M, ML, MLZ, MZ
// * Path contours: 1 or 2
// * Path verbs: Line, Quad, Cubic, Conic
//
// Each test is drawn to a 50x20 offscreen surface, and expected to produce some number (0 - 2) of
// visible pieces of cap geometry. These are counted by scanning horizontally for peaks (blobs).

static bool draw_path_cell(GrDirectContext* dContext, SkCanvas* canvas, SkImage* img,
                           int expectedCaps) {
    // Draw the image
    canvas->drawImage(img, 0, 0);

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

    // Read the pixels back
    SkImageInfo info = SkImageInfo::MakeN32Premul(w, h);
    SkAutoPixmapStorage pmap;
    pmap.alloc(info);
    if (!img->readPixels(dContext, pmap, 0, 0)) {
        return false;
    }

    // To account for rasterization differences, we scan the middle two rows [y, y+1] of the image
    SkASSERT(h % 2 == 0);
    int y = (h - 1) / 2;

    bool inBlob = false;
    int numBlobs = 0;
    for (int x = 0; x < w; ++x) {
        // We drew white-on-black. We can look for any non-zero value. Just check red.
        // And we care if either row is non-zero, so just add them to simplify everything.
        uint32_t v = SkGetPackedR32(*pmap.addr32(x, y)) + SkGetPackedR32(*pmap.addr32(x, y + 1));

        if (!inBlob && v) {
            ++numBlobs;
        }
        inBlob = SkToBool(v);
    }

    SkPaint outline;
    outline.setStyle(SkPaint::kStroke_Style);
    if (numBlobs == expectedCaps) {
        outline.setColor(0xFF007F00); // Green
    } else if (numBlobs > expectedCaps) {
        outline.setColor(0xFF7F7F00); // Yellow -- more geometry than expected
    } else {
        outline.setColor(0xFF7F0000); // Red -- missing some geometry
    }

    canvas->drawRect(SkRect::MakeWH(w, h), outline);
    return numBlobs == expectedCaps;
}

static const SkPaint::Cap kCaps[] = {
    SkPaint::kButt_Cap,
    SkPaint::kRound_Cap,
    SkPaint::kSquare_Cap
};

static const SkScalar kWidths[] = { 0.0f, 0.9f, 1.0f, 1.1f, 15.0f, 25.0f };

// Full set of path structures for single contour case (each primitive with and without a close)
static const char* kAllVerbs[] = {
    nullptr,
    "z ",
    "l 0 0 ",
    "l 0 0 z ",
    "q 0 0 0 0 ",
    "q 0 0 0 0 z ",
    "c 0 0 0 0 0 0 ",
    "c 0 0 0 0 0 0 z ",
    "a 0 0 0 0 0 0 0 ",
    "a 0 0 0 0 0 0 0 z "
};

// Reduced set of path structures for double contour case, to keep total number of cases down
static const char* kSomeVerbs[] = {
    nullptr,
    "z ",
    "l 0 0 ",
    "l 0 0 z ",
    "q 0 0 0 0 ",
    "q 0 0 0 0 z ",
};

static const int kCellWidth = 50;
static const int kCellHeight = 20;
static const int kCellPad = 2;

static const int kNumRows = SK_ARRAY_COUNT(kCaps) * SK_ARRAY_COUNT(kWidths);
static const int kNumColumns = SK_ARRAY_COUNT(kAllVerbs);
static const int kTotalWidth = kNumColumns * (kCellWidth + kCellPad) + kCellPad;
static const int kTotalHeight = kNumRows * (kCellHeight + kCellPad) + kCellPad;

static const int kDblContourNumColums = SK_ARRAY_COUNT(kSomeVerbs) * SK_ARRAY_COUNT(kSomeVerbs);
static const int kDblContourTotalWidth = kDblContourNumColums * (kCellWidth + kCellPad) + kCellPad;

// 50% transparent versions of the colors used for positive/negative triage icons on gold.skia.org
static const SkColor kFailureRed = 0x7FE7298A;
static const SkColor kSuccessGreen = 0x7F1B9E77;

static skiagm::DrawResult draw_zero_length_capped_paths(SkCanvas* canvas, bool aa,
                                                        SkString* errorMsg) {
    auto rContext = canvas->recordingContext();
    auto dContext = GrAsDirectContext(rContext);

    if (!dContext && rContext) {
        *errorMsg = "Not supported in DDL mode";
        return skiagm::DrawResult::kSkip;
    }

    canvas->translate(kCellPad, kCellPad);

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

    SkPaint paint;
    paint.setColor(SK_ColorWHITE);
    paint.setAntiAlias(aa);
    paint.setStyle(SkPaint::kStroke_Style);

    int numFailedTests = 0;
    for (auto cap : kCaps) {
        for (auto width : kWidths) {
            paint.setStrokeCap(cap);
            paint.setStrokeWidth(width);
            canvas->save();

            for (auto verb : kAllVerbs) {
                SkString pathStr;
                pathStr.appendf("M %f %f ", (kCellWidth - 1) * 0.5f, (kCellHeight - 1) * 0.5f);
                if (verb) {
                    pathStr.append(verb);
                }

                SkPath path;
                SkParsePath::FromSVGString(pathStr.c_str(), &path);

                surface->getCanvas()->clear(SK_ColorTRANSPARENT);
                surface->getCanvas()->drawPath(path, paint);
                auto img = surface->makeImageSnapshot();

                // All cases should draw one cap, except for butt capped, and dangling moves
                // (without a verb or close), which shouldn't draw anything.
                int expectedCaps = ((SkPaint::kButt_Cap == cap) || !verb) ? 0 : 1;

                if (!draw_path_cell(dContext, canvas, img.get(), expectedCaps)) {
                    ++numFailedTests;
                }
                canvas->translate(kCellWidth + kCellPad, 0);
            }
            canvas->restore();
            canvas->translate(0, kCellHeight + kCellPad);
        }
    }

    canvas->drawColor(numFailedTests > 0 ? kFailureRed : kSuccessGreen);
    return skiagm::DrawResult::kOk;
}

DEF_SIMPLE_GM_BG_CAN_FAIL(zero_length_paths_aa, canvas, errorMsg,
                          kTotalWidth, kTotalHeight, SK_ColorBLACK) {
    return draw_zero_length_capped_paths(canvas, true, errorMsg);
}

DEF_SIMPLE_GM_BG_CAN_FAIL(zero_length_paths_bw, canvas, errorMsg,
                          kTotalWidth, kTotalHeight, SK_ColorBLACK) {
    return draw_zero_length_capped_paths(canvas, false, errorMsg);
}

static skiagm::DrawResult draw_zero_length_capped_paths_dbl_contour(SkCanvas* canvas, bool aa,
                                                                    SkString* errorMsg) {
    auto rContext = canvas->recordingContext();
    auto dContext = GrAsDirectContext(rContext);

    if (!dContext && rContext) {
        *errorMsg = "Not supported in DDL mode";
        return skiagm::DrawResult::kSkip;
    }
    canvas->translate(kCellPad, kCellPad);

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

    SkPaint paint;
    paint.setColor(SK_ColorWHITE);
    paint.setAntiAlias(aa);
    paint.setStyle(SkPaint::kStroke_Style);

    int numFailedTests = 0;
    for (auto cap : kCaps) {
        for (auto width : kWidths) {
            paint.setStrokeCap(cap);
            paint.setStrokeWidth(width);
            canvas->save();

            for (auto firstVerb : kSomeVerbs) {
                for (auto secondVerb : kSomeVerbs) {
                    int expectedCaps = 0;

                    SkString pathStr;
                    pathStr.append("M 9.5 9.5 ");
                    if (firstVerb) {
                        pathStr.append(firstVerb);
                        ++expectedCaps;
                    }
                    pathStr.append("M 40.5 9.5 ");
                    if (secondVerb) {
                        pathStr.append(secondVerb);
                        ++expectedCaps;
                    }

                    SkPath path;
                    SkParsePath::FromSVGString(pathStr.c_str(), &path);

                    surface->getCanvas()->clear(SK_ColorTRANSPARENT);
                    surface->getCanvas()->drawPath(path, paint);
                    auto img = surface->makeImageSnapshot();

                    if (SkPaint::kButt_Cap == cap) {
                        expectedCaps = 0;
                    }

                    if (!draw_path_cell(dContext, canvas, img.get(), expectedCaps)) {
                        ++numFailedTests;
                    }
                    canvas->translate(kCellWidth + kCellPad, 0);
                }
            }
            canvas->restore();
            canvas->translate(0, kCellHeight + kCellPad);
        }
    }

    canvas->drawColor(numFailedTests > 0 ? kFailureRed : kSuccessGreen);
    return skiagm::DrawResult::kOk;
}

DEF_SIMPLE_GM_BG_CAN_FAIL(zero_length_paths_dbl_aa, canvas, errorMsg,
                          kDblContourTotalWidth, kTotalHeight, SK_ColorBLACK) {
    return draw_zero_length_capped_paths_dbl_contour(canvas, true, errorMsg);
}

DEF_SIMPLE_GM_BG_CAN_FAIL(zero_length_paths_dbl_bw, canvas, errorMsg,
                          kDblContourTotalWidth, kTotalHeight, SK_ColorBLACK) {
    return draw_zero_length_capped_paths_dbl_contour(canvas, false, errorMsg);
}
