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

import java.util.Iterator;

import org.xml.sax.Locator;

import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.FObjMixed;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.ValidationException;
import org.apache.fop.fo.XMLObj;
import org.apache.fop.fo.flow.table.Table;

/**
 * Abstract base class for the <a href="http://www.w3.org/TR/xsl/#fo_retrieve-marker">
 * <code>fo:retrieve-marker</code></a> and
 * <a href="http://www.w3.org/TR/xsl/#fo_retrieve-table-marker">
 * <code>fo:retrieve-table-marker</code></a> formatting objects.

 */
public abstract class AbstractRetrieveMarker extends FObjMixed {

    private PropertyList propertyList;

    private String retrieveClassName;

    /**
     * Create a new AbstractRetrieveMarker instance that
     * is a child of the given {@link FONode}
     *
     * @param parent    the parent {@link FONode}
     */
    public AbstractRetrieveMarker(FONode parent) {
        super(parent);
    }

    /**
     * {@inheritDoc}
     * <p>XSL Content Model: empty
     */
    protected void validateChildNode(Locator loc, String nsURI, String localName)
                throws ValidationException {
        if (FO_URI.equals(nsURI)) {
            invalidChildError(loc, nsURI, localName);
        }
    }

    /**
     * {@inheritDoc}
     * Store a reference to the parent {@link PropertyList}
     * to be used when the retrieve-marker is resolved.
     */
    public void bind(PropertyList pList) throws FOPException {
        super.bind(pList);
        this.retrieveClassName = pList.get(PR_RETRIEVE_CLASS_NAME).getString();
        if (retrieveClassName == null || retrieveClassName.equals("")) {
            missingPropertyError("retrieve-class-name");
        }
        this.propertyList = pList.getParentPropertyList();
    }

    private PropertyList createPropertyListFor(FObj fo, PropertyList parent) {
        return getBuilderContext().getPropertyListMaker().make(fo, parent);
    }

    private void cloneSingleNode(FONode child, FONode newParent,
                            Marker marker, PropertyList parentPropertyList)
        throws FOPException {

        if (child != null) {
            FONode newChild = child.clone(newParent, true);
            if (child instanceof FObj) {
                Marker.MarkerPropertyList pList;
                PropertyList newPropertyList = createPropertyListFor(
                            (FObj) newChild, parentPropertyList);

                pList = marker.getPropertyListFor(child);
                newChild.processNode(
                        child.getLocalName(),
                        getLocator(),
                        pList,
                        newPropertyList);
                addChildTo(newChild, newParent);
                if (newChild.getNameId() == FO_TABLE) {
                    Table t = (Table) child;
                    cloneSubtree(t.getColumns().iterator(),
                            newChild, marker, newPropertyList);
                    cloneSingleNode(t.getTableHeader(),
                            newChild, marker, newPropertyList);
                    cloneSingleNode(t.getTableFooter(),
                            newChild, marker, newPropertyList);
                }
                cloneSubtree(child.getChildNodes(), newChild,
                        marker, newPropertyList);
            } else if (child instanceof FOText) {
                FOText ft = (FOText) newChild;
                ft.bind(parentPropertyList);
                addChildTo(newChild, newParent);
            } else if (child instanceof XMLObj) {
                addChildTo(newChild, newParent);
            }

            // trigger end-of-node white-space handling
            // and finalization for table-FOs
            newChild.finalizeNode();
        }
    }

    /**
     * Clone the FO nodes in the parent iterator,
     * attach the new nodes to the new parent,
     * and map the new nodes to the existing property lists.
     * FOText nodes are also in the new map, with a null value.
     * Clone the subtree by a recursive call to this method.
     * @param parentIter the iterator over the children of the old parent
     * @param newParent the new parent for the cloned nodes
     * @param marker the marker that contains the old property list mapping
     * @param parentPropertyList the parent PropertyList
     * @throws FOPException in case there was an error
     */
    private void cloneSubtree(Iterator parentIter, FONode newParent,
                              Marker marker, PropertyList parentPropertyList)
        throws FOPException {
        if (parentIter != null) {
            FONode child;
            while (parentIter.hasNext()) {
                child = (FONode) parentIter.next();
                cloneSingleNode(child, newParent,
                        marker, parentPropertyList);
            }
        }
    }

    private void cloneFromMarker(Marker marker)
        throws FOPException {
        cloneSubtree(marker.getChildNodes(), this,
                        marker, propertyList);
        handleWhiteSpaceFor(this, null);
    }

    /**
     * Clone the subtree of the given marker
     *
     * @param marker the marker that is to be cloned
     */
    public void bindMarker(Marker marker) {
        // clean up remnants from a possible earlier layout
        if (firstChild != null) {
            currentTextNode = null;
            firstChild = null;
        }
        if (marker.getChildNodes() != null) {
            try {
                cloneFromMarker(marker);
            } catch (FOPException exc) {
                getFOValidationEventProducer().markerCloningFailed(this,
                        marker.getMarkerClassName(), exc, getLocator());
            }
        } else if (log.isDebugEnabled()) {
            log.debug("Empty marker retrieved...");
        }
    }

    /**
     * Return the value for the <code>retrieve-class-name</code>
     * property
     *
     * @return the value for retrieve-class-name
     */
    public String getRetrieveClassName() {
        return this.retrieveClassName;
    }

}
