/*
 * 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.Collection;
import java.util.Iterator;
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 subData = new java.util.ArrayList();

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

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

    // ID Reference for this bookmark
    private String idRef;

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

    // unresolved idrefs by this bookmark and child bookmarks below it
    private Map unresolvedIDRefs = new java.util.HashMap();

    /**
     * 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) {
        idRef = null;
        whenToProcess = END_OF_DOC;
        // top level defined in Rec to show all child bookmarks
        bShow = 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) {
        bookmarkTitle = bookmark.getBookmarkTitle();
        bShow = bookmark.showChildItems();
        this.idRef = bookmark.getInternalDestination();
    }

    private void putUnresolved(String id, BookmarkData bd) {
        List refs = (List)unresolvedIDRefs.get(id);
        if (refs == null) {
            refs = new java.util.ArrayList();
            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;
        bShow = 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;
        bShow = 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 || sub.pageRef.equals("")) {
            putUnresolved(sub.getIDRef(), sub);
            String[] ids = sub.getIDRefs();
            for (int count = 0; count < ids.length; count++) {
                putUnresolved(ids[count], 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 bShow;
    }

    /**
     * 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 (BookmarkData) 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 (String[])unresolvedIDRefs.keySet().toArray(new String[] {});
    }

    /**
     * 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} List)
     */
    public void resolveIDRef(String id, List pages) {
        if (id.equals(idRef)) {
            //Own ID has been resolved, so note the page
            pageRef = (PageViewport) pages.get(0);
            //Note: Determining the placement inside the page is the renderer's job.
        }

        //Notify all child bookmarks
        Collection refs = (Collection)unresolvedIDRefs.get(id);
        if (refs != null) {
            Iterator iter = refs.iterator();
            while (iter.hasNext()) {
                BookmarkData bd = (BookmarkData)iter.next();
                bd.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;
    }

}
