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

import java.util.List;
import java.util.Map;

import org.apache.fop.fo.pagination.bookmarks.Bookmark;
import org.apache.fop.fo.pagination.bookmarks.BookmarkTree;

/**
 * An instance of this class is either a PDF bookmark-tree and
 * its child bookmark-items, or a bookmark-item and the child
 * child bookmark-items under it.
 */
public class BookmarkData extends AbstractOffDocumentItem implements Resolvable {

    private List<BookmarkData> subData = new java.util.ArrayList<BookmarkData>();

    // bookmark-title for this fo:bookmark
    private String bookmarkTitle;

    // indicator of whether to initially display/hide child bookmarks of this object
    private boolean showChildren = true;

    // ID Reference for this bookmark
    private String idRef;

    // PageViewport that the idRef item refers to
    private PageViewport pageRef;

    // unresolved idrefs by this bookmark and child bookmarks below it
    private Map<String, List<Resolvable>> unresolvedIDRefs
            = new java.util.HashMap<String, List<Resolvable>>();

    /**
     * Create a new bookmark data object.
     * This should only be called by the bookmark-tree item because
     * it has no idref item that needs to be resolved.
     *
     * @param bookmarkTree fo:bookmark-tree for this document
     */
    public BookmarkData(BookmarkTree bookmarkTree) {
        this.idRef = null;
        this.whenToProcess = END_OF_DOC;
        // top level defined in Rec to show all child bookmarks
        this.showChildren = true;

        for (int count = 0; count < bookmarkTree.getBookmarks().size(); count++) {
            Bookmark bkmk = (Bookmark)(bookmarkTree.getBookmarks()).get(count);
            addSubData(createBookmarkData(bkmk));
        }
    }

    /**
     * Create a new pdf bookmark data object.
     * This is used by the bookmark-items to create a data object
     * with a idref.  During processing, this idref will be
     * subsequently resolved to a particular PageViewport.
     *
     * @param bookmark the fo:bookmark object
     */
    public BookmarkData(Bookmark bookmark) {
        this.bookmarkTitle = bookmark.getBookmarkTitle();
        this.showChildren = bookmark.showChildItems();
        this.idRef = bookmark.getInternalDestination();
    }

    private void putUnresolved(String id, BookmarkData bd) {
        List<Resolvable> refs = unresolvedIDRefs.get(id);
        if (refs == null) {
            refs = new java.util.ArrayList<Resolvable>();
            unresolvedIDRefs.put(id, refs);
        }
        refs.add(bd);
    }

    /**
     * Create a new bookmark data root object.
     * This constructor is called by the AreaTreeParser when the
     * <bookmarkTree> element is read from the XML file
     */
    public BookmarkData() {
        idRef = null;
        whenToProcess = END_OF_DOC;
        showChildren = true;
    }

    /**
     * Create a new bookmark data object.
     * This constructor is called by the AreaTreeParser when a
     * <bookmark> element is read from the XML file.
     *
     * @param title the bookmark's title
     * @param showChildren whether to initially display the bookmark's children
     * @param pv the target PageViewport
     * @param idRef the target ID
     */
    public BookmarkData(String title, boolean showChildren, PageViewport pv, String idRef) {
        bookmarkTitle = title;
        this.showChildren = showChildren;
        pageRef = pv;
        this.idRef = idRef;
    }

    /**
     * Get the idref for this bookmark-item
     *
     * @return the idref for the bookmark-item
     */
    public String getIDRef() {
        return idRef;
    }

    /**
     * Add a child bookmark data object.
     * This adds a child bookmark in the bookmark hierarchy.
     *
     * @param sub the child bookmark data
     */
    public void addSubData(BookmarkData sub) {
        subData.add(sub);
        if (sub.pageRef == null) {
            putUnresolved(sub.getIDRef(), sub);
            String[] ids = sub.getIDRefs();
            for (String id : ids) {
                putUnresolved(id, sub);
            }
        }
    }

    /**
     * Get the title for this bookmark object.
     *
     * @return the bookmark title
     */
    public String getBookmarkTitle() {
        return bookmarkTitle;
    }

    /**
     * Indicator of whether to initially display child bookmarks.
     *
     * @return true to initially display child bookmarks, false otherwise
     */
    public boolean showChildItems() {
        return showChildren;
    }

    /**
     * Get the size of child data objects.
     *
     * @return the number of child bookmark data
     */
    public int getCount() {
        return subData.size();
    }

    /**
     * Get the child data object.
     *
     * @param count the index to get
     * @return the child bookmark data
     */
    public BookmarkData getSubData(int count) {
        return subData.get(count);
    }

    /**
     * Get the PageViewport object that this bookmark refers to
     *
     * @return the PageViewport that this bookmark points to
     */
    public PageViewport getPageViewport() {
        return pageRef;
    }

    /**
     * Check if this resolvable object has been resolved.
     * A BookmarkData object is considered resolved once the idrefs for it
     * and for all of its child bookmark-items have been resolved.
     *
     * @return true if this object has been resolved
     */
    public boolean isResolved() {
        return unresolvedIDRefs == null || (unresolvedIDRefs.size() == 0);
    }

    /**
     * {@inheritDoc}
     */
    public String[] getIDRefs() {
        return unresolvedIDRefs.keySet().toArray(
                new String[unresolvedIDRefs.keySet().size()]);
    }

    /**
     * Resolve this resolvable object.
     * This resolves the idref of this object and if possible also
     * resolves id references of child elements that have the same
     * id reference.
     *
     * {@inheritDoc}
     */
    public void resolveIDRef(String id, List<PageViewport> pages) {
        if (id.equals(idRef)) {
            //Own ID has been resolved, so note the page
            pageRef = pages.get(0);
            //Note: Determining the placement inside the page is the renderer's job.
        }

        //Notify all child bookmarks
        List<Resolvable> refs = unresolvedIDRefs.get(id);
        if (refs != null) {
            for (Resolvable res : refs) {
                res.resolveIDRef(id, pages);
            }
        }
        unresolvedIDRefs.remove(id);
    }

    /**
     * {@inheritDoc}
     */
    public String getName() {
        return "Bookmarks";
    }

    /**
     * Create and return the bookmark data for this bookmark
     * This creates a bookmark data with the destination
     * and adds all the data from child bookmarks
     *
     * @param bookmark the Bookmark object for which a bookmark entry should be
     * created
     * @return the new bookmark data
     */
    private BookmarkData createBookmarkData(Bookmark bookmark) {
        BookmarkData data = new BookmarkData(bookmark);
        for (int count = 0; count < bookmark.getChildBookmarks().size(); count++) {
            Bookmark bkmk = (Bookmark)(bookmark.getChildBookmarks()).get(count);
            data.addSubData(createBookmarkData(bkmk));
        }
        return data;
    }

}
