/*
 * 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;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;

/**
 * This represents a single Outline object in a PDF, including the root Outlines
 * object. Outlines provide the bookmark bar, usually rendered to the right of
 * a PDF document in user agents such as Acrobat Reader
 *
 * @author Kelly A. Campbell
 *
 */
public class PDFOutline extends PDFObject {

    /**
     * list of sub-entries (outline objects)
     */
    private List subentries;

    /**
     * parent outline object. Root Outlines parent is null
     */
    private PDFOutline parent;

    private PDFOutline prev;
    private PDFOutline next;

    private PDFOutline first;
    private PDFOutline last;

    private int count;

    // whether to show this outline item's child outline items
    private boolean openItem = false;

    /**
     * title to display for the bookmark entry
     */
    private String title;

    private String actionRef;

    /**
     * Create a PDF outline with the title and action.
     *
     * @param title the title of the outline entry (can only be null for root Outlines obj)
     * @param action the action for this outline
     * @param openItem indicator of whether child items are visible or not
     */
    public PDFOutline(String title, String action, boolean openItem) {
        super();
        subentries = new java.util.ArrayList();
        count = 0;
        parent = null;
        prev = null;
        next = null;
        first = null;
        last = null;
        this.title = title;
        actionRef = action;
        this.openItem = openItem;
    }

    /**
     * Set the title of this Outline object.
     *
     * @param t the title of the outline
     */
    public void setTitle(String t) {
        title = t;
    }

    /**
     * Add a sub element to this outline.
     *
     * @param outline a sub outline
     */
    public void addOutline(PDFOutline outline) {
        if (subentries.size() > 0) {
            outline.prev
                = (PDFOutline)subentries.get(subentries.size() - 1);
            outline.prev.next = outline;
        } else {
            first = outline;
        }

        subentries.add(outline);
        outline.parent = this;

        // note: count is not just the immediate children
        incrementCount();

        last = outline;
    }

    /**
     * Increment the number of subentries and descendants.
     */
    private void incrementCount() {
        // count is a total of our immediate subentries
        // and all descendent subentries
        count++;
        if (parent != null) {
            parent.incrementCount();
        }
    }

    /**
     * {@inheritDoc}
     */
    protected byte[] toPDF() {
        ByteArrayOutputStream bout = new ByteArrayOutputStream(128);
        try {
            bout.write(encode(getObjectID()));
            bout.write(encode("<<"));
            if (parent == null) {
                // root Outlines object
                if (first != null && last != null) {
                    bout.write(encode(" /First " + first.referencePDF() + "\n"));
                    bout.write(encode(" /Last " + last.referencePDF() + "\n"));
                    // no count... we start with the outline completely closed for now
                }
            } else {
                // subentry Outline item object
                bout.write(encode(" /Title "));
                bout.write(encodeText(this.title));
                bout.write(encode("\n"));
                bout.write(encode(" /Parent " + parent.referencePDF() + "\n"));
                if (prev != null) {
                    bout.write(encode(" /Prev " + prev.referencePDF() + "\n"));
                }
                if (next != null) {
                    bout.write(encode(" /Next " + next.referencePDF() + "\n"));
                }
                if (first != null && last != null) {
                    bout.write(encode(" /First " + first.referencePDF() + "\n"));
                    bout.write(encode(" /Last " + last.referencePDF() + "\n"));
                }
                if (count > 0) {
                    bout.write(encode(" /Count " + (openItem ? "" : "-")
                        + count + "\n"));
                }
                if (actionRef != null) {
                    bout.write(encode(" /A " + actionRef + "\n"));
                }
            }
            bout.write(encode(">> endobj\n"));
        } catch (IOException ioe) {
            log.error("Ignored I/O exception", ioe);
        }
        return bout.toByteArray();
    }

}
