/*
 * Copyright 2016 Google Inc.
 *
 * 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 "SkDocument.h"
#include "SkPDFCanon.h"
#include "SkPDFMetadata.h"
#include "SkPDFFont.h"

class SkPDFDevice;

/*  @param rasterDpi the DPI 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.  A good choice is
 *         SK_ScalarDefaultRasterDPI(72.0f).
 */
sk_sp<SkDocument> SkPDFMakeDocument(SkWStream* stream,
                                    const SkDocument::PDFMetadata&);

// Logically part of SkPDFDocument (like SkPDFCanon), but separate to
// keep similar functionality together.
struct SkPDFObjectSerializer : SkNoncopyable {
    SkPDFObjNumMap fObjNumMap;
    SkTDArray<int32_t> fOffsets;
    sk_sp<SkPDFObject> fInfoDict;
    size_t fBaseOffset;
    int32_t fNextToBeSerialized;  // index in fObjNumMap

    SkPDFObjectSerializer();
    ~SkPDFObjectSerializer();
    SkPDFObjectSerializer(SkPDFObjectSerializer&&);
    SkPDFObjectSerializer& operator=(SkPDFObjectSerializer&&);

    void addObjectRecursively(const sk_sp<SkPDFObject>&);
    void serializeHeader(SkWStream*, const SkDocument::PDFMetadata&);
    void serializeObjects(SkWStream*);
    void serializeFooter(SkWStream*, const sk_sp<SkPDFObject>, sk_sp<SkPDFObject>);
    int32_t offset(SkWStream*);
};

/** Concrete implementation of SkDocument that creates PDF files. This
    class does not produced linearized or optimized PDFs; instead it
    it attempts to use a minimum amount of RAM. */
class SkPDFDocument : public SkDocument {
public:
    SkPDFDocument(SkWStream*,
                  const SkDocument::PDFMetadata&);
    ~SkPDFDocument() override;
    SkCanvas* onBeginPage(SkScalar, SkScalar) override;
    void onEndPage() override;
    void onClose(SkWStream*) override;
    void onAbort() override;

    /**
       Serialize the object, as well as any other objects it
       indirectly refers to.  If any any other objects have been added
       to the SkPDFObjNumMap without serializing them, they will be
       serialized as well.

       It might go without saying that objects should not be changed
       after calling serialize, since those changes will be too late.
     */
    void serialize(const sk_sp<SkPDFObject>&);
    SkPDFCanon* canon() { return &fCanon; }
    SkScalar rasterDpi() const { return fMetadata.fRasterDPI; }
    void registerFont(SkPDFFont* f) { fFonts.add(f); }
    const PDFMetadata& metadata() const { return fMetadata; }

private:
    SkPDFObjectSerializer fObjectSerializer;
    SkPDFCanon fCanon;
    SkTArray<sk_sp<SkPDFDict>> fPages;
    SkTHashSet<SkPDFFont*> fFonts;
    sk_sp<SkPDFDict> fDests;
    sk_sp<SkPDFDevice> fPageDevice;
    std::unique_ptr<SkCanvas> fCanvas;
    sk_sp<SkPDFObject> fID;
    sk_sp<SkPDFObject> fXMP;
    SkDocument::PDFMetadata fMetadata;

    void reset();
};

#endif  // SkPDFDocument_DEFINED
