// Copyright 2018 Google LLC.
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#ifndef SkPDFDocument_DEFINED
#define SkPDFDocument_DEFINED

#include "include/core/SkDocument.h"

#include <vector>

#include "include/core/SkColor.h"
#include "include/core/SkMilestone.h"
#include "include/core/SkScalar.h"
#include "include/core/SkString.h"
#include "include/core/SkTime.h"
#include "include/private/base/SkNoncopyable.h"

#define SKPDF_STRING(X) SKPDF_STRING_IMPL(X)
#define SKPDF_STRING_IMPL(X) #X

class SkExecutor;
class SkPDFArray;
class SkPDFTagTree;

namespace SkPDF {

/** Attributes for nodes in the PDF tree. */
class SK_API AttributeList : SkNoncopyable {
public:
    AttributeList();
    ~AttributeList();

    // Each attribute must have an owner (e.g. "Layout", "List", "Table", etc)
    // and an attribute name (e.g. "BBox", "RowSpan", etc.) from PDF32000_2008 14.8.5,
    // and then a value of the proper type according to the spec.
    void appendInt(const char* owner, const char* name, int value);
    void appendFloat(const char* owner, const char* name, float value);
    void appendName(const char* owner, const char* attrName, const char* value);
    void appendFloatArray(const char* owner,
                          const char* name,
                          const std::vector<float>& value);
    void appendNodeIdArray(const char* owner,
                           const char* attrName,
                           const std::vector<int>& nodeIds);

private:
    friend class ::SkPDFTagTree;

    std::unique_ptr<SkPDFArray> fAttrs;
};

/** A node in a PDF structure tree, giving a semantic representation
    of the content.  Each node ID is associated with content
    by passing the SkCanvas and node ID to SkPDF::SetNodeId() when drawing.
    NodeIDs should be unique within each tree.
*/
struct StructureElementNode {
    SkString fTypeString;
    std::vector<std::unique_ptr<StructureElementNode>> fChildVector;
    int fNodeId = 0;
    std::vector<int> fAdditionalNodeIds;
    AttributeList fAttributes;
    SkString fAlt;
    SkString fLang;
};

/** Optional metadata to be passed into the PDF factory function.
*/
struct Metadata {
    /** The document's title.
    */
    SkString fTitle;

    /** The name of the person who created the document.
    */
    SkString fAuthor;

    /** The subject of the document.
    */
    SkString fSubject;

    /** Keywords associated with the document.  Commas may be used to delineate
        keywords within the string.
    */
    SkString fKeywords;

    /** If the document was converted to PDF from another format,
        the name of the conforming product that created the
        original document from which it was converted.
    */
    SkString fCreator;

    /** The product that is converting this document to PDF.
    */
    SkString fProducer = SkString("Skia/PDF m" SKPDF_STRING(SK_MILESTONE));

    /** The date and time the document was created.
        The zero default value represents an unknown/unset time.
    */
    SkTime::DateTime fCreation = {0, 0, 0, 0, 0, 0, 0, 0};

    /** The date and time the document was most recently modified.
        The zero default value represents an unknown/unset time.
    */
    SkTime::DateTime fModified = {0, 0, 0, 0, 0, 0, 0, 0};

    /** The DPI (pixels-per-inch) at which features without native PDF support
        will be rasterized (e.g. draw image with perspective, draw text with
        perspective, ...)  A larger DPI would create a PDF that reflects the
        original intent with better fidelity, but it can make for larger PDF
        files too, which would use more memory while rendering, and it would be
        slower to be processed or sent online or to printer.
    */
    SkScalar fRasterDPI = SK_ScalarDefaultRasterDPI;

    /** If true, include XMP metadata, a document UUID, and sRGB output intent
        information.  This adds length to the document and makes it
        non-reproducable, but are necessary features for PDF/A-2b conformance
    */
    bool fPDFA = false;

    /** Encoding quality controls the trade-off between size and quality. By
        default this is set to 101 percent, which corresponds to lossless
        encoding. If this value is set to a value <= 100, and the image is
        opaque, it will be encoded (using JPEG) with that quality setting.
    */
    int fEncodingQuality = 101;

    /** An optional tree of structured document tags that provide
        a semantic representation of the content. The caller
        should retain ownership.
    */
    StructureElementNode* fStructureElementTreeRoot = nullptr;

    /** Executor to handle threaded work within PDF Backend. If this is nullptr,
        then all work will be done serially on the main thread. To have worker
        threads assist with various tasks, set this to a valid SkExecutor
        instance. Currently used for executing Deflate algorithm in parallel.

        If set, the PDF output will be non-reproducible in the order and
        internal numbering of objects, but should render the same.

        Experimental.
    */
    SkExecutor* fExecutor = nullptr;

    /** PDF streams may be compressed to save space.
        Use this to specify the desired compression vs time tradeoff.
    */
    enum class CompressionLevel : int {
        Default = -1,
        None = 0,
        LowButFast = 1,
        Average = 6,
        HighButSlow = 9,
    } fCompressionLevel = CompressionLevel::Default;

    /** Preferred Subsetter. Only respected if both are compiled in.

        The Sfntly subsetter is deprecated.

        Experimental.
    */
    enum Subsetter {
        kHarfbuzz_Subsetter,
        kSfntly_Subsetter,
    } fSubsetter = kHarfbuzz_Subsetter;
};

/** Associate a node ID with subsequent drawing commands in an
    SkCanvas.  The same node ID can appear in a StructureElementNode
    in order to associate a document's structure element tree with
    its content.

    A node ID of zero indicates no node ID.

    @param canvas  The canvas used to draw to the PDF.
    @param nodeId  The node ID for subsequent drawing commands.
*/
SK_API void SetNodeId(SkCanvas* dst, int nodeID);

/** Create a PDF-backed document, writing the results into a SkWStream.

    PDF pages are sized in point units. 1 pt == 1/72 inch == 127/360 mm.

    @param stream A PDF document will be written to this stream.  The document may write
           to the stream at anytime during its lifetime, until either close() is
           called or the document is deleted.
    @param metadata a PDFmetadata object.  Any fields may be left empty.

    @returns NULL if there is an error, otherwise a newly created PDF-backed SkDocument.
*/
SK_API sk_sp<SkDocument> MakeDocument(SkWStream* stream, const Metadata& metadata);

static inline sk_sp<SkDocument> MakeDocument(SkWStream* stream) {
    return MakeDocument(stream, Metadata());
}

}  // namespace SkPDF

#undef SKPDF_STRING
#undef SKPDF_STRING_IMPL
#endif  // SkPDFDocument_DEFINED
