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

import java.util.LinkedList;
import java.util.List;
import java.util.Collections;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.area.Area;
import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.layoutmgr.AbstractLayoutManager;
import org.apache.fop.layoutmgr.InlineKnuthSequence;
import org.apache.fop.layoutmgr.KnuthGlue;
import org.apache.fop.layoutmgr.KnuthPenalty;
import org.apache.fop.layoutmgr.KnuthSequence;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.TraitSetter;
import org.apache.fop.traits.MinOptMax;


/**
 * Base LayoutManager for leaf-node FObj, ie: ones which have no children.
 * These are all inline objects. Most of them cannot be split (Text is
 * an exception to this rule.)
 * This class can be extended to handle the creation and adding of the
 * inline area.
 */
public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
                                   implements InlineLevelLayoutManager {

    /** logging instance */
    protected static final Log log = LogFactory.getLog(LeafNodeLayoutManager.class);

    /** The inline area that this leafnode will add. */
    protected InlineArea curArea = null;
    /** Any border, padding and background properties applying to this area */
    protected CommonBorderPaddingBackground commonBorderPaddingBackground = null;
    /** The alignment context applying to this area */
    protected AlignmentContext alignmentContext = null;

    /** Flag to indicate if something was changed as part of the getChangeKnuthElements sequence */
    protected boolean somethingChanged = false;
    /** Our area info for the Knuth elements */
    protected AreaInfo areaInfo = null;

    /**
     * Store information about the inline area
     */
    protected class AreaInfo {
        /** letter space count */
        protected short letterSpaces;
        /** ipd of area */
        protected MinOptMax ipdArea;
        /** true if hyphenated */
        protected boolean isHyphenated;
        /** alignment context */
        protected AlignmentContext alignmentContext;

        /**
         * Construct an area information item.
         * @param letterSpaces letter space count
         * @param ipd inline progression dimension
         * @param isHyphenated true if hyphenated
         * @param alignmentContext an alignment context
         */
        public AreaInfo(short letterSpaces, MinOptMax ipd, boolean isHyphenated,
                        AlignmentContext alignmentContext) {
            this.letterSpaces = letterSpaces;
            this.ipdArea = ipd;
            this.isHyphenated = isHyphenated;
            this.alignmentContext = alignmentContext;
        }

    }

    /**
     * Create a Leaf node layout manager.
     * @param node the FObj to attach to this LM.
     */
    public LeafNodeLayoutManager(FObj node) {
        super(node);
    }

    /**
     * Create a Leaf node layout manager.
     */
    public LeafNodeLayoutManager() {
    }

    /**
     * get the inline area.
     * @param context the context used to create the area
     * @return the current inline area for this layout manager
     */
    public InlineArea get(LayoutContext context) {
        return curArea;
    }

    /**
     * Check if this inline area is resolved due to changes in
     * page or ipd.
     * Currently not used.
     * @return true if the area is resolved when adding
     */
    public boolean resolved() {
        return false;
    }

    /**
     * Set the current inline area.
     * @param ia the inline area to set for this layout manager
     */
    public void setCurrentArea(InlineArea ia) {
        curArea = ia;
    }

    /**
     * This is a leaf-node, so this method should never be called.
     * @param childArea the childArea to add
     */
    @Override
    public void addChildArea(Area childArea) {
        assert false;
    }

    /**
     * This is a leaf-node, so this method should never be called.
     * @param childArea the childArea to get the parent for
     * @return the parent area
     */
    @Override
    public Area getParentArea(Area childArea) {
        assert false;
        return null;
    }

    /**
     * Set the border and padding properties of the inline area.
     * @param commonBorderPaddingBackground the alignment adjust property
     */
    protected void setCommonBorderPaddingBackground(
            CommonBorderPaddingBackground commonBorderPaddingBackground) {
        this.commonBorderPaddingBackground = commonBorderPaddingBackground;
    }

    /**
     * Get the allocation ipd of the inline area.
     * This method may be overridden to handle percentage values.
     * @param refIPD the ipd of the parent reference area
     * @return the min/opt/max ipd of the inline area
     */
    protected MinOptMax getAllocationIPD(int refIPD) {
        return MinOptMax.getInstance(curArea.getIPD());
    }

    /**
     * Add the area for this layout manager.
     * This adds the single inline area to the parent.
     * @param posIter the position iterator
     * @param context the layout context for adding the area
     */
    @Override
    public void addAreas(PositionIterator posIter, LayoutContext context) {
        addId();

        InlineArea area = getEffectiveArea();
        if (area.getAllocIPD() > 0 || area.getAllocBPD() > 0) {
            offsetArea(area, context);
            widthAdjustArea(area, context);
            if (commonBorderPaddingBackground != null) {
                // Add border and padding to area
                TraitSetter.setBorderPaddingTraits(area,
                                                   commonBorderPaddingBackground,
                                                   false, false, this);
                TraitSetter.addBackground(area, commonBorderPaddingBackground, this);
            }
            parentLayoutManager.addChildArea(area);
        }

        while (posIter.hasNext()) {
            posIter.next();
        }
    }

    /**
     * @return the effective area to be added to the area tree. Normally, this is simply "curArea"
     * but in the case of page-number(-citation) curArea is cloned, updated and returned.
     */
    protected InlineArea getEffectiveArea() {
        return curArea;
    }

    /**
     * Offset this area.
     * Offset the inline area in the bpd direction when adding the
     * inline area.
     * This is used for vertical alignment.
     * Subclasses should override this if necessary.
     * @param area the inline area to be updated
     * @param context the layout context used for adding the area
     */
    protected void offsetArea(InlineArea area, LayoutContext context) {
        area.setBlockProgressionOffset(alignmentContext.getOffset());
    }

    /**
     * Creates a new alignment context or returns the current
     * alignment context.
     * This is used for vertical alignment.
     * Subclasses should override this if necessary.
     * @param context the layout context used
     * @return the appropriate alignment context
     */
    protected AlignmentContext makeAlignmentContext(LayoutContext context) {
        return context.getAlignmentContext();
    }

    /**
     * Adjust the width of the area when adding.
     * This uses the min/opt/max values to adjust the with
     * of the inline area by a percentage.
     * @param area the inline area to be updated
     * @param context the layout context for adding this area
     */
    protected void widthAdjustArea(InlineArea area, LayoutContext context) {
        double dAdjust = context.getIPDAdjust();
        int adjustment = 0;
        if (dAdjust < 0) {
            adjustment += (int) (dAdjust * areaInfo.ipdArea.getShrink());
        } else if (dAdjust > 0) {
            adjustment += (int) (dAdjust * areaInfo.ipdArea.getStretch());
        }
        area.setIPD(areaInfo.ipdArea.getOpt() + adjustment);
        area.setAdjustment(adjustment);
    }

    /** {@inheritDoc} */
    @Override
    public List getNextKnuthElements(LayoutContext context, int alignment) {
        curArea = get(context);

        if (curArea == null) {
            setFinished(true);
            return null;
        }

        alignmentContext = makeAlignmentContext(context);

        MinOptMax ipd = getAllocationIPD(context.getRefIPD());

        // create the AreaInfo object to store the computed values
        areaInfo = new AreaInfo((short) 0, ipd, false, alignmentContext);

        // node is a fo:ExternalGraphic, fo:InstreamForeignObject,
        // fo:PageNumber or fo:PageNumberCitation
        KnuthSequence seq = new InlineKnuthSequence();

        addKnuthElementsForBorderPaddingStart(seq);

        seq.add(new KnuthInlineBox(areaInfo.ipdArea.getOpt(), alignmentContext,
                                    notifyPos(new LeafPosition(this, 0)), false));

        addKnuthElementsForBorderPaddingEnd(seq);

        setFinished(true);
        return Collections.singletonList(seq);
    }

    /** {@inheritDoc} */
    public List addALetterSpaceTo(List oldList) {
        // return the unchanged elements
        return oldList;
    }

    /**
     * {@inheritDoc}
     * Only TextLM has a meaningful implementation of this method
     */
    public List addALetterSpaceTo(List oldList, int depth) {
        return addALetterSpaceTo(oldList);
    }

    /** {@inheritDoc} */
    public String getWordChars(Position pos) {
        return "";
    }

    /** {@inheritDoc} */
    public void hyphenate(Position pos, HyphContext hyphContext) {
    }

    /** {@inheritDoc} */
    public boolean applyChanges(List oldList) {
        setFinished(false);
        return false;
    }

    /**
     * {@inheritDoc}
     * Only TextLM has a meaningful implementation of this method
     */
    public boolean applyChanges(List oldList, int depth) {
        return applyChanges(oldList);
    }

    /**
     * {@inheritDoc}
     * No subclass has a meaningful implementation of this method
     */
    public List getChangedKnuthElements(List oldList, int alignment, int depth) {
        return getChangedKnuthElements(oldList, alignment);
    }

    /** {@inheritDoc} */
    @Override
    public List getChangedKnuthElements(List oldList, int alignment) {
        if (isFinished()) {
            return null;
        }

        LinkedList returnList = new LinkedList();

        addKnuthElementsForBorderPaddingStart(returnList);

        // fobj is a fo:ExternalGraphic, fo:InstreamForeignObject,
        // fo:PageNumber or fo:PageNumberCitation
        returnList.add(new KnuthInlineBox(areaInfo.ipdArea.getOpt(), areaInfo.alignmentContext,
                                          notifyPos(new LeafPosition(this, 0)), true));

        addKnuthElementsForBorderPaddingEnd(returnList);

        setFinished(true);
        return returnList;
    }

    /**
     * Creates Knuth elements for start border padding and adds them to the return list.
     * @param returnList return list to add the additional elements to
     */
    protected void addKnuthElementsForBorderPaddingStart(List returnList) {
        //Border and Padding (start)
        if (commonBorderPaddingBackground != null) {
            int ipStart = commonBorderPaddingBackground.getBorderStartWidth(false)
                         + commonBorderPaddingBackground.getPaddingStart(false, this);
            if (ipStart > 0) {
                // Add a non breakable glue
                returnList.add(new KnuthPenalty(0, KnuthPenalty.INFINITE,
                                                false, new LeafPosition(this, -1), true));
                returnList.add(new KnuthGlue(ipStart, 0, 0, new LeafPosition(this, -1), true));
            }
        }
    }

    /**
     * Creates Knuth elements for end border padding and adds them to the return list.
     * @param returnList return list to add the additional elements to
     */
    protected void addKnuthElementsForBorderPaddingEnd(List returnList) {
        //Border and Padding (after)
        if (commonBorderPaddingBackground != null) {
            int ipEnd = commonBorderPaddingBackground.getBorderEndWidth(false)
                        + commonBorderPaddingBackground.getPaddingEnd(false, this);
            if (ipEnd > 0) {
                // Add a non breakable glue
                returnList.add(new KnuthPenalty(0, KnuthPenalty.INFINITE,
                                                false, new LeafPosition(this, -1), true));
                returnList.add(new KnuthGlue(ipEnd, 0, 0, new LeafPosition(this, -1), true));
            }
        }
    }

}

