/*
 * Copyright 2020 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "tests/Test.h"

#include "include/core/SkCanvas.h"
#include "include/core/SkFont.h"
#include "include/core/SkStream.h"
#include "include/docs/SkPDFDocument.h"

using PDFTag = SkPDF::StructureElementNode;

// Test building a tagged PDF containing a table.
// Add this to args.gn to output the PDF to a file:
//   extra_cflags = [ "-DSK_PDF_TEST_TAGS_OUTPUT_PATH=\"/tmp/table.pdf\"" ]
DEF_TEST(SkPDF_tagged_table, r) {
    REQUIRE_PDF_DOCUMENT(SkPDF_tagged, r);
#ifdef SK_PDF_TEST_TAGS_OUTPUT_PATH
    SkFILEWStream outputStream(SK_PDF_TEST_TAGS_OUTPUT_PATH);
#else
    SkDynamicMemoryWStream outputStream;
#endif

    SkSize pageSize = SkSize::Make(612, 792);  // U.S. Letter

    SkPDF::Metadata metadata;
    metadata.fTitle = "Example Tagged Table PDF";
    metadata.fCreator = "Skia";
    SkTime::DateTime now;
    SkTime::GetDateTime(&now);
    metadata.fCreation = now;
    metadata.fModified = now;

    constexpr int kRowCount = 5;
    constexpr int kColCount = 4;
    const char* cellData[kRowCount * kColCount] = {
        "Car",                  "Engine",   "City MPG", "Highway MPG",
        "Mitsubishi Mirage ES", "Gas",      "28",       "47",
        "Toyota Prius Three",   "Hybrid",   "43",       "59",
        "Nissan Leaf SL",       "Electric", "N/A",      nullptr,
        "Tesla Model 3",        nullptr,    "N/A",      nullptr
    };

    // The document tag.
    PDFTag root;
    root.fNodeId = 1;
    root.fType = SkPDF::DocumentStructureType::kDocument;
    root.fChildCount = 2;
    PDFTag rootChildren[2];

    // Heading.
    PDFTag& h1 = rootChildren[0];
    h1.fNodeId = 2;
    h1.fType = SkPDF::DocumentStructureType::kH1;
    h1.fChildCount = 0;

    // Table.
    PDFTag& table = rootChildren[1];
    table.fNodeId = 3;
    table.fType = SkPDF::DocumentStructureType::kTable;
    table.fChildCount = 5;
    table.fAttributes.appendFloatArray("Layout", "BBox", {72, 72, 360, 360});

    PDFTag rows[kRowCount];
    PDFTag all_cells[kRowCount * kColCount];
    for (int rowIndex = 0; rowIndex < kRowCount; rowIndex++) {
        PDFTag& row = rows[rowIndex];
        row.fNodeId = 4 + rowIndex;
        row.fType = SkPDF::DocumentStructureType::kTR;
        row.fChildCount = kColCount;
        PDFTag* cells = &all_cells[rowIndex * kColCount];

        for (int colIndex = 0; colIndex < kColCount; colIndex++) {
            int cellIndex = rowIndex * kColCount + colIndex;
            PDFTag& cell = cells[colIndex];
            cell.fNodeId = 10 + cellIndex;
            if (!cellData[cellIndex])
                cell.fType = SkPDF::DocumentStructureType::kNonStruct;
            else if (rowIndex == 0 || colIndex == 0)
                cell.fType = SkPDF::DocumentStructureType::kTH;
            else
                cell.fType = SkPDF::DocumentStructureType::kTD;
            cell.fChildCount = 0;

            if (cellIndex == 13) {
                cell.fAttributes.appendInt("Table", "RowSpan", 2);
            } else if (cellIndex == 14 || cellIndex == 18) {
                cell.fAttributes.appendInt("Table", "ColSpan", 2);
            } else if (cell.fType == SkPDF::DocumentStructureType::kTH) {
                cell.fAttributes.appendString(
                    "Table", "Scope", rowIndex == 0 ? "Column" : "Row");
            }
        }
        row.fChildren = cells;
    }
    table.fChildren = rows;
    root.fChildren = rootChildren;

    metadata.fStructureElementTreeRoot = &root;
    sk_sp<SkDocument> document = SkPDF::MakeDocument(
        &outputStream, metadata);

    SkPaint paint;
    paint.setColor(SK_ColorBLACK);

    SkCanvas* canvas =
            document->beginPage(pageSize.width(),
                                pageSize.height());
    SkPDF::SetNodeId(canvas, 2);
    SkFont font(nullptr, 36);
    canvas->drawString("Tagged PDF Table", 72, 72, font, paint);

    font.setSize(14);
    for (int rowIndex = 0; rowIndex < kRowCount; rowIndex++) {
        for (int colIndex = 0; colIndex < kColCount; colIndex++) {
            int cellIndex = rowIndex * kColCount + colIndex;
            const char* str = cellData[cellIndex];
            if (!str)
                continue;

            int x = 72 + colIndex * 108 + (colIndex > 0 ? 72 : 0);
            int y = 144 + rowIndex * 48;

            SkPDF::SetNodeId(canvas, 10 + cellIndex);
            canvas->drawString(str, x, y, font, paint);
        }
    }

    document->endPage();
    document->close();
    outputStream.flush();
}
