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

import java.util.LinkedList;

import org.apache.fop.layoutmgr.SpaceResolver.SpaceHandlingBreakPosition;

/**
 * Utility class which provides common code for the addAreas stage.
 */
public final class AreaAdditionUtil {

    private AreaAdditionUtil() {
    }

    /**
     * Creates the child areas for the given layout manager.
     * @param parentLM the parent layout manager
     * @param parentIter the position iterator
     * @param layoutContext the layout context
     */
    public static void addAreas(AbstractLayoutManager parentLM,
            PositionIterator parentIter, LayoutContext layoutContext) {
        LayoutManager childLM;
        LayoutContext lc = LayoutContext.offspringOf(layoutContext);
        LayoutManager firstLM = null;
        LayoutManager lastLM = null;
        Position firstPos = null;
        Position lastPos = null;

        if (parentLM != null) {
            parentLM.addId();
        }

        // "unwrap" the NonLeafPositions stored in parentIter
        // and put them in a new list;
        LinkedList<Position> positionList = new LinkedList<Position>();
        Position pos;
        while (parentIter.hasNext()) {
            pos = parentIter.next();
            if (pos == null) {
                continue;
            }
            if (pos.getIndex() >= 0) {
                if (firstPos == null) {
                    firstPos = pos;
                }
                lastPos = pos;
            }
            if (pos instanceof NonLeafPosition && pos.getPosition() != null) {
                // pos was created by a child of this FlowLM
                positionList.add(pos.getPosition());
                lastLM = (pos.getPosition().getLM());
                if (firstLM == null) {
                    firstLM = lastLM;
                }
            } else if (pos instanceof SpaceHandlingBreakPosition) {
                positionList.add(pos);
            } else {
                // pos was created by this LM, so it must be ignored
            }
        }
        if (firstPos == null) {
            return; //Nothing to do, return early
            //TODO This is a hack to avoid an NPE in the code block below.
            //If there's no firstPos/lastPos there's currently no way to
            //correctly determine first and last conditions. The Iterator
            //doesn't give us that info.
        }

        if (parentLM != null) {
            parentLM.registerMarkers(
                    true,
                    parentLM.isFirst(firstPos),
                    parentLM.isLast(lastPos));
        }

        PositionIterator childPosIter = new PositionIterator(positionList.listIterator());

        while ((childLM = childPosIter.getNextChildLM()) != null) {
            // TODO vh: the test above might be problematic in some cases. See comment in
            // the TableCellLM.getNextKnuthElements method
            // Add the block areas to Area
            lc.setFlags(LayoutContext.FIRST_AREA, childLM == firstLM);
            lc.setFlags(LayoutContext.LAST_AREA, childLM == lastLM);
            // set the space adjustment ratio
            lc.setSpaceAdjust(layoutContext.getSpaceAdjust());
            // set space before for the first LM, in order to implement
            // display-align = center or after
            lc.setSpaceBefore((childLM == firstLM ? layoutContext.getSpaceBefore() : 0));
            // set space after for each LM, in order to implement
            // display-align = distribute
            lc.setSpaceAfter(layoutContext.getSpaceAfter());
            lc.setStackLimitBP(layoutContext.getStackLimitBP());
            childLM.addAreas(childPosIter, lc);
        }

        if (parentLM != null) {
            parentLM.registerMarkers(
                    false,
                    parentLM.isFirst(firstPos),
                    parentLM.isLast(lastPos));
        }


    }

}
