/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.fop.pdf;

// Java
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.pdf.StandardStructureAttributes.Table.Scope;
import org.apache.fop.pdf.xref.CrossReferenceStream;
import org.apache.fop.pdf.xref.CrossReferenceTable;
import org.apache.fop.pdf.xref.TrailerDictionary;

/* image support modified from work of BoBoGi */
/* font support based on work by Takayuki Takeuchi */

/**
 * Class representing a PDF document.
 *
 * The document is built up by calling various methods and then finally
 * output to given filehandle using output method.
 *
 * A PDF document consists of a series of numbered objects preceded by a
 * header and followed by an xref table and trailer. The xref table
 * allows for quick access to objects by listing their character
 * positions within the document. For this reason the PDF document must
 * keep track of the character position of each object.  The document
 * also keeps direct track of the /Root, /Info and /Resources objects.
 *
 * Modified by Mark Lillywhite, mark-fop@inomial.com. The changes
 * involve: ability to output pages one-at-a-time in a streaming
 * fashion (rather than storing them all for output at the end);
 * ability to write the /Pages object after writing the rest
 * of the document; ability to write to a stream and flush
 * the object list; enhanced trailer output; cleanups.
 *
 */
public class PDFDocument {

    /** the encoding to use when converting strings to PDF commands */
    public static final String ENCODING = "ISO-8859-1";

    /** the counter for object numbering */
    protected int objectcount;

    /** the logger instance */
    private Log log = LogFactory.getLog("org.apache.fop.pdf");

    /** the current character position */
    protected long position;

    /** the character position of each object */
    protected List<Long> indirectObjectOffsets = new ArrayList<Long>();

    protected List<PDFStructElem> structureTreeElements;

    /** List of objects to write in the trailer */
    protected List<PDFObject> trailerObjects = new ArrayList<PDFObject>();

    /** the objects themselves */
    protected List<PDFObject> objects = new LinkedList<PDFObject>();

    /** Controls the PDF version of this document */
    private VersionController versionController;

    /** Indicates which PDF profiles are active (PDF/A, PDF/X etc.) */
    private PDFProfile pdfProfile = new PDFProfile(this);

    /** the /Root object */
    private PDFRoot root;

    /** The root outline object */
    private PDFOutline outlineRoot;

    /** The /Pages object (mark-fop@inomial.com) */
    private PDFPages pages;

    /** the /Info object */
    private PDFInfo info;

    /** the /Resources object */
    private PDFResources resources;

    /** the document's encryption, if it exists */
    private PDFEncryption encryption;

    /** the colorspace (0=RGB, 1=CMYK) */
    private PDFDeviceColorSpace colorspace
        = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);

    /** the counter for Pattern name numbering (e.g. 'Pattern1') */
    private int patternCount;

    /** the counter for Shading name numbering */
    private int shadingCount;

    /** the counter for XObject numbering */
    private int xObjectCount;

    protected int gStateObjectCount;

    /* TODO: Should be modified (works only for image subtype) */
    private Map<String, PDFXObject> xObjectsMap = new HashMap<String, PDFXObject>();

    private Map<String, PDFFont> fontMap = new HashMap<String, PDFFont>();

    private Map<String, List<String>> filterMap = new HashMap<String, List<String>>();

    private List<PDFGState> gstates = new ArrayList<PDFGState>();

    private List<PDFFunction> functions = new ArrayList<PDFFunction>();

    private List<PDFShading> shadings = new ArrayList<PDFShading>();

    private List<PDFPattern> patterns = new ArrayList<PDFPattern>();

    private List<PDFLink> links = new ArrayList<PDFLink>();

    private List<PDFDestination> destinations;

    private List<PDFFileSpec> filespecs = new ArrayList<PDFFileSpec>();

    private List<PDFGoToRemote> gotoremotes = new ArrayList<PDFGoToRemote>();

    private List<PDFGoTo> gotos = new ArrayList<PDFGoTo>();

    private List<PDFLaunch> launches = new ArrayList<PDFLaunch>();

    protected List<PDFPage> pageObjs = new ArrayList<PDFPage>();

    private List<PDFLayer> layers;

    private List<PDFNavigator> navigators;

    private List<PDFNavigatorAction> navigatorActions;

    private PDFFactory factory;

    private FileIDGenerator fileIDGenerator;

    private boolean accessibilityEnabled;

    private boolean mergeFontsEnabled;

    private boolean linearizationEnabled;

    private boolean formXObjectEnabled;

    protected boolean outputStarted;

    /**
     * Creates an empty PDF document.
     *
     * The constructor creates a /Root and /Pages object to
     * track the document but does not write these objects until
     * the trailer is written. Note that the object ID of the
     * pages object is determined now, and the xref table is
     * updated later. This allows Pages to refer to their
     * Parent before we write it out.
     *
     * @param prod the name of the producer of this pdf document
     */
    public PDFDocument(String prod) {
        this(prod, null);
        versionController = VersionController.getDynamicVersionController(Version.V1_4, this);
    }

    /**
     * Creates an empty PDF document.
     *
     * The constructor creates a /Root and /Pages object to
     * track the document but does not write these objects until
     * the trailer is written. Note that the object ID of the
     * pages object is determined now, and the xref table is
     * updated later. This allows Pages to refer to their
     * Parent before we write it out.
     *
     * @param prod the name of the producer of this pdf document
     * @param versionController the version controller of this PDF document
     */
    public PDFDocument(String prod, VersionController versionController) {

        this.factory = new PDFFactory(this);

        /* create the /Root, /Info and /Resources objects */
        this.pages = getFactory().makePages();

        // Create the Root object
        this.root = getFactory().makeRoot(this.pages);

        // Create the Resources object
        this.resources = getFactory().makeResources();

        // Make the /Info record
        this.info = getFactory().makeInfo(prod);

        this.versionController = versionController;
    }

    /**
     * Returns the current PDF version.
     *
     * @return returns the PDF version
     */
    public Version getPDFVersion() {
        return versionController.getPDFVersion();
    }

    /**
     * Sets the PDF version of this document.
     *
     * @param version the PDF version
     * @throws IllegalStateException if the version of this PDF is not allowed to change.
     */
    public void setPDFVersion(Version version) {
        versionController.setPDFVersion(version);
    }

    /** @return the String representing the current PDF version */
    public String getPDFVersionString() {
        return versionController.getPDFVersion().toString();
    }

    /** @return the PDF profile currently active. */
    public PDFProfile getProfile() {
        return this.pdfProfile;
    }

    /**
     * Returns the factory for PDF objects.
     *
     * @return the {@link PDFFactory} object
     */
    public PDFFactory getFactory() {
        return this.factory;
    }

    /**
     * Converts text to a byte array for writing to a PDF file.
     *
     * @param text text to convert/encode
     * @return the resulting <code>byte</code> array
     */
    public static byte[] encode(String text) {
        try {
            return text.getBytes(ENCODING);
        } catch (UnsupportedEncodingException uee) {
            return text.getBytes();
        }
    }

    /**
     * Flushes the given text buffer to an output stream with the right encoding and resets
     * the text buffer. This is used to efficiently switch between outputting text and binary
     * content.
     * @param textBuffer the text buffer
     * @param out the output stream to flush the text content to
     * @throws IOException if an I/O error occurs while writing to the output stream
     */
    public static void flushTextBuffer(StringBuilder textBuffer, OutputStream out)
            throws IOException {
        out.write(encode(textBuffer.toString()));
        textBuffer.setLength(0);
    }

    /**
     * Sets the producer of the document.
     *
     * @param producer string indicating application producing the PDF
     */
    public void setProducer(String producer) {
        this.info.setProducer(producer);
    }

    /**
      * Sets the creation date of the document.
      *
      * @param date Date to be stored as creation date in the PDF.
      */
    public void setCreationDate(Date date) {
        this.info.setCreationDate(date);
    }

    /**
      * Sets the creator of the document.
      *
      * @param creator string indicating application creating the document
      */
    public void setCreator(String creator) {
        this.info.setCreator(creator);
    }

    /**
     * Sets the filter map to use for filters in this document.
     *
     * @param map the map of filter lists for each stream type
     */
    public void setFilterMap(Map<String, List<String>> map) {
        this.filterMap = map;
    }

    /**
     * Returns the {@link PDFFilter}s map used for filters in this document.
     *
     * @return the map of filters being used
     */
    public Map<String, List<String>> getFilterMap() {
        return this.filterMap;
    }

    /**
     * Returns the {@link PDFPages} object associated with the root object.
     *
     * @return the {@link PDFPages} object
     */
    public PDFPages getPages() {
        return this.pages;
    }

    /**
     * Get the {@link PDFRoot} object for this document.
     *
     * @return the {@link PDFRoot} object
     */
    public PDFRoot getRoot() {
        return this.root;
    }

    /**
     * Get the Structural Tree Collection for this document
     * @return
     */
    public List<PDFStructElem> getStructureTreeElements() {
        return structureTreeElements;
    }

    /**
     * Creates and returns a StructTreeRoot object.
     *
     * @param parentTree the value of the ParenTree entry
     * @return the structure tree root
     */
    public PDFStructTreeRoot makeStructTreeRoot(PDFParentTree parentTree) {
        PDFStructTreeRoot structTreeRoot = new PDFStructTreeRoot(parentTree);
        assignObjectNumber(structTreeRoot);
        addTrailerObject(structTreeRoot);
        root.setStructTreeRoot(structTreeRoot);
        structureTreeElements = new ArrayList<PDFStructElem>();
        return structTreeRoot;
    }

    /**
     * Adds the given element to the structure tree.
     */
    public void registerStructureElement(PDFStructElem structElem) {
        assignObjectNumber(structElem);
        structureTreeElements.add(structElem);
    }

    /**
     * Assigns the given scope to the given element and adds it to the structure tree. The
     * scope may not be added if it's not compatible with this document's PDF version.
     */
    public void registerStructureElement(PDFStructElem structElem, Scope scope) {
        registerStructureElement(structElem);
        versionController.addTableHeaderScopeAttribute(structElem, scope);
    }

    /**
     * Get the {@link PDFInfo} object for this document.
     *
     * @return the {@link PDFInfo} object
     */
    public PDFInfo getInfo() {
        return this.info;
    }

    /**
     * Registers a {@link PDFObject} in this PDF document.
     * The object is assigned a new object number.
     *
     * @param obj {@link PDFObject} to add
     * @return the added {@link PDFObject} added (with its object number set)
     */
    public PDFObject registerObject(PDFObject obj) {
        assignObjectNumber(obj);
        addObject(obj);
        if (obj instanceof AbstractPDFStream) {
            ((AbstractPDFStream) obj).registerChildren();
        }
        return obj;
    }

    /**
     * Registers a {@link PDFObject} in this PDF document at end.
     * The object is assigned a new object number.
     *
     * @param obj {@link PDFObject} to add
     * @return the added {@link PDFObject} added (with its object number set)
     */
    <T extends PDFObject> T registerTrailerObject(T obj) {
        assignObjectNumber(obj);
        addTrailerObject(obj);
        return obj;
    }

    /**
     * Assigns the {@link PDFObject} an object number,
     * and sets the parent of the {@link PDFObject} to this document.
     *
     * @param obj {@link PDFObject} to assign a number to
     */
    public void assignObjectNumber(PDFObject obj) {
        if (outputStarted && isLinearizationEnabled()) {
            throw new IllegalStateException("Can't assign number after start of output");
        }
        if (obj == null) {
            throw new NullPointerException("obj must not be null");
        }
        if (obj.hasObjectNumber()) {
            throw new IllegalStateException(
                "Error registering a PDFObject: "
                    + "PDFObject already has an object number");
        }
        PDFDocument currentParent = obj.getDocument();
        if (currentParent != null && currentParent != this) {
            throw new IllegalStateException(
                "Error registering a PDFObject: "
                    + "PDFObject already has a parent PDFDocument");
        }

        obj.setObjectNumber(this);

        if (currentParent == null) {
            obj.setDocument(this);
        }
    }

    /**
     * Adds a {@link PDFObject} to this document.
     * The object <em>MUST</em> have an object number assigned.
     *
     * @param obj {@link PDFObject} to add
     */
    public void addObject(PDFObject obj) {
        if (obj == null) {
            throw new NullPointerException("obj must not be null");
        }
        if (!obj.hasObjectNumber()) {
            throw new IllegalStateException(
                "Error adding a PDFObject: "
                    + "PDFObject doesn't have an object number");
        }

        //Add object to list
        this.objects.add(obj);

        //Add object to special lists where necessary
        if (obj instanceof PDFFunction) {
            this.functions.add((PDFFunction) obj);
        }
        if (obj instanceof PDFShading) {
            final String shadingName = "Sh" + (++this.shadingCount);
            ((PDFShading)obj).setName(shadingName);
            this.shadings.add((PDFShading) obj);
        }
        if (obj instanceof PDFPattern) {
            final String patternName = "Pa" + (++this.patternCount);
            ((PDFPattern)obj).setName(patternName);
            this.patterns.add((PDFPattern) obj);
        }
        if (obj instanceof PDFFont) {
            final PDFFont font = (PDFFont)obj;
            this.fontMap.put(font.getName(), font);
        }
        if (obj instanceof PDFGState) {
            this.gstates.add((PDFGState) obj);
        }
        if (obj instanceof PDFPage) {
            this.pages.notifyKidRegistered((PDFPage)obj);
            pageObjs.add((PDFPage) obj);
        }
        if (obj instanceof PDFLaunch) {
            this.launches.add((PDFLaunch) obj);
        }
        if (obj instanceof PDFLink) {
            this.links.add((PDFLink) obj);
        }
        if (obj instanceof PDFFileSpec) {
            this.filespecs.add((PDFFileSpec) obj);
        }
        if (obj instanceof PDFGoToRemote) {
            this.gotoremotes.add((PDFGoToRemote) obj);
        }
        if (obj instanceof PDFLayer) {
            if (this.layers == null) {
                this.layers = new ArrayList<PDFLayer>();
            }
            this.layers.add((PDFLayer) obj);
        }
        if (obj instanceof PDFNavigator) {
            if (this.navigators == null) {
                this.navigators = new ArrayList<PDFNavigator>();
            }
            this.navigators.add((PDFNavigator) obj);
        }
        if (obj instanceof PDFNavigatorAction) {
            if (this.navigatorActions == null) {
                this.navigatorActions = new ArrayList<PDFNavigatorAction>();
            }
            this.navigatorActions.add((PDFNavigatorAction) obj);
        }
    }

    /**
     * Add trailer object.
     * Adds an object to the list of trailer objects.
     *
     * @param obj the PDF object to add
     */
    public void addTrailerObject(PDFObject obj) {
        this.trailerObjects.add(obj);

        if (obj instanceof PDFGoTo) {
            this.gotos.add((PDFGoTo) obj);
        }
    }

    /**
     * Apply the encryption filter to a PDFStream if encryption is enabled.
     *
     * @param stream PDFStream to encrypt
     */
    public void applyEncryption(AbstractPDFStream stream) {
        if (isEncryptionActive()) {
            this.encryption.applyFilter(stream);
        }
    }

    /**
     * Enables PDF encryption.
     *
     * @param params The encryption parameters for the pdf file
     */
    public void setEncryption(PDFEncryptionParams params) {
        getProfile().verifyEncryptionAllowed();
        fileIDGenerator = FileIDGenerator.getRandomFileIDGenerator();
        this.encryption = PDFEncryptionManager.newInstance(params, this);
        if (this.encryption != null) {
            PDFObject pdfObject = (PDFObject)this.encryption;
            addTrailerObject(pdfObject);
            try {
                if (encryption.getPDFVersion().compareTo(versionController.getPDFVersion()) > 0) {
                    versionController.setPDFVersion(encryption.getPDFVersion());
                }
            } catch (IllegalStateException ise) {
                log.warn("Configured encryption requires PDF version " + encryption.getPDFVersion()
                        + " but version has been set to " + versionController.getPDFVersion() + ".");
                throw ise;
            }
        } else {
            log.warn("PDF encryption is unavailable. PDF will be generated without encryption.");
            if (params.getEncryptionLengthInBits() == 256) {
                log.warn("Make sure the JCE Unlimited Strength Jurisdiction Policy files are available."
                        + "AES 256 encryption cannot be performed without them.");
            }
        }
    }

    /**
     * Indicates whether encryption is active for this PDF or not.
     *
     * @return boolean True if encryption is active
     */
    public boolean isEncryptionActive() {
        return this.encryption != null;
    }

    /**
     * Returns the active Encryption object.
     *
     * @return the Encryption object
     */
    public PDFEncryption getEncryption() {
        return this.encryption;
    }

    private Object findPDFObject(List<? extends PDFObject> list, PDFObject compare) {
        for (PDFObject obj : list) {
            if (compare.contentEquals(obj)) {
                return obj;
            }
        }
        return null;
    }

    /**
     * Looks through the registered functions to see if one that is equal to
     * a reference object exists
     *
     * @param compare reference object
     * @return the function if it was found, null otherwise
     */
    protected PDFFunction findFunction(PDFFunction compare) {
        return (PDFFunction)findPDFObject(this.functions, compare);
    }

    /**
     * Looks through the registered shadings to see if one that is equal to
     * a reference object exists
     *
     * @param compare reference object
     * @return the shading if it was found, null otherwise
     */
    protected PDFShading findShading(PDFShading compare) {
        return (PDFShading)findPDFObject(this.shadings, compare);
    }

    /**
     * Find a previous pattern.
     * The problem with this is for tiling patterns the pattern
     * data stream is stored and may use up memory, usually this
     * would only be a small amount of data.
     *
     * @param compare reference object
     * @return the shading if it was found, null otherwise
     */
    protected PDFPattern findPattern(PDFPattern compare) {
        return (PDFPattern)findPDFObject(this.patterns, compare);
    }

    /**
     * Finds a font.
     *
     * @param fontname name of the font
     * @return PDFFont the requested font, null if it wasn't found
     */
    protected PDFFont findFont(String fontname) {
        return this.fontMap.get(fontname);
    }

    /**
     * Finds a named destination.
     *
     * @param compare reference object to use as search template
     * @return the link if found, null otherwise
     */
    protected PDFDestination findDestination(PDFDestination compare) {
        int index = getDestinationList().indexOf(compare);
        if (index >= 0) {
            return getDestinationList().get(index);
        } else {
            return null;
        }
    }

    /**
     * Finds a link.
     *
     * @param compare reference object to use as search template
     * @return the link if found, null otherwise
     */
    protected PDFLink findLink(PDFLink compare) {
        return (PDFLink)findPDFObject(this.links, compare);
    }

    /**
     * Finds a file spec.
     *
     * @param compare reference object to use as search template
     * @return the file spec if found, null otherwise
     */
    protected PDFFileSpec findFileSpec(PDFFileSpec compare) {
        return (PDFFileSpec)findPDFObject(this.filespecs, compare);
    }

    /**
     * Finds a goto remote.
     *
     * @param compare reference object to use as search template
     * @return the goto remote if found, null otherwise
     */
    protected PDFGoToRemote findGoToRemote(PDFGoToRemote compare) {
        return (PDFGoToRemote)findPDFObject(this.gotoremotes, compare);
    }

    /**
     * Finds a goto.
     *
     * @param compare reference object to use as search template
     * @return the goto if found, null otherwise
     */
    protected PDFGoTo findGoTo(PDFGoTo compare) {
        return (PDFGoTo)findPDFObject(this.gotos, compare);
    }

    /**
     * Finds a launch.
     *
     * @param compare reference object to use as search template
     * @return the launch if found, null otherwise
     */
    protected PDFLaunch findLaunch(PDFLaunch compare) {
        return (PDFLaunch) findPDFObject(this.launches, compare);
    }

    /**
     * Looks for an existing GState to use
     *
     * @param wanted requested features
     * @param current currently active features
     * @return the GState if found, null otherwise
     */
    protected PDFGState findGState(PDFGState wanted, PDFGState current) {
        PDFGState poss;
        for (PDFGState avail : this.gstates) {
            poss = new PDFGState();
            poss.addValues(current);
            poss.addValues(avail);
            if (poss.equals(wanted)) {
                return avail;
            }
        }
        return null;
    }

    /**
     * Returns the PDF color space object.
     *
     * @return the color space
     */
    public PDFDeviceColorSpace getPDFColorSpace() {
        return this.colorspace;
    }

    /**
     * Returns the color space.
     *
     * @return the color space
     */
    public int getColorSpace() {
        return getPDFColorSpace().getColorSpace();
    }

    /**
     * Set the color space.
     * This is used when creating gradients.
     *
     * @param theColorspace the new color space
     */
    public void setColorSpace(int theColorspace) {
        this.colorspace.setColorSpace(theColorspace);
    }

    /**
     * Returns the font map for this document.
     *
     * @return the map of fonts used in this document
     */
    public Map<String, PDFFont> getFontMap() {
        return this.fontMap;
    }

    /**
     * Get an image from the image map.
     *
     * @param key the image key to look for
     * @return the image or PDFXObject for the key if found
     * @deprecated Use getXObject instead (so forms are treated in the same way)
     */
    @Deprecated
    public PDFImageXObject getImage(String key) {
        return (PDFImageXObject)this.xObjectsMap.get(key);
    }

    /**
     * Get an XObject from the image map.
     *
     * @param key the XObject key to look for
     * @return the PDFXObject for the key if found
     */
    public PDFXObject getXObject(String key) {
        return this.xObjectsMap.get(key);
    }

    /**
     * Adds a destination to the document.
     * @param destination the destination object
     */
    public void addDestination(PDFDestination destination) {
        if (this.destinations == null) {
            this.destinations = new ArrayList<PDFDestination>();
        }
        this.destinations.add(destination);
    }

    /**
     * Gets the list of named destinations.
     *
     * @return the list of named destinations.
     */
    public List<PDFDestination> getDestinationList() {
        if (hasDestinations()) {
            return this.destinations;
        } else {
            return Collections.emptyList();
        }
    }

    /**
     * Gets whether the document has named destinations.
     *
     * @return whether the document has named destinations.
     */
    public boolean hasDestinations() {
        return this.destinations != null && !this.destinations.isEmpty();
    }

    /**
     * Add an image to the PDF document.
     * This adds an image to the PDF objects.
     * If an image with the same key already exists it will return the
     * old {@link PDFXObject}.
     *
     * @param res the PDF resource context to add to, may be null
     * @param img the PDF image to add
     * @return the PDF XObject that references the PDF image data
     */
    public PDFImageXObject addImage(PDFResourceContext res, PDFImage img) {
        // check if already created
        String key = img.getKey();
        PDFImageXObject xObject = (PDFImageXObject)this.xObjectsMap.get(key);
        if (xObject != null) {
            if (res != null) {
                res.addXObject(xObject);
            }
            return xObject;
        }

        // setup image
        img.setup(this);
        // create a new XObject
        xObject = new PDFImageXObject(++this.xObjectCount, img);
        registerObject(xObject);
        this.resources.addXObject(xObject);
        if (res != null) {
            res.addXObject(xObject);
        }
        this.xObjectsMap.put(key, xObject);
        return xObject;
    }

    /**
     * Add a form XObject to the PDF document.
     * This adds a Form XObject to the PDF objects.
     * If a Form XObject with the same key already exists it will return the
     * old {@link PDFFormXObject}.
     *
     * @param res the PDF resource context to add to, may be null
     * @param cont the PDF Stream contents of the Form XObject
     * @param formres a reference to the PDF Resources for the Form XObject data
     * @param key the key for the object
     * @return the PDF Form XObject that references the PDF data
     */
    public PDFFormXObject addFormXObject(
        PDFResourceContext res,
        PDFStream cont,
        PDFReference formres,
        String key) {

        // check if already created
        PDFFormXObject xObject = (PDFFormXObject)xObjectsMap.get(key);
        if (xObject != null) {
            if (res != null) {
                res.addXObject(xObject);
            }
            return xObject;
        }

        xObject = new PDFFormXObject(
                ++this.xObjectCount,
                cont,
                formres);
        registerObject(xObject);
        this.resources.addXObject(xObject);
        if (res != null) {
            res.addXObject(xObject);
        }
        this.xObjectsMap.put(key, xObject);
        return xObject;
    }

    /**
     * Get the root Outlines object. This method does not write
     * the outline to the PDF document, it simply creates a
     * reference for later.
     *
     * @return the PDF Outline root object
     */
    public PDFOutline getOutlineRoot() {
        if (this.outlineRoot != null) {
            return this.outlineRoot;
        }

        this.outlineRoot = new PDFOutline(null, null, true);
        assignObjectNumber(this.outlineRoot);
        addTrailerObject(this.outlineRoot);
        this.root.setRootOutline(this.outlineRoot);
        return this.outlineRoot;
    }

    /**
     * Get the /Resources object for the document
     *
     * @return the /Resources object
     */
    public PDFResources getResources() {
        return this.resources;
    }

    public void enableAccessibility(boolean enableAccessibility) {
        this.accessibilityEnabled = enableAccessibility;
    }

    /**
     *
     */
    public PDFReference resolveExtensionReference(String id) {
        if (layers != null) {
            for (PDFLayer layer : layers) {
                if (layer.hasId(id)) {
                    return layer.makeReference();
                }
            }
        }
        if (navigators != null) {
            for (PDFNavigator navigator : navigators) {
                if (navigator.hasId(id)) {
                    return navigator.makeReference();
                }
            }
        }
        if (navigatorActions != null) {
            for (PDFNavigatorAction action : navigatorActions) {
                if (action.hasId(id)) {
                    return action.makeReference();
                }
            }
        }
        return null;
    }

    /**
     * Writes out the entire document
     *
     * @param stream the OutputStream to output the document to
     * @throws IOException if there is an exception writing to the output stream
     */
    public void output(OutputStream stream) throws IOException {
        outputStarted = true;
        //Write out objects until the list is empty. This approach (used with a
        //LinkedList) allows for output() methods to create and register objects
        //on the fly even during serialization.
        while (this.objects.size() > 0) {
            PDFObject object = this.objects.remove(0);
            streamIndirectObject(object, stream);
        }
    }

    protected void writeTrailer(OutputStream stream, int first, int last, int size, long mainOffset, long startxref)
            throws IOException {
        TrailerOutputHelper trailerOutputHelper = mayCompressStructureTreeElements()
                ? new CompressedTrailerOutputHelper()
                : new UncompressedTrailerOutputHelper();
        if (structureTreeElements != null) {
            trailerOutputHelper.outputStructureTreeElements(stream);
        }
        TrailerDictionary trailerDictionary = createTrailerDictionary(mainOffset != 0);
        if (mainOffset != 0) {
            trailerDictionary.getDictionary().put("Prev", mainOffset);
        }
        trailerOutputHelper.outputCrossReferenceObject(stream, trailerDictionary, first, last, size);
        String trailer = "\nstartxref\n" + startxref + "\n%%EOF\n";
        stream.write(encode(trailer));
    }

    protected int streamIndirectObject(PDFObject o, OutputStream stream) throws IOException {
        outputStarted = true;
        recordObjectOffset(o);
        int len = outputIndirectObject(o, stream);
        this.position += len;
        return len;
    }

    private void streamIndirectObjects(Collection<? extends PDFObject> objects, OutputStream stream)
            throws IOException {
        for (PDFObject o : objects) {
            streamIndirectObject(o, stream);
        }
    }

    private void recordObjectOffset(PDFObject object) {
        int index = object.getObjectNumber().getNumber() - 1;
        while (indirectObjectOffsets.size() <= index) {
            indirectObjectOffsets.add(null);
        }
        indirectObjectOffsets.set(index, position);
    }

    /**
     * Outputs the given object, wrapped by obj/endobj, to the given stream.
     *
     * @param object an indirect object, as described in Section 3.2.9 of the PDF 1.5
     * Reference.
     * @param stream the stream to which the object must be output
     * @throws IllegalArgumentException if the object is not an indirect object
     */
    public static int outputIndirectObject(PDFObject object, OutputStream stream)
            throws IOException {
        if (!object.hasObjectNumber()) {
            throw new IllegalArgumentException("Not an indirect object");
        }
        byte[] obj = encode(object.getObjectID());
        stream.write(obj);
        int length = object.output(stream);
        byte[] endobj = encode("\nendobj\n");
        stream.write(endobj);
        return obj.length + length + endobj.length;
    }

    /**
     * Write the PDF header.
     *
     * This method must be called prior to formatting
     * and outputting AreaTrees.
     *
     * @param stream the OutputStream to write the header to
     * @throws IOException if there is an exception writing to the output stream
     */
    public void outputHeader(OutputStream stream) throws IOException {
        this.position = 0;

        getProfile().verifyPDFVersion();

        byte[] pdf = encode("%PDF-" + getPDFVersionString() + "\n");
        stream.write(pdf);
        this.position += pdf.length;

        // output a binary comment as recommended by the PDF spec (3.4.1)
        byte[] bin = {
                (byte)'%',
                (byte)0xAA,
                (byte)0xAB,
                (byte)0xAC,
                (byte)0xAD,
                (byte)'\n' };
        stream.write(bin);
        this.position += bin.length;
    }

    /**
     * Write the trailer
     *
     * @param stream the OutputStream to write the trailer to
     * @throws IOException if there is an exception writing to the output stream
     */
    public void outputTrailer(OutputStream stream) throws IOException {
        createDestinations();
        output(stream);
        outputTrailerObjectsAndXref(stream);
    }

    private void createDestinations() {
        if (hasDestinations()) {
            Collections.sort(this.destinations, new DestinationComparator());
            PDFDests dests = getFactory().makeDests(this.destinations);
            if (this.root.getNames() == null) {
                this.root.setNames(getFactory().makeNames());
            }
            this.root.getNames().setDests(dests);
        }
    }

    private void outputTrailerObjectsAndXref(OutputStream stream) throws IOException {
        TrailerOutputHelper trailerOutputHelper = mayCompressStructureTreeElements()
                ? new CompressedTrailerOutputHelper()
                : new UncompressedTrailerOutputHelper();
        if (structureTreeElements != null) {
            trailerOutputHelper.outputStructureTreeElements(stream);
        }
        streamIndirectObjects(trailerObjects, stream);
        TrailerDictionary trailerDictionary = createTrailerDictionary(true);
        long startxref = trailerOutputHelper.outputCrossReferenceObject(stream, trailerDictionary, 0,
                indirectObjectOffsets.size(), indirectObjectOffsets.size());
        String trailer = "\nstartxref\n" + startxref + "\n%%EOF\n";
        stream.write(encode(trailer));
    }

    private boolean mayCompressStructureTreeElements() {
        return accessibilityEnabled
                && versionController.getPDFVersion().compareTo(Version.V1_5) >= 0
                && !isLinearizationEnabled();
    }

    private TrailerDictionary createTrailerDictionary(boolean addRoot) {
        FileIDGenerator gen = getFileIDGenerator();
        TrailerDictionary trailerDictionary = new TrailerDictionary(this);
        if (addRoot) {
            trailerDictionary.setRoot(root).setInfo(info);
        }
        trailerDictionary.setFileID(gen.getOriginalFileID(), gen.getUpdatedFileID());
        if (isEncryptionActive()) {
            trailerDictionary.setEncryption(encryption);
        }
        return trailerDictionary;
    }

    public boolean isMergeFontsEnabled() {
        return mergeFontsEnabled;
    }

    public void setMergeFontsEnabled(boolean mergeFontsEnabled) {
        this.mergeFontsEnabled = mergeFontsEnabled;
        if (mergeFontsEnabled) {
            getResources().createFontsAsObj();
        }
    }

    private interface TrailerOutputHelper {

        void outputStructureTreeElements(OutputStream stream) throws IOException;

        /**
         * @return the offset of the cross-reference object (the value of startxref)
         */
        long outputCrossReferenceObject(OutputStream stream, TrailerDictionary trailerDictionary,
                                        int first, int last, int size)
                throws IOException;
    }

    private class UncompressedTrailerOutputHelper implements TrailerOutputHelper {

        public void outputStructureTreeElements(OutputStream stream)
                throws IOException {
            streamIndirectObjects(structureTreeElements, stream);
        }

        public long outputCrossReferenceObject(OutputStream stream,
                TrailerDictionary trailerDictionary, int first, int last, int size) throws IOException {
            new CrossReferenceTable(trailerDictionary, position,
                    indirectObjectOffsets, first, last, size).output(stream);
            return position;
        }
    }

    private class CompressedTrailerOutputHelper implements TrailerOutputHelper {

        private ObjectStreamManager structureTreeObjectStreams;

        public void outputStructureTreeElements(OutputStream stream)
                throws IOException {
            assert structureTreeElements.size() > 0;
            structureTreeObjectStreams = new ObjectStreamManager(PDFDocument.this);
            for (PDFStructElem structElem : structureTreeElements) {
                structureTreeObjectStreams.add(structElem);
            }
        }

        public long outputCrossReferenceObject(OutputStream stream,
                TrailerDictionary trailerDictionary, int first, int last, int size) throws IOException {
            // Outputting the object streams should not have created new indirect objects
            assert objects.isEmpty();
            new CrossReferenceStream(PDFDocument.this, ++objectcount, trailerDictionary, position,
                    indirectObjectOffsets,
                    structureTreeObjectStreams.getCompressedObjectReferences())
                    .output(stream);
            return position;
        }
    }

    long getCurrentFileSize() {
        return position;
    }

    FileIDGenerator getFileIDGenerator() {
        if (fileIDGenerator == null) {
            try {
                fileIDGenerator = FileIDGenerator.getDigestFileIDGenerator(this);
            } catch (NoSuchAlgorithmException e) {
                fileIDGenerator = FileIDGenerator.getRandomFileIDGenerator();
            }
        }
        return fileIDGenerator;
    }

    public boolean isLinearizationEnabled() {
        return linearizationEnabled;
    }

    public void setLinearizationEnabled(boolean b) {
        linearizationEnabled = b;
    }

    public boolean isFormXObjectEnabled() {
        return formXObjectEnabled;
    }

    public void setFormXObjectEnabled(boolean b) {
        formXObjectEnabled = b;
    }
}
