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

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Stack;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.fo.flow.ListItem;
import org.apache.fop.fo.flow.ListItemBody;
import org.apache.fop.fo.flow.ListItemLabel;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.layoutmgr.BlockLayoutManager;
import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.BreakOpportunity;
import org.apache.fop.layoutmgr.BreakOpportunityHelper;
import org.apache.fop.layoutmgr.ElementListObserver;
import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.FloatContentLayoutManager;
import org.apache.fop.layoutmgr.FootenoteUtil;
import org.apache.fop.layoutmgr.Keep;
import org.apache.fop.layoutmgr.KnuthBlockBox;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthPenalty;
import org.apache.fop.layoutmgr.KnuthPossPosIter;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.ListElement;
import org.apache.fop.layoutmgr.NonLeafPosition;
import org.apache.fop.layoutmgr.PageProvider;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.SpaceResolver;
import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager;
import org.apache.fop.layoutmgr.TraitSetter;
import org.apache.fop.traits.SpaceVal;
import org.apache.fop.util.BreakUtil;

/**
 * LayoutManager for a list-item FO.
 * The list item contains a list item label and a list item body.
 */
public class ListItemLayoutManager extends SpacedBorderedPaddedBlockLayoutManager
        implements BreakOpportunity {

    /** logging instance */
    private static Log log = LogFactory.getLog(ListItemLayoutManager.class);

    private ListItemContentLayoutManager label;
    private ListItemContentLayoutManager body;

    private Block curBlockArea;

    private List<ListElement> labelList;
    private List<ListElement> bodyList;

    private Keep keepWithNextPendingOnLabel;
    private Keep keepWithNextPendingOnBody;

    public class ListItemPosition extends Position {
        private int labelFirstIndex;
        private int labelLastIndex;
        private int bodyFirstIndex;
        private int bodyLastIndex;
        private Position originalLabelPosition;
        private Position originalBodyPosition;

        public ListItemPosition(LayoutManager lm, int labelFirst, int labelLast,
                int bodyFirst, int bodyLast) {
            super(lm);
            labelFirstIndex = labelFirst;
            labelLastIndex = labelLast;
            bodyFirstIndex = bodyFirst;
            bodyLastIndex = bodyLast;
        }

        public int getLabelFirstIndex() {
            return labelFirstIndex;
        }

        public int getLabelLastIndex() {
            return labelLastIndex;
        }

        public int getBodyFirstIndex() {
            return bodyFirstIndex;
        }

        public int getBodyLastIndex() {
            return bodyLastIndex;
        }

        /** {@inheritDoc} */
        public boolean generatesAreas() {
            return true;
        }

        /** {@inheritDoc} */
        public String toString() {
            StringBuffer sb = new StringBuffer("ListItemPosition:");
            sb.append(getIndex()).append("(");
            sb.append("label:").append(labelFirstIndex).append("-").append(labelLastIndex);
            sb.append(" body:").append(bodyFirstIndex).append("-").append(bodyLastIndex);
            sb.append(")");
            return sb.toString();
        }

        public Position getOriginalLabelPosition() {
            return originalLabelPosition;
        }

        public void setOriginalLabelPosition(Position originalLabelPosition) {
            this.originalLabelPosition = originalLabelPosition;
        }

        public Position getOriginalBodyPosition() {
            return originalBodyPosition;
        }

        public void setOriginalBodyPosition(Position originalBodyPosition) {
            this.originalBodyPosition = originalBodyPosition;
        }
    }

    /**
     * Create a new list item layout manager.
     * @param node list-item to create the layout manager for
     */
    public ListItemLayoutManager(ListItem node) {
        super(node);
        setLabel(node.getLabel());
        setBody(node.getBody());
    }

    @Override
    protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
        return getListItemFO().getCommonBorderPaddingBackground();
    }

    /**
     * Convenience method.
     * @return the ListBlock node
     */
    protected ListItem getListItemFO() {
        return (ListItem)fobj;
    }

    /**
     * Create a LM for the fo:list-item-label object
     * @param node the fo:list-item-label FO
     */
    public void setLabel(ListItemLabel node) {
        label = new ListItemContentLayoutManager(node);
        label.setParent(this);
    }

    /**
     * Create a LM for the fo:list-item-body object
     * @param node the fo:list-item-body FO
     */
    public void setBody(ListItemBody node) {
        body = new ListItemContentLayoutManager(node);
        body.setParent(this);
    }

    /** {@inheritDoc} */
    @Override
    public void initialize() {
        foSpaceBefore = new SpaceVal(
                getListItemFO().getCommonMarginBlock().spaceBefore, this).getSpace();
        foSpaceAfter = new SpaceVal(
                getListItemFO().getCommonMarginBlock().spaceAfter, this).getSpace();
        startIndent = getListItemFO().getCommonMarginBlock().startIndent.getValue(this);
        endIndent = getListItemFO().getCommonMarginBlock().endIndent.getValue(this);
    }

    private void resetSpaces() {
        this.discardBorderBefore = false;
        this.discardBorderAfter = false;
        this.discardPaddingBefore = false;
        this.discardPaddingAfter = false;
        this.effSpaceBefore = null;
        this.effSpaceAfter = null;
    }

    /** {@inheritDoc} */
    public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack,
            Position restartPosition, LayoutManager restartAtLM) {
        referenceIPD = context.getRefIPD();
        LayoutContext childLC;

        List<ListElement> returnList = new LinkedList<ListElement>();

        if (!breakBeforeServed(context, returnList)) {
            return returnList;
        }

        addFirstVisibleMarks(returnList, context, alignment);

        // label
        childLC = makeChildLayoutContext(context);
        childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
        label.initialize();
        boolean labelDone = false;
        Stack labelLMStack = null;
        Position labelRestartPosition = null;
        LayoutManager labelRestartLM = null;
        if (restartPosition != null && restartPosition instanceof ListItemPosition) {
            ListItemPosition lip = (ListItemPosition) restartPosition;
            if (lip.labelLastIndex <= lip.labelFirstIndex) {
                labelDone = true;
            } else {
                labelRestartPosition = lip.getOriginalLabelPosition();
                labelRestartLM = labelRestartPosition.getLM();
                LayoutManager lm = labelRestartLM;
                labelLMStack = new Stack();
                while (lm != this) {
                    labelLMStack.push(lm);
                    lm = lm.getParent();
                    if (lm instanceof ListItemContentLayoutManager) {
                        lm = lm.getParent();
                    }
                }
            }
        }
        labelList = !labelDone ? label.getNextKnuthElements(childLC, alignment, labelLMStack,
                labelRestartPosition, labelRestartLM) : (List) new LinkedList<KnuthElement>();

        //Space resolution as if the contents were placed in a new reference area
        //(see 6.8.3, XSL 1.0, section on Constraints, last paragraph)
        SpaceResolver.resolveElementList(labelList);
        ElementListObserver.observe(labelList, "list-item-label", label.getPartFO().getId());

        context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
        this.keepWithNextPendingOnLabel = childLC.getKeepWithNextPending();

        // body
        childLC = makeChildLayoutContext(context);
        childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
        body.initialize();
        boolean bodyDone = false;
        Stack bodyLMStack = null;
        Position bodyRestartPosition = null;
        LayoutManager bodyRestartLM = null;
        if (restartPosition != null && restartPosition instanceof ListItemPosition) {
            ListItemPosition lip = (ListItemPosition) restartPosition;
            if (lip.bodyLastIndex <= lip.bodyFirstIndex) {
                bodyDone = true;
            } else {
                bodyRestartPosition = lip.getOriginalBodyPosition();
                bodyRestartLM = bodyRestartPosition.getLM();
                LayoutManager lm = bodyRestartLM;
                bodyLMStack = new Stack();
                while (lm != this) {
                    bodyLMStack.push(lm);
                    lm = lm.getParent();
                    if (lm instanceof ListItemContentLayoutManager) {
                        lm = lm.getParent();
                    }
                }
            }
        }
        bodyList = !bodyDone ? body.getNextKnuthElements(childLC, alignment, bodyLMStack,
                bodyRestartPosition, bodyRestartLM) : (List) new LinkedList<KnuthElement>();

        //Space resolution as if the contents were placed in a new reference area
        //(see 6.8.3, XSL 1.0, section on Constraints, last paragraph)
        SpaceResolver.resolveElementList(bodyList);
        ElementListObserver.observe(bodyList, "list-item-body", body.getPartFO().getId());

        context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
        this.keepWithNextPendingOnBody = childLC.getKeepWithNextPending();

        List<ListElement> returnedList = new LinkedList<ListElement>();
        if (!labelList.isEmpty() && labelList.get(0) instanceof KnuthBlockBox) {
            KnuthBlockBox kbb = (KnuthBlockBox) labelList.get(0);
            if (kbb.getWidth() == 0 && kbb.hasFloatAnchors()) {
                List<FloatContentLayoutManager> floats = kbb.getFloatContentLMs();
                returnedList.add(new KnuthBlockBox(0, Collections.emptyList(), null, false, floats));
                Keep keep = getKeepTogether();
                returnedList.add(new BreakElement(new LeafPosition(this, 0), keep.getPenalty(), keep
                        .getContext(), context));
                labelList.remove(0);
                labelList.remove(0);
            }
        }
        if (!bodyList.isEmpty() && bodyList.get(0) instanceof KnuthBlockBox) {
            KnuthBlockBox kbb = (KnuthBlockBox) bodyList.get(0);
            if (kbb.getWidth() == 0 && kbb.hasFloatAnchors()) {
                List<FloatContentLayoutManager> floats = kbb.getFloatContentLMs();
                returnedList.add(new KnuthBlockBox(0, Collections.emptyList(), null, false, floats));
                Keep keep = getKeepTogether();
                returnedList.add(new BreakElement(new LeafPosition(this, 0), keep.getPenalty(), keep
                        .getContext(), context));
                bodyList.remove(0);
                bodyList.remove(0);
            }
        }

        // create a combined list
        returnedList.addAll(getCombinedKnuthElementsForListItem(labelList, bodyList, context));

        // "wrap" the Position inside each element
        wrapPositionElements(returnedList, returnList, true);

        addLastVisibleMarks(returnList, context, alignment);

        addKnuthElementsForBreakAfter(returnList, context);

        context.updateKeepWithNextPending(this.keepWithNextPendingOnLabel);
        context.updateKeepWithNextPending(this.keepWithNextPendingOnBody);
        context.updateKeepWithNextPending(getKeepWithNext());
        context.updateKeepWithPreviousPending(getKeepWithPrevious());

        setFinished(true);
        resetSpaces();
        return returnList;
    }

    /**
     * Overridden to unconditionally add elements for space-before.
     * {@inheritDoc}
     */
    @Override
    protected void addFirstVisibleMarks(List<ListElement> elements,
                                        LayoutContext context, int alignment) {
        addKnuthElementsForSpaceBefore(elements, alignment);
        addKnuthElementsForBorderPaddingBefore(elements, !firstVisibleMarkServed);
        firstVisibleMarkServed = true;
        //Spaces, border and padding to be repeated at each break
        addPendingMarks(context);
    }

    private List getCombinedKnuthElementsForListItem(List<ListElement> labelElements,
            List<ListElement> bodyElements, LayoutContext context) {
        // Copy elements to array lists to improve element access performance
        List[] elementLists = {new ArrayList<ListElement>(labelElements),
                               new ArrayList<ListElement>(bodyElements)};
        int[] fullHeights = {ElementListUtils.calcContentLength(elementLists[0]),
                ElementListUtils.calcContentLength(elementLists[1])};
        int[] partialHeights = {0, 0};
        int[] start = {-1, -1};
        int[] end = {-1, -1};

        int totalHeight = Math.max(fullHeights[0], fullHeights[1]);
        int step;
        int addedBoxHeight = 0;
        Keep keepWithNextActive = Keep.KEEP_AUTO;

        LinkedList<ListElement> returnList = new LinkedList<ListElement>();
        while ((step = getNextStep(elementLists, start, end, partialHeights)) > 0) {

            if (end[0] + 1 == elementLists[0].size()) {
                keepWithNextActive = keepWithNextActive.compare(keepWithNextPendingOnLabel);
            }
            if (end[1] + 1 == elementLists[1].size()) {
                keepWithNextActive = keepWithNextActive.compare(keepWithNextPendingOnBody);
            }

            // compute penalty height and box height
            int penaltyHeight = step
                + getMaxRemainingHeight(fullHeights, partialHeights)
                - totalHeight;

            //Additional penalty height from penalties in the source lists
            int additionalPenaltyHeight = 0;
            int stepPenalty = 0;
            int breakClass = EN_AUTO;
            KnuthElement endEl = elementLists[0].size() > 0 ? (KnuthElement) elementLists[0].get(end[0])
                    : null;
            Position originalLabelPosition =
                    (endEl != null && endEl.getPosition() != null) ? endEl.getPosition().getPosition() : null;
            if (endEl instanceof KnuthPenalty) {
                additionalPenaltyHeight = endEl.getWidth();
                stepPenalty = endEl.getPenalty() == -KnuthElement.INFINITE ? -KnuthElement.INFINITE : Math
                        .max(stepPenalty, endEl.getPenalty());
                breakClass = BreakUtil.compareBreakClasses(breakClass,
                        ((KnuthPenalty) endEl).getBreakClass());
            }
            endEl = elementLists[1].size() > 0 ? (KnuthElement) elementLists[1].get(end[1]) : null;
            Position originalBodyPosition =
                    (endEl != null && endEl.getPosition() != null) ? endEl.getPosition().getPosition() : null;
            if (endEl instanceof KnuthPenalty) {
                additionalPenaltyHeight = Math.max(
                        additionalPenaltyHeight, endEl.getWidth());
                stepPenalty = endEl.getPenalty() == -KnuthElement.INFINITE ? -KnuthElement.INFINITE : Math
                        .max(stepPenalty, endEl.getPenalty());
                breakClass = BreakUtil.compareBreakClasses(breakClass,
                        ((KnuthPenalty) endEl).getBreakClass());
            }

            int boxHeight = step - addedBoxHeight - penaltyHeight;
            penaltyHeight += additionalPenaltyHeight; //Add AFTER calculating boxHeight!

            // collect footnote information
            // TODO this should really not be done like this. ListItemLM should remain as
            // footnote-agnostic as possible
            LinkedList<LayoutManager> footnoteList = new LinkedList<LayoutManager>();
            for (int i = 0; i < elementLists.length; i++) {
                footnoteList.addAll(FootenoteUtil.getFootnotes(elementLists[i], start[i], end[i]));
            }

            LinkedList<FloatContentLayoutManager> floats = new LinkedList<FloatContentLayoutManager>();
            for (int i = 0; i < elementLists.length; i++) {
                floats.addAll(FloatContentLayoutManager.checkForFloats(elementLists[i], start[i], end[i]));
            }

            // add the new elements
            addedBoxHeight += boxHeight;
            ListItemPosition stepPosition = new ListItemPosition(this, start[0], end[0], start[1], end[1]);
            stepPosition.setOriginalLabelPosition(originalLabelPosition);
            stepPosition.setOriginalBodyPosition(originalBodyPosition);

            if (floats.isEmpty()) {
                returnList.add(new KnuthBlockBox(boxHeight, footnoteList, stepPosition, false));
            } else {
                // add a line with height zero and no content and attach float to it
                returnList.add(new KnuthBlockBox(0, Collections.emptyList(), stepPosition, false, floats));
                // add a break element to signal that we should restart LB at this break
                Keep keep = getKeepTogether();
                returnList.add(new BreakElement(stepPosition, keep.getPenalty(), keep.getContext(), context));
                // add the original line where the float was but without the float now
                returnList.add(new KnuthBlockBox(boxHeight, footnoteList, stepPosition, false));
            }
            if (originalBodyPosition != null && getKeepWithPrevious().isAuto()
                    && shouldWeAvoidBreak(returnList, originalBodyPosition.getLM())) {
                stepPenalty++;
            }
            if (addedBoxHeight < totalHeight) {
                Keep keep = keepWithNextActive.compare(getKeepTogether());
                int p = stepPenalty;
                if (p > -KnuthElement.INFINITE) {
                    p = Math.max(p, keep.getPenalty());
                    breakClass = keep.getContext();
                }
                returnList.add(new BreakElement(stepPosition, penaltyHeight, p, breakClass, context));
            }
        }

        return returnList;
    }

    private boolean shouldWeAvoidBreak(List returnList, LayoutManager lm) {
        if (isChangingIPD(lm)) {
            if (lm instanceof BlockLayoutManager) {
                return true;
            }
            if (lm instanceof ListBlockLayoutManager) {
                int penaltyShootout = 0;
                for (Object o : returnList) {
                    if (o instanceof BreakElement) {
                        if (((BreakElement) o).getPenaltyValue() > 0) {
                            penaltyShootout++;
                        } else {
                            penaltyShootout--;
                        }
                    }
                }
                return penaltyShootout > 0;
            }
        }
        return false;
    }

    private boolean isChangingIPD(LayoutManager lm) {
        PageProvider pageProvider = lm.getPSLM().getPageProvider();
        int currentIPD = pageProvider.getCurrentIPD();
        int nextIPD = pageProvider.getNextIPD();
        return nextIPD != currentIPD;
    }

    private int getNextStep(List[] elementLists, int[] start, int[] end, int[] partialHeights) {
        // backup of partial heights
        int[] backupHeights = {partialHeights[0], partialHeights[1]};

        // set starting points
        start[0] = end[0] + 1;
        start[1] = end[1] + 1;

        // get next possible sequence for label and body
        int seqCount = 0;
        for (int i = 0; i < start.length; i++) {
            while (end[i] + 1 < elementLists[i].size()) {
                end[i]++;
                KnuthElement el = (KnuthElement)elementLists[i].get(end[i]);
                if (el.isPenalty()) {
                    if (el.getPenalty() < KnuthElement.INFINITE) {
                        //First legal break point
                        break;
                    }
                } else if (el.isGlue()) {
                    if (end[i] > 0) {
                        KnuthElement prev = (KnuthElement)elementLists[i].get(end[i] - 1);
                        if (prev.isBox()) {
                            //Second legal break point
                            break;
                        }
                    }
                    partialHeights[i] += el.getWidth();
                } else {
                    partialHeights[i] += el.getWidth();
                }
            }
            if (end[i] < start[i]) {
                partialHeights[i] = backupHeights[i];
            } else {
                seqCount++;
            }
        }
        if (seqCount == 0) {
            return 0;
        }

        // determine next step
        int step;
        if (backupHeights[0] == 0 && backupHeights[1] == 0) {
            // this is the first step: choose the maximum increase, so that
            // the smallest area in the first page will contain at least
            // a label area and a body area
            step = Math.max((end[0] >= start[0] ? partialHeights[0] : Integer.MIN_VALUE),
                            (end[1] >= start[1] ? partialHeights[1] : Integer.MIN_VALUE));
        } else {
            // this is not the first step: choose the minimum increase
            step = Math.min((end[0] >= start[0] ? partialHeights[0] : Integer.MAX_VALUE),
                            (end[1] >= start[1] ? partialHeights[1] : Integer.MAX_VALUE));
        }

        // reset bigger-than-step sequences
        for (int i = 0; i < partialHeights.length; i++) {
            if (partialHeights[i] > step) {
                partialHeights[i] = backupHeights[i];
                end[i] = start[i] - 1;
            }
        }

        return step;
    }

    private int getMaxRemainingHeight(int[] fullHeights, int[] partialHeights) {
        return Math.max(fullHeights[0] - partialHeights[0],
                        fullHeights[1] - partialHeights[1]);
    }

    /** {@inheritDoc} */
    @Override
    public List getChangedKnuthElements(List oldList, int alignment) {
        // label
        labelList = label.getChangedKnuthElements(labelList, alignment);

        // body
        // "unwrap" the Positions stored in the elements
        ListIterator oldListIterator = oldList.listIterator();
        KnuthElement oldElement;
        while (oldListIterator.hasNext()) {
            oldElement = (KnuthElement)oldListIterator.next();
            Position innerPosition = oldElement.getPosition().getPosition();
            if (innerPosition != null) {
                // oldElement was created by a descendant of this BlockLM
                oldElement.setPosition(innerPosition);
            } else {
                // thisElement was created by this BlockLM
                // modify its position in order to recognize it was not created
                // by a child
                oldElement.setPosition(new Position(this));
            }
        }

        List returnedList = body.getChangedKnuthElements(oldList, alignment);
        // "wrap" the Position inside each element
        List tempList = returnedList;
        KnuthElement tempElement;
        returnedList = new LinkedList();
        for (Object aTempList : tempList) {
            tempElement = (KnuthElement) aTempList;
            tempElement.setPosition(new NonLeafPosition(this, tempElement.getPosition()));
            returnedList.add(tempElement);
        }

        return returnedList;
    }


    @Override
    public boolean hasLineAreaDescendant() {
        return label.hasLineAreaDescendant() || body.hasLineAreaDescendant();
    }

    @Override
    public int getBaselineOffset() {
        if (label.hasLineAreaDescendant()) {
            return label.getBaselineOffset();
        } else if (body.hasLineAreaDescendant()) {
            return body.getBaselineOffset();
        } else {
            throw newNoLineAreaDescendantException();
        }
    }

    /**
     * Add the areas for the break points.
     *
     * @param parentIter the position iterator
     * @param layoutContext the layout context for adding areas
     */
    @Override
    public void addAreas(PositionIterator parentIter,
                         LayoutContext layoutContext) {
        getParentArea(null);

        addId();

        LayoutContext lc = LayoutContext.offspringOf(layoutContext);
        Position firstPos = null;
        Position lastPos = null;

        // "unwrap" the NonLeafPositions stored in parentIter
        LinkedList<Position> positionList = new LinkedList<Position>();
        Position pos;
        while (parentIter.hasNext()) {
            pos = parentIter.next();
            if (pos.getIndex() >= 0) {
                if (firstPos == null) {
                    firstPos = pos;
                }
                lastPos = pos;
            }
            if (pos instanceof NonLeafPosition && pos.getPosition() != null) {
                // pos contains a ListItemPosition created by this ListBlockLM
                positionList.add(pos.getPosition());
            }
        }
        if (positionList.isEmpty()) {
            reset();
            return;
        }

        registerMarkers(true, isFirst(firstPos), isLast(lastPos));

        // use the first and the last ListItemPosition to determine the
        // corresponding indexes in the original labelList and bodyList
        int labelFirstIndex = ((ListItemPosition) positionList.getFirst()).getLabelFirstIndex();
        int labelLastIndex = ((ListItemPosition) positionList.getLast()).getLabelLastIndex();
        int bodyFirstIndex = ((ListItemPosition) positionList.getFirst()).getBodyFirstIndex();
        int bodyLastIndex = ((ListItemPosition) positionList.getLast()).getBodyLastIndex();

        //Determine previous break if any (in item label list)
        int previousBreak = ElementListUtils.determinePreviousBreak(labelList, labelFirstIndex);
        SpaceResolver.performConditionalsNotification(labelList,
                labelFirstIndex, labelLastIndex, previousBreak);

        //Determine previous break if any (in item body list)
        previousBreak = ElementListUtils.determinePreviousBreak(bodyList, bodyFirstIndex);
        SpaceResolver.performConditionalsNotification(bodyList,
                bodyFirstIndex, bodyLastIndex, previousBreak);

        // add label areas
        if (labelFirstIndex <= labelLastIndex) {
            KnuthPossPosIter labelIter = new KnuthPossPosIter(labelList,
                    labelFirstIndex, labelLastIndex + 1);
            lc.setFlags(LayoutContext.FIRST_AREA, layoutContext.isFirstArea());
            lc.setFlags(LayoutContext.LAST_AREA, layoutContext.isLastArea());
            // set the space adjustment ratio
            lc.setSpaceAdjust(layoutContext.getSpaceAdjust());
            // TO DO: use the right stack limit for the label
            lc.setStackLimitBP(layoutContext.getStackLimitBP());
            label.addAreas(labelIter, lc);
        }

        // add body areas
        if (bodyFirstIndex <= bodyLastIndex) {
            KnuthPossPosIter bodyIter = new KnuthPossPosIter(bodyList,
                    bodyFirstIndex, bodyLastIndex + 1);
            lc.setFlags(LayoutContext.FIRST_AREA, layoutContext.isFirstArea());
            lc.setFlags(LayoutContext.LAST_AREA, layoutContext.isLastArea());
            // set the space adjustment ratio
            lc.setSpaceAdjust(layoutContext.getSpaceAdjust());
            // TO DO: use the right stack limit for the body
            lc.setStackLimitBP(layoutContext.getStackLimitBP());
            body.addAreas(bodyIter, lc);
        }

        // after adding body areas, set the maximum area bpd
        int childCount = curBlockArea.getChildAreas().size();
        assert childCount >= 1 && childCount <= 2;
        int itemBPD = ((Block)curBlockArea.getChildAreas().get(0)).getAllocBPD();
        if (childCount == 2) {
            itemBPD = Math.max(itemBPD, ((Block)curBlockArea.getChildAreas().get(1)).getAllocBPD());
        }
        curBlockArea.setBPD(itemBPD);

        registerMarkers(false, isFirst(firstPos), isLast(lastPos));

        // We are done with this area add the background
        TraitSetter.addBackground(curBlockArea,
                getListItemFO().getCommonBorderPaddingBackground(),
                this);
        TraitSetter.addSpaceBeforeAfter(curBlockArea, layoutContext.getSpaceAdjust(),
                effSpaceBefore, effSpaceAfter);

        flush();

        curBlockArea = null;
        resetSpaces();

        checkEndOfLayout(lastPos);
    }

    /**
     * Return an Area which can contain the passed childArea. The childArea
     * may not yet have any content, but it has essential traits set.
     * In general, if the LayoutManager already has an Area it simply returns
     * it. Otherwise, it makes a new Area of the appropriate class.
     * It gets a parent area for its area by calling its parent LM.
     * Finally, based on the dimensions of the parent area, it initializes
     * its own area. This includes setting the content IPD and the maximum
     * BPD.
     *
     * @param childArea the child area
     * @return the parent are for the child
     */
    @Override
    public Area getParentArea(Area childArea) {
        if (curBlockArea == null) {
            curBlockArea = new Block();
            curBlockArea.setChangeBarList(getChangeBarList());

            // Set up dimensions
            /*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea);

            // set traits
            ListItem fo = getListItemFO();
            TraitSetter.setProducerID(curBlockArea, fo.getId());
            TraitSetter.addBorders(curBlockArea, fo.getCommonBorderPaddingBackground(),
                    discardBorderBefore, discardBorderAfter, false, false, this);
            TraitSetter.addPadding(curBlockArea, fo.getCommonBorderPaddingBackground(),
                    discardPaddingBefore, discardPaddingAfter, false, false, this);
            TraitSetter.addMargins(curBlockArea, fo.getCommonBorderPaddingBackground(),
                    fo.getCommonMarginBlock(), this);
            TraitSetter.addBreaks(curBlockArea, fo.getBreakBefore(), fo.getBreakAfter());

            int contentIPD = referenceIPD - getIPIndents();
            curBlockArea.setIPD(contentIPD);

            curBlockArea.setBidiLevel(fo.getBidiLevel());

            setCurrentArea(curBlockArea);
        }
        return curBlockArea;
    }

    /**
     * Add the child.
     * Rows return the areas returned by the child elements.
     * This simply adds the area to the parent layout manager.
     *
     * @param childArea the child area
     */
    @Override
    public void addChildArea(Area childArea) {
        if (curBlockArea != null) {
            curBlockArea.addBlock((Block) childArea);
        }
    }

    /** {@inheritDoc} */
    @Override
    public KeepProperty getKeepTogetherProperty() {
        return getListItemFO().getKeepTogether();
    }

    /** {@inheritDoc} */
    @Override
    public KeepProperty getKeepWithPreviousProperty() {
        return getListItemFO().getKeepWithPrevious();
    }

    /** {@inheritDoc} */
    @Override
    public KeepProperty getKeepWithNextProperty() {
        return getListItemFO().getKeepWithNext();
    }

    /** {@inheritDoc} */
    @Override
    public void reset() {
        super.reset();
        label.reset();
        body.reset();
    }

    @Override
    public int getBreakBefore() {
        int breakBefore = BreakOpportunityHelper.getBreakBefore(this);
        breakBefore = BreakUtil.compareBreakClasses(breakBefore, label.getBreakBefore());
        breakBefore = BreakUtil.compareBreakClasses(breakBefore, body.getBreakBefore());
        return breakBefore;
    }

    /** {@inheritDoc} */
    public boolean isRestartable() {
        return true;
    }
}

