/*
 * 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 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));
        }


    }

}
