/*
 * Copyright 2010 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkPDFTypes_DEFINED
#define SkPDFTypes_DEFINED

#include "SkRefCnt.h"
#include "SkScalar.h"
#include "SkString.h"
#include "SkTDArray.h"
#include "SkTHash.h"
#include "SkTypes.h"

class SkPDFObjNumMap;
class SkPDFObject;
class SkPDFSubstituteMap;
class SkWStream;

/** \class SkPDFObject

    A PDF Object is the base class for primitive elements in a PDF file.  A
    common subtype is used to ease the use of indirect object references,
    which are common in the PDF format.

*/
class SkPDFObject : public SkRefCnt {
public:
    SK_DECLARE_INST_COUNT(SkPDFObject);

    /** Subclasses must implement this method to print the object to the
     *  PDF file.
     *  @param catalog  The object catalog to use.
     *  @param stream   The writable output stream to send the output to.
     */
    // TODO(halcanary): make this method const
    virtual void emitObject(SkWStream* stream,
                            const SkPDFObjNumMap& objNumMap,
                            const SkPDFSubstituteMap& substitutes) = 0;

    /**
     *  Adds all transitive dependencies of this object to the
     *  catalog.  Implementations should respect the catalog's object
     *  substitution map.
     */
    virtual void addResources(SkPDFObjNumMap* catalog,
                              const SkPDFSubstituteMap& substitutes) const {}

private:
    typedef SkRefCnt INHERITED;
};

////////////////////////////////////////////////////////////////////////////////

/**
   A SkPDFUnion is a non-virtualized implementation of the
   non-compound, non-specialized PDF Object types: Name, String,
   Number, Boolean.
 */
class SkPDFUnion {
public:
    // u.move() is analogous to std::move(u). It returns an rvalue.
    SkPDFUnion move() { return static_cast<SkPDFUnion&&>(*this); }
    // Move contstructor and assignemnt operator destroy the argument
    // and steal their references (if needed).
    SkPDFUnion(SkPDFUnion&& other);
    SkPDFUnion& operator=(SkPDFUnion&& other);

    ~SkPDFUnion();

    /** The following nine functions are the standard way of creating
        SkPDFUnion objects. */

    static SkPDFUnion Int(int32_t);

    static SkPDFUnion Int(size_t);

    static SkPDFUnion Bool(bool);

    static SkPDFUnion Scalar(SkScalar);

    /** These two functions do NOT take ownership of ptr, and do NOT
        copy the string.  Suitable for passing in static const
        strings. For example:
          SkPDFUnion n = SkPDFUnion::Name("Length");
          SkPDFUnion u = SkPDFUnion::String("Identity"); */

    /** SkPDFUnion::Name(const char*) assumes that the passed string
        is already a valid name (that is: it has no control or
        whitespace characters).  This will not copy the name. */
    static SkPDFUnion Name(const char*);

    /** SkPDFUnion::String will encode the passed string.  This will
        not copy the name. */
    static SkPDFUnion String(const char*);

    /** SkPDFUnion::Name(const SkString&) does not assume that the
        passed string is already a valid name and it will escape the
        string. */
    static SkPDFUnion Name(const SkString&);

    /** SkPDFUnion::String will encode the passed string. */
    static SkPDFUnion String(const SkString&);

    /** This function DOES take ownership of the object. E.g.
          SkAutoTUnref<SkPDFDict> dict(new SkPDFDict);
          dict->insert(.....);
          SkPDFUnion u = SkPDFUnion::Object(dict.detach()) */
    static SkPDFUnion Object(SkPDFObject*);

    /** This function DOES take ownership of the object. E.g.
          SkAutoTUnref<SkPDFBitmap> image(
                 SkPDFBitmap::Create(fCanon, bitmap));
          SkPDFUnion u = SkPDFUnion::ObjRef(image.detach()) */
    static SkPDFUnion ObjRef(SkPDFObject*);

    /** These two non-virtual methods mirror SkPDFObject's
        corresponding virtuals. */
    void emitObject(SkWStream*,
                    const SkPDFObjNumMap&,
                    const SkPDFSubstituteMap&) const;
    void addResources(SkPDFObjNumMap*, const SkPDFSubstituteMap&) const;

    bool isName() const;

private:
    union {
        int32_t fIntValue;
        bool fBoolValue;
        SkScalar fScalarValue;
        const char* fStaticString;
        char fSkString[sizeof(SkString)];
        SkPDFObject* fObject;
    };
    enum class Type : char {
        /** It is an error to call emitObject() or addResources() on an
            kDestroyed object. */
        kDestroyed = 0,
        kInt,
        kBool,
        kScalar,
        kName,
        kString,
        kNameSkS,
        kStringSkS,
        kObjRef,
        kObject,
    };
    Type fType;

    SkPDFUnion(Type);
    // We do not now need copy constructor and copy assignment, so we
    // will disable this functionality.
    SkPDFUnion& operator=(const SkPDFUnion&) = delete;
    SkPDFUnion(const SkPDFUnion&) = delete;
};
SK_COMPILE_ASSERT(sizeof(SkString) == sizeof(void*), SkString_size);

////////////////////////////////////////////////////////////////////////////////

#if 0  // Enable if needed.
/** This class is a SkPDFUnion with SkPDFObject virtuals attached.
    The only use case of this is when a non-compound PDF object is
    referenced indirectly. */
class SkPDFAtom : public SkPDFObject {
public:
    void emitObject(SkWStream* stream,
                    const SkPDFObjNumMap& objNumMap,
                    const SkPDFSubstituteMap& substitutes) final;
    void addResources(SkPDFObjNumMap*, const SkPDFSubstituteMap&) const final;
    SkPDFAtom(SkPDFUnion&& v) : fValue(v.move()) {}

private:
    const SkPDFUnion fValue;
    typedef SkPDFObject INHERITED;
};
#endif  // 0

////////////////////////////////////////////////////////////////////////////////

/** \class SkPDFArray

    An array object in a PDF.
*/
class SkPDFArray : public SkPDFObject {
public:
    SK_DECLARE_INST_COUNT(SkPDFArray)

    static const int kMaxLen = 8191;

    /** Create a PDF array. Maximum length is 8191.
     */
    SkPDFArray();
    virtual ~SkPDFArray();

    // The SkPDFObject interface.
    void emitObject(SkWStream* stream,
                    const SkPDFObjNumMap& objNumMap,
                    const SkPDFSubstituteMap& substitutes) override;
    void addResources(SkPDFObjNumMap*,
                      const SkPDFSubstituteMap&) const override;

    /** The size of the array.
     */
    int size() const;

    /** Preallocate space for the given number of entries.
     *  @param length The number of array slots to preallocate.
     */
    void reserve(int length);

    /** Appends a value to the end of the array.
     *  @param value The value to add to the array.
     */
    void appendInt(int32_t);
    void appendBool(bool);
    void appendScalar(SkScalar);
    void appendName(const char[]);
    void appendName(const SkString&);
    void appendString(const char[]);
    void appendString(const SkString&);
    /** appendObject and appendObjRef take ownership of the passed object */
    void appendObject(SkPDFObject*);
    void appendObjRef(SkPDFObject*);

private:
    SkTDArray<SkPDFUnion> fValues;
    void append(SkPDFUnion&& value);
    typedef SkPDFObject INHERITED;
};

/** \class SkPDFDict

    A dictionary object in a PDF.
*/
class SkPDFDict : public SkPDFObject {
public:
    SK_DECLARE_INST_COUNT(SkPDFDict)

    /** Create a PDF dictionary. Maximum number of entries is 4095.
     */
    SkPDFDict();

    /** Create a PDF dictionary with a Type entry.
     *  @param type   The value of the Type entry.
     */
    explicit SkPDFDict(const char type[]);

    virtual ~SkPDFDict();

    // The SkPDFObject interface.
    void emitObject(SkWStream* stream,
                    const SkPDFObjNumMap& objNumMap,
                    const SkPDFSubstituteMap& substitutes) override;
    void addResources(SkPDFObjNumMap*,
                      const SkPDFSubstituteMap&) const override;

    /** The size of the dictionary.
     */
    int size() const;

    /** Add the value to the dictionary with the given key.  Takes
     *  ownership of the object.
     *  @param key   The text of the key for this dictionary entry.
     *  @param value The value for this dictionary entry.
     */
    void insertObject(const char key[], SkPDFObject* value);
    void insertObject(const SkString& key, SkPDFObject* value);
    void insertObjRef(const char key[], SkPDFObject* value);
    void insertObjRef(const SkString& key, SkPDFObject* value);

    /** Add the value to the dictionary with the given key.
     *  @param key   The text of the key for this dictionary entry.
     *  @param value The value for this dictionary entry.
     */
    void insertBool(const char key[], bool value);
    void insertInt(const char key[], int32_t value);
    void insertInt(const char key[], size_t value);
    void insertScalar(const char key[], SkScalar value);
    void insertName(const char key[], const char nameValue[]);
    void insertName(const char key[], const SkString& nameValue);
    void insertString(const char key[], const char value[]);
    void insertString(const char key[], const SkString& value);

    /** Remove all entries from the dictionary.
     */
    void clear();

private:
    struct Record {
        SkPDFUnion fKey;
        SkPDFUnion fValue;
    };
    SkTDArray<Record> fRecords;
    static const int kMaxLen = 4095;

    void set(SkPDFUnion&& name, SkPDFUnion&& value);

    typedef SkPDFObject INHERITED;
};

////////////////////////////////////////////////////////////////////////////////

/** \class SkPDFObjNumMap

    The PDF Object Number Map manages object numbers.  It is used to
    create the PDF cross reference table.
*/
class SkPDFObjNumMap : SkNoncopyable {
public:
    /** Add the passed object to the catalog.
     *  @param obj         The object to add.
     *  @return True iff the object was not already added to the catalog.
     */
    bool addObject(SkPDFObject* obj);

    /** Get the object number for the passed object.
     *  @param obj         The object of interest.
     */
    int32_t getObjectNumber(SkPDFObject* obj) const;

    const SkTDArray<SkPDFObject*>& objects() const { return fObjects; }

private:
    SkTDArray<SkPDFObject*> fObjects;
    SkTHashMap<SkPDFObject*, int32_t> fObjectNumbers;
};

////////////////////////////////////////////////////////////////////////////////

/** \class SkPDFSubstituteMap

    The PDF Substitute Map manages substitute objects and owns the
    substitutes.
*/
class SkPDFSubstituteMap : SkNoncopyable {
public:
    ~SkPDFSubstituteMap();
    /** Set substitute object for the passed object.
        Refs substitute.
     */
    void setSubstitute(SkPDFObject* original, SkPDFObject* substitute);

    /** Find and return any substitute object set for the passed object. If
     *  there is none, return the passed object.
     */
    SkPDFObject* getSubstitute(SkPDFObject* object) const;

    SkPDFObject* operator()(SkPDFObject* o) const {
        return this->getSubstitute(o);
    }

private:
    SkTHashMap<SkPDFObject*, SkPDFObject*> fSubstituteMap;
};

#endif
