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

// java
import java.util.List;
import java.util.Locale;

import org.xml.sax.Locator;

import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.FOEventHandler;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FOTreeBuilderContext;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.ValidationException;
import org.apache.fop.fo.extensions.destination.Destination;
import org.apache.fop.fo.pagination.bookmarks.BookmarkTree;
import org.apache.fop.fo.properties.CommonAccessibility;
import org.apache.fop.fo.properties.CommonAccessibilityHolder;
import org.apache.fop.fo.properties.CommonHyphenation;

/**
 * Class modeling the <a href="http://www.w3.org/TR/xsl/#fo_root">
 * <code>fo:root</code></a> formatting object.
 * Contains page masters, page-sequences.
 */
public class Root extends FObj implements CommonAccessibilityHolder {

    private CommonAccessibility commonAccessibility;

    private int mediaUsage;

    private LayoutMasterSet layoutMasterSet;
    private Declarations declarations;
    private BookmarkTree bookmarkTree;
    private List<Destination> destinationList;
    private List<PageSequence> pageSequences;
    private Locale locale;

    // temporary until above list populated
    private boolean pageSequenceFound;

    /**
     * Keeps count of page number from over PageSequence instances
     */
    private int endingPageNumberOfPreviousSequence;
    private int totalPagesGenerated;

    /**
     * Context class used while building the FO tree.
     */
    private FOTreeBuilderContext builderContext;

    /**
     * FOEventHandler object for this FO Tree
     */
    private FOEventHandler foEventHandler;

    private PageSequence lastSeq;

    public void setLastSeq(PageSequence seq) {
        lastSeq = seq;
    }

    public PageSequence getLastSeq() {
          return lastSeq;
    }

    /**
     * Base constructor
     *
     * @param parent {@link FONode} that is the parent of this object
     * Note: parent should be null for the fo:root.
     */
    public Root(FONode parent) {
        super(parent);
        pageSequences = new java.util.ArrayList<PageSequence>();
    }

    /** {@inheritDoc} */
    public void bind(PropertyList pList) throws FOPException {
        super.bind(pList);
        commonAccessibility = CommonAccessibility.getInstance(pList);
        mediaUsage = pList.get(PR_MEDIA_USAGE).getEnum();
        String language = pList.get(PR_LANGUAGE).getString();
        String country = pList.get(PR_COUNTRY).getString();
        locale = CommonHyphenation.toLocale(language, country);
    }

     /** {@inheritDoc} */
    public void startOfNode() throws FOPException {
        foEventHandler.startRoot(this);
    }

    /** {@inheritDoc} */
    public void endOfNode() throws FOPException {
        if (!pageSequenceFound || layoutMasterSet == null) {
            missingChildElementError("(layout-master-set, declarations?, "
                + "bookmark-tree?, (page-sequence|fox:external-document)+)");
        }
        foEventHandler.endRoot(this);
    }

    /**
     * {@inheritDoc}
     * <br>XSL 1.0 Spec: (layout-master-set,declarations?,page-sequence+)
     * <br>FOP: (layout-master-set, declarations?, fox:bookmarks?, page-sequence+)
     */
    protected void validateChildNode(Locator loc, String nsURI, String localName)
        throws ValidationException {
        if (FO_URI.equals(nsURI)) {
            if (localName.equals("layout-master-set")) {
                if (layoutMasterSet != null) {
                    tooManyNodesError(loc, "fo:layout-master-set");
                }
            } else if (localName.equals("declarations")) {
                if (layoutMasterSet == null) {
                    nodesOutOfOrderError(loc, "fo:layout-master-set", "fo:declarations");
                } else if (declarations != null) {
                    tooManyNodesError(loc, "fo:declarations");
                } else if (bookmarkTree != null) {
                    nodesOutOfOrderError(loc, "fo:declarations", "fo:bookmark-tree");
                } else if (pageSequenceFound) {
                    nodesOutOfOrderError(loc, "fo:declarations", "fo:page-sequence");
                }
            } else if (localName.equals("bookmark-tree")) {
                if (layoutMasterSet == null) {
                    nodesOutOfOrderError(loc, "fo:layout-master-set", "fo:bookmark-tree");
                } else if (bookmarkTree != null) {
                    tooManyNodesError(loc, "fo:bookmark-tree");
                } else if (pageSequenceFound) {
                    nodesOutOfOrderError(loc, "fo:bookmark-tree", "fo:page-sequence");
                }
            } else if (localName.equals("page-sequence")) {
                if (layoutMasterSet == null) {
                    nodesOutOfOrderError(loc, "fo:layout-master-set", "fo:page-sequence");
                } else {
                    pageSequenceFound = true;
                }
            } else {
                invalidChildError(loc, nsURI, localName);
            }
        } else {
            if (FOX_URI.equals(nsURI)) {
                if ("external-document".equals(localName)) {
                    pageSequenceFound = true;
                }
            }
            //invalidChildError(loc, nsURI, localName);
            //Ignore non-FO elements under root
        }
    }


    /**
     * @param loc location in the source file
     * @param child the {@link FONode} to validate against
     * @throws ValidationException if the incoming node is not a valid child for the given FO
     */
    protected void validateChildNode(Locator loc, FONode child) throws ValidationException {
        if (child instanceof AbstractPageSequence) {
            pageSequenceFound = true;
        }
    }

    /** {@inheritDoc} */
    public CommonAccessibility getCommonAccessibility() {
        return commonAccessibility;
    }

    /**
     * Sets the FOEventHandler object that this Root is attached to
     * @param foEventHandler the FOEventHandler object
     */
    public void setFOEventHandler(FOEventHandler foEventHandler) {
        this.foEventHandler = foEventHandler;
    }

    /**
     * This method overrides the FONode version. The FONode version calls the
     * method by the same name for the parent object. Since Root is at the top
     * of the tree, it returns the actual FOEventHandler object. Thus, any FONode
     * can use this chain to find which FOEventHandler it is being built for.
     * @return the FOEventHandler implementation that this Root is attached to
     */
    public FOEventHandler getFOEventHandler() {
        return foEventHandler;
    }

    /**
     * Sets the builder context for this FO tree.
     * @param context the builder context to be used
     */
    public void setBuilderContext(FOTreeBuilderContext context) {
        this.builderContext = context;
    }

    /** {@inheritDoc} */
    public FOTreeBuilderContext getBuilderContext() {
        return this.builderContext;
    }

    /**
    * Gets the last page number generated by the previous page-sequence
    * @return the last page number, 0 if no page sequences yet generated
    */
    public int getEndingPageNumberOfPreviousSequence() {
        return endingPageNumberOfPreviousSequence;
    }

    /**
     * Returns the total number of pages generated by FOP
     * (May not equal endingPageNumberOfPreviousSequence due to
     * initial-page-number property on fo:page-sequences.)
     * @return the last page number, 0 if no page sequences yet generated
     */
    public int getTotalPagesGenerated() {
        return totalPagesGenerated;
    }

    /**
     * Notify additional pages generated to increase the totalPagesGenerated counter
     * @param lastPageNumber the last page number generated by the sequence
     * @param additionalPages the total pages generated by the sequence (for statistics)
     * @throws IllegalArgumentException for negative additional page counts
     */
    public void notifyPageSequenceFinished(int lastPageNumber, int additionalPages)
            throws IllegalArgumentException {

        if (additionalPages >= 0) {
            totalPagesGenerated += additionalPages;
            endingPageNumberOfPreviousSequence = lastPageNumber;
        } else {
            throw new IllegalArgumentException(
                "Number of additional pages must be zero or greater.");
        }
    }

    /**
     * Returns the number of PageSequence instances.
     * @return the number of PageSequence instances
     */
    public int getPageSequenceCount() {
        return pageSequences.size();
    }

    /**
     * Some properties, such as 'force-page-count', require a
     * page-sequence to know about some properties of the next.
     * @param current the current PageSequence
     * @return succeeding PageSequence; null if none
     */
    public PageSequence getSucceedingPageSequence(PageSequence current) {
        int currentIndex = pageSequences.indexOf(current);
        if (currentIndex == -1) {
            return null;
        }
        if (currentIndex < (pageSequences.size() - 1)) {
            return pageSequences.get(currentIndex + 1);
        } else {
            return null;
        }
    }

    /**
     * Adds the specified page sequence.
     *
     * @param pageSequence The page sequence to add
     */
    public void addPageSequence(PageSequence pageSequence) {
        pageSequences.add(pageSequence);
    }

    /**
     * Returns the last page sequence (current while parsing).
     *
     * @return The last page sequence or null
     */
    public PageSequence getLastPageSequence() {
        if (getPageSequenceCount() > 0) {
            return pageSequences.get(getPageSequenceCount() - 1);
        } else {
            return null;
        }
    }

    /**
     * Returns the associated LayoutMasterSet.
     * @return the LayoutMasterSet instance
     */
    public LayoutMasterSet getLayoutMasterSet() {
        return this.layoutMasterSet;
    }

    /**
     * Sets the associated LayoutMasterSet.
     * @param layoutMasterSet the LayoutMasterSet to use
     */
    public void setLayoutMasterSet(LayoutMasterSet layoutMasterSet) {
        this.layoutMasterSet = layoutMasterSet;
    }

    /**
     * Returns the associated Declarations.
     * @return the Declarations instance
     */
    public Declarations getDeclarations() {
        return this.declarations;
    }

    /**
     * Sets the associated Declarations.
     * @param declarations the Declarations to use
     */
    public void setDeclarations(Declarations declarations) {
        this.declarations = declarations;
    }

    /**
     * Set the BookmarkTree object for this FO
     * @param bookmarkTree the BookmarkTree object
     */
    public void setBookmarkTree(BookmarkTree bookmarkTree) {
        this.bookmarkTree = bookmarkTree;
    }

    /**
     * Add a Destination object to this FO
     * @param destination the Destination object to add
     */
    public void addDestination(Destination destination) {
        if (destinationList == null) {
          destinationList = new java.util.ArrayList<Destination>();
        }
        destinationList.add(destination);
    }

    /**
     * Public accessor for the list of Destination objects for this FO
     * @return the Destination object
     */
    public List getDestinationList() {
        return destinationList;
    }

    /**
     * Public accessor for the BookmarkTree object for this FO
     * @return the BookmarkTree object
     */
    public BookmarkTree getBookmarkTree() {
        return bookmarkTree;
    }

    /** {@inheritDoc} */
    public Root getRoot() {
        return this;
    }

    /** {@inheritDoc} */
    public String getLocalName() {
        return "root";
    }

    /**
     * {@inheritDoc}
     * @return {@link org.apache.fop.fo.Constants#FO_ROOT}
     */
    public int getNameId() {
        return FO_ROOT;
    }


    /** @return locale proprty. */
    public Locale getLocale() {
        return locale;
    }

}
