/*
 * 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.Collections;
import java.util.List;

import org.apache.fop.fo.Constants;
import org.apache.fop.layoutmgr.inline.AlignmentContext;
import org.apache.fop.layoutmgr.inline.HyphContext;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.traits.WritingMode;


/**
 * This class is used to pass information to the getNextKnuthElements()
 * method. It is set up by higher level LM and used by lower level LM.
 */
public final class LayoutContext {

    /** Generated break possibility is first in a new area */
    public static final int NEW_AREA = 0x01;

    /**
     * If this flag is set, it indicates that any break-before values other than "auto" should
     * not cause a mandatory break as this break was already handled by a parent layout manager.
     */
    public static final int SUPPRESS_BREAK_BEFORE = 0x02;

    public static final int FIRST_AREA = 0x04;

    public static final int LAST_AREA = 0x08;

    public static final int RESOLVE_LEADING_SPACE = 0x10;

    private static final int TREAT_AS_ARTIFACT = 0x20;

    private int flags; // Contains some set of flags defined above

    /**
     * Total available stacking dimension for a "galley-level" layout
     * manager in block-progression-direction. It is passed by the
     * parent LM.
     * These LM <b>may</b> wish to pass this information down to lower
     * level LM to allow them to optimize returned break possibilities.
     */
    private MinOptMax stackLimitBP;

    /** to keep track of spanning in multi-column layout */
    private int currentSpan = Constants.NOT_SET;
    private int nextSpan = Constants.NOT_SET;

    /** inline-progression-dimension of nearest ancestor reference area */
    private int refIPD;
    //TODO After the split of stackLimit into stackLimitBP and stackLimitIP there's now some
    //overlap with refIPD. Need to investigate how best to refactor that.

    /** the writing mode established by the nearest ancestor reference area */
    private WritingMode writingMode = WritingMode.LR_TB;

    /** Current pending space-after or space-end from preceding area */
    private SpaceSpecifier trailingSpace;

    /** Current pending space-before or space-start from ancestor areas */
    private SpaceSpecifier leadingSpace;

    /**
     * A list of pending marks (border and padding) on the after edge when a page break occurs.
     * May be null.
     */
    private List pendingAfterMarks;

    /**
     * A list of pending marks (border and padding) on the before edge when a page break occurs.
     * May be null.
     */
    private List pendingBeforeMarks;

    /** Current hyphenation context. May be null. */
    private HyphContext hyphContext;

    /** Alignment in BP direction */
    private int bpAlignment = Constants.EN_START;

    /** Stretch or shrink value when making areas. */
    private double ipdAdjust;

    /** Stretch or shrink value when adding spaces. */
    private double dSpaceAdjust;

    private AlignmentContext alignmentContext;

    /** Amount of space before / start */
    private int spaceBefore;
    /** Amount of space after / end */
    private int spaceAfter;

    /** Amount of space to reserve at the beginning of each line */
    private int lineStartBorderAndPaddingWidth;
    /** Amount of space to reserve at the end of each line */
    private int lineEndBorderAndPaddingWidth;

    private int breakBefore;
    private int breakAfter;

    private Keep pendingKeepWithNext = Keep.KEEP_AUTO;
    private Keep pendingKeepWithPrevious = Keep.KEEP_AUTO;

    private int disableColumnBalancing;

    public static LayoutContext newInstance() {
        return new LayoutContext(0);
    }

    public static LayoutContext copyOf(LayoutContext copy) {
        return new LayoutContext(copy);
    }

    /**
     * Returns a descendant of the given layout context. The new context is the same as
     * what would have been created by {@link #newInstance()}, except for inheritable
     * properties that are passed on by the parent. At the moment, the only inheritable
     * property is the value returned by {@link #treatAsArtifact()}.
     */
    public static LayoutContext offspringOf(LayoutContext parent) {
        LayoutContext offspring = new LayoutContext(0);
        offspring.setTreatAsArtifact(parent.treatAsArtifact());
        return offspring;
    }

    private LayoutContext(LayoutContext parentLC) {
        this.flags = parentLC.flags;
        this.refIPD = parentLC.refIPD;
        this.writingMode = parentLC.writingMode;
        setStackLimitBP(parentLC.getStackLimitBP());
        this.leadingSpace = parentLC.leadingSpace; //???
        this.trailingSpace = parentLC.trailingSpace; //???
        this.hyphContext = parentLC.hyphContext;
        this.bpAlignment = parentLC.bpAlignment;
        this.dSpaceAdjust = parentLC.dSpaceAdjust;
        this.ipdAdjust = parentLC.ipdAdjust;
        this.alignmentContext = parentLC.alignmentContext;
        this.lineStartBorderAndPaddingWidth = parentLC.lineStartBorderAndPaddingWidth;
        this.lineEndBorderAndPaddingWidth = parentLC.lineEndBorderAndPaddingWidth;
        copyPendingMarksFrom(parentLC);
        this.pendingKeepWithNext = parentLC.pendingKeepWithNext;
        this.pendingKeepWithPrevious = parentLC.pendingKeepWithPrevious;
        // Copy other fields as necessary.
        this.disableColumnBalancing = parentLC.disableColumnBalancing;
    }

    private LayoutContext(int flags) {
        this.flags = flags;
        this.refIPD = 0;
        stackLimitBP = MinOptMax.ZERO;
        leadingSpace = null;
        trailingSpace = null;
    }

    /** @param source from which pending marks are copied */
    public void copyPendingMarksFrom(LayoutContext source) {
        if (source.pendingAfterMarks != null) {
            this.pendingAfterMarks = new java.util.ArrayList(source.pendingAfterMarks);
        }
        if (source.pendingBeforeMarks != null) {
            this.pendingBeforeMarks = new java.util.ArrayList(source.pendingBeforeMarks);
        }
    }

    /** @param flags to set */
    public void setFlags(int flags) {
        setFlags(flags, true);
    }

    /**
     * @param flags to set or clear
     * @param bSet true to set, false to clear
     */
    public void setFlags(int flags, boolean bSet) {
        if (bSet) {
            this.flags |= flags;
        } else {
            this.flags &= ~flags;
        }
    }

    /** @param flags to clear */
    public void unsetFlags(int flags) {
        setFlags(flags, false);
    }

    /** @return true if new area is set */
    public boolean isStart() {
        return ((this.flags & NEW_AREA) != 0);
    }

    /** @return true if new area is set and leading space is non-null */
    public boolean startsNewArea() {
        return ((this.flags & NEW_AREA) != 0 && leadingSpace != null);
    }

    /** @return true if first area is set */
    public boolean isFirstArea() {
        return ((this.flags & FIRST_AREA) != 0);
    }

    /** @return true if last area is set */
    public boolean isLastArea() {
        return ((this.flags & LAST_AREA) != 0);
    }

    /** @return true if suppress break before is set */
    public boolean suppressBreakBefore() {
        return ((this.flags & SUPPRESS_BREAK_BEFORE) != 0);
    }

    /**
     * Returns the strength of a keep-with-next currently pending.
     * @return the keep-with-next strength
     */
    public Keep getKeepWithNextPending() {
        return this.pendingKeepWithNext;
    }

    /**
     * Returns the strength of a keep-with-previous currently pending.
     * @return the keep-with-previous strength
     */
    public Keep getKeepWithPreviousPending() {
        return this.pendingKeepWithPrevious;
    }

    /**
     * Clears any pending keep-with-next strength.
     */
    public void clearKeepWithNextPending() {
        this.pendingKeepWithNext = Keep.KEEP_AUTO;
    }

    /**
     * Clears any pending keep-with-previous strength.
     */
    public void clearKeepWithPreviousPending() {
        this.pendingKeepWithPrevious = Keep.KEEP_AUTO;
    }

    /**
     * Clears both keep-with-previous and keep-with-next strengths.
     */
    public void clearKeepsPending() {
        clearKeepWithPreviousPending();
        clearKeepWithNextPending();
    }

    /**
     * Updates the currently pending keep-with-next strength.
     * @param keep the new strength to consider
     */
    public void updateKeepWithNextPending(Keep keep) {
        this.pendingKeepWithNext = this.pendingKeepWithNext.compare(keep);
    }

    /**
     * Updates the currently pending keep-with-previous strength.
     * @param keep the new strength to consider
     */
    public void updateKeepWithPreviousPending(Keep keep) {
        this.pendingKeepWithPrevious = this.pendingKeepWithPrevious.compare(keep);
    }

    /**
     * Indicates whether a keep-with-next constraint is pending.
     * @return true if a keep-with-next constraint is pending
     */
    public boolean isKeepWithNextPending() {
        return !getKeepWithNextPending().isAuto();
    }

    /**
     * Indicates whether a keep-with-previous constraint is pending.
     * @return true if a keep-with-previous constraint is pending
     */
    public boolean isKeepWithPreviousPending() {
        return !getKeepWithPreviousPending().isAuto();
    }

    /** @param space leading space */
    public void setLeadingSpace(SpaceSpecifier space) {
        leadingSpace = space;
    }

    /** @return leading space */
    public SpaceSpecifier getLeadingSpace() {
        return leadingSpace;
    }

    /** @return true if resolve leading space is set */
    public boolean resolveLeadingSpace() {
        return ((this.flags & RESOLVE_LEADING_SPACE) != 0);
    }

    /** @param space trailing space */
    public void setTrailingSpace(SpaceSpecifier space) {
        trailingSpace = space;
    }

    /** @return trailing space */
    public SpaceSpecifier getTrailingSpace() {
        return trailingSpace;
    }

    /**
     * Adds a border or padding element to the pending list which will be used to generate
     * the right element list for break possibilities. Conditionality resolution will be done
     * elsewhere.
     * @param element the border, padding or space element
     */
    public void addPendingAfterMark(UnresolvedListElementWithLength element) {
        if (this.pendingAfterMarks == null) {
            this.pendingAfterMarks = new java.util.ArrayList();
        }
        this.pendingAfterMarks.add(element);
    }

    /**
     * @return the pending border and padding elements at the after edge
     * @see #addPendingAfterMark(UnresolvedListElementWithLength)
     */
    public List getPendingAfterMarks() {
        if (this.pendingAfterMarks != null) {
            return Collections.unmodifiableList(this.pendingAfterMarks);
        } else {
            return null;
        }
    }

    /**
     * Clears all pending marks on the LayoutContext.
     */
    public void clearPendingMarks() {
        this.pendingBeforeMarks = null;
        this.pendingAfterMarks = null;
    }

    /**
     * Adds a border or padding element to the pending list which will be used to generate
     * the right element list for break possibilities. Conditionality resolution will be done
     * elsewhere.
     * @param element the border, padding or space element
     */
    public void addPendingBeforeMark(UnresolvedListElementWithLength element) {
        if (this.pendingBeforeMarks == null) {
            this.pendingBeforeMarks = new java.util.ArrayList();
        }
        this.pendingBeforeMarks.add(element);
    }

    /**
     * @return the pending border and padding elements at the before edge
     * @see #addPendingBeforeMark(UnresolvedListElementWithLength)
     */
    public List getPendingBeforeMarks() {
        if (this.pendingBeforeMarks != null) {
            return Collections.unmodifiableList(this.pendingBeforeMarks);
        } else {
            return null;
        }
    }

    /**
     * Sets the stack limit in block-progression-dimension.
     * @param limit the stack limit
     */
    public void setStackLimitBP(MinOptMax limit) {
        stackLimitBP = limit;
    }

    /**
     * Returns the stack limit in block-progression-dimension.
     * @return the stack limit
     */
    public MinOptMax getStackLimitBP() {
        return stackLimitBP;
    }

    /**
     * Sets the inline-progression-dimension of the nearest ancestor reference area.
     * @param ipd of nearest ancestor reference area
     */
    public void setRefIPD(int ipd) {
        refIPD = ipd;
    }

    /**
     * Returns the inline-progression-dimension of the nearest ancestor reference area.
     *
     * @return the inline-progression-dimension of the nearest ancestor reference area
     */
    public int getRefIPD() {
        return refIPD;
    }

    /** @param hyph a hyphenation context */
    public void setHyphContext(HyphContext hyph) {
        hyphContext = hyph;
    }

    /** @return hyphenation context */
    public HyphContext getHyphContext() {
        return hyphContext;
    }

    /**
     * Sets the currently applicable alignment in BP direction.
     * @param alignment one of EN_START, EN_JUSTIFY etc.
     */
    public void setBPAlignment(int alignment) {
        this.bpAlignment = alignment;
    }

    /** @return the currently applicable alignment in BP direction (EN_START, EN_JUSTIFY...) */
    public int getBPAlignment() {
        return this.bpAlignment;
    }

    /** @param adjust space adjustment */
    public void setSpaceAdjust(double adjust) {
        dSpaceAdjust = adjust;
    }

    /** @return space adjustment */
    public double getSpaceAdjust() {
        return dSpaceAdjust;
    }

    /** @param ipdA ipd adjustment */
    public void setIPDAdjust(double ipdA) {
        ipdAdjust = ipdA;
    }

    /** @return ipd adjustment */
    public double getIPDAdjust() {
        return ipdAdjust;
    }

    /** @param alignmentContext alignment context */
    public void setAlignmentContext(AlignmentContext alignmentContext) {
        this.alignmentContext = alignmentContext;
    }

    /** @return alignment context */
    public AlignmentContext getAlignmentContext() {
        return this.alignmentContext;
    }

    /**
     * Reset alignment context.
     */
    public void resetAlignmentContext() {
        if (this.alignmentContext != null) {
            this.alignmentContext = this.alignmentContext.getParentAlignmentContext();
        }
    }

    /**
     * Get the width to be reserved for border and padding at the start of the line.
     * @return the width to be reserved
     */
    public int getLineStartBorderAndPaddingWidth() {
        return lineStartBorderAndPaddingWidth;
    }

    /**
     * Set the width to be reserved for border and padding at the start of the line.
     * @param lineStartBorderAndPaddingWidth the width to be reserved
     */
    public void setLineStartBorderAndPaddingWidth(int lineStartBorderAndPaddingWidth) {
        this.lineStartBorderAndPaddingWidth = lineStartBorderAndPaddingWidth;
    }

    /**
     * Get the width to be reserved for border and padding at the end of the line.
     * @return the width to be reserved
     */
    public int getLineEndBorderAndPaddingWidth() {
        return lineEndBorderAndPaddingWidth;
    }

    /**
     * Set the width to be reserved for border and padding at the end of the line.
     * @param lineEndBorderAndPaddingWidth the width to be reserved
     */
    public void setLineEndBorderAndPaddingWidth(int lineEndBorderAndPaddingWidth) {
        this.lineEndBorderAndPaddingWidth = lineEndBorderAndPaddingWidth;
    }

    /**
     * @return one of: {@link Constants#NOT_SET}, {@link Constants#EN_NONE}
     *                  {@link Constants#EN_ALL}
     */
    public int getNextSpan() {
        return nextSpan;
    }

    /**
     * @return one of: {@link Constants#NOT_SET}, {@link Constants#EN_NONE}
     *                  {@link Constants#EN_ALL}
     */
    public int getCurrentSpan() {
        return (currentSpan == Constants.NOT_SET)
                ? Constants.EN_NONE : currentSpan;
    }

    /**
     * Used to signal the PSLM that the element list ends early because of a span change in
     * multi-column layout.
     * @param span the new span value (legal values: NOT_SET, EN_NONE, EN_ALL)
     */
    public void signalSpanChange(int span) {
        switch (span) {
        case Constants.NOT_SET:
        case Constants.EN_NONE:
        case Constants.EN_ALL:
            this.currentSpan = this.nextSpan;
            this.nextSpan = span;
            break;
        default:
            assert false;
            throw new IllegalArgumentException("Illegal value on signalSpanChange() for span: "
                    + span);
        }
    }

    /**
     * Get the writing mode of the relevant reference area.
     * @return the applicable writing mode
     */
    public WritingMode getWritingMode() {
        return writingMode;
    }

    /**
     * Set the writing mode.
     * @param writingMode the writing mode
     */
    public void setWritingMode(WritingMode writingMode) {
        this.writingMode = writingMode;
    }

    /**
     * Get the current amount of space before / start
     * @return the space before / start amount
     */
    public int getSpaceBefore() {
        return spaceBefore;
    }

    /**
     * Set the amount of space before / start
     * @param spaceBefore the amount of space before / start
     */
    public void setSpaceBefore(int spaceBefore) {
        this.spaceBefore = spaceBefore;
    }

    /**
     * Get the current amount of space after / end
     * @return the space after / end amount
     */
    public int getSpaceAfter() {
        return spaceAfter;
    }

    /**
     * Set the amount of space after / end
     * @param spaceAfter the amount of space after / end
     */
    public void setSpaceAfter(int spaceAfter) {
        this.spaceAfter = spaceAfter;
    }

    /**
     * Returns the value of the break before the element whose
     * {@link LayoutManager#getNextKnuthElements(LayoutContext, int)} method has just been
     * called.
     *
     * @return one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN},
     * {@link Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE}, or
     * {@link Constants#EN_ODD_PAGE}
     */
    public int getBreakBefore() {
        return breakBefore;
    }

    /**
     * Sets the value of the break before the current element.
     *
     * @param breakBefore the value of the break-before
     * @see #getBreakBefore()
     */
    public void setBreakBefore(int breakBefore) {
        this.breakBefore = breakBefore;
    }

    /**
     * Returns the value of the break after the element whose
     * {@link LayoutManager#getNextKnuthElements(LayoutContext, int)} method has just been
     * called.
     *
     * @return one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN},
     * {@link Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE}, or
     * {@link Constants#EN_ODD_PAGE}
     */
    public int getBreakAfter() {
        return breakAfter;
    }


    /**
     * Sets the value of the break after the current element.
     *
     * @param breakAfter the value of the break-after
     * @see #getBreakAfter()
     */
    public void setBreakAfter(int breakAfter) {
        this.breakAfter = breakAfter;
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        return "Layout Context:"
                + "\nStack Limit BPD: \t"
                + (getStackLimitBP() == null ? "null" : getStackLimitBP().toString())
                + "\nTrailing Space: \t"
                + (getTrailingSpace() == null ? "null" : getTrailingSpace().toString())
                + "\nLeading Space: \t"
                + (getLeadingSpace() == null ? "null" : getLeadingSpace().toString())
                + "\nReference IPD: \t" + getRefIPD()
                + "\nSpace Adjust: \t" + getSpaceAdjust()
                + "\nIPD Adjust: \t" + getIPDAdjust()
                + "\nResolve Leading Space: \t" + resolveLeadingSpace()
                + "\nSuppress Break Before: \t" + suppressBreakBefore()
                + "\nIs First Area: \t" + isFirstArea()
                + "\nStarts New Area: \t" + startsNewArea()
                + "\nIs Last Area: \t" + isLastArea()
                + "\nKeeps: \t[keep-with-next=" + getKeepWithNextPending()
                + "][keep-with-previous=" + getKeepWithPreviousPending() + "] pending"
                + "\nBreaks: \tforced [" + (breakBefore != Constants.EN_AUTO ? "break-before" : "") + "]["
                + (breakAfter != Constants.EN_AUTO ? "break-after" : "") + "]";
    }

    /**
     * Returns whether the column balancer should be disabled before a spanning block
     *
     * @return one of {@link Constants#EN_TRUE}, {@link Constants#EN_FALSE}
     */
    public int getDisableColumnBalancing() {
        return disableColumnBalancing;
    }

    /**
     * Sets whether the column balancer should be disabled before a spanning block
     *
     * @param disableColumnBalancing the value of the fox:disable-column-balancing property
     * @see #getDisableColumnBalancing()
     */
    public void setDisableColumnBalancing(int disableColumnBalancing) {
        this.disableColumnBalancing = disableColumnBalancing;
    }

    public boolean treatAsArtifact() {
        return (flags & TREAT_AS_ARTIFACT) != 0;
    }

    public void setTreatAsArtifact(boolean treatAsArtifact) {
        setFlags(TREAT_AS_ARTIFACT, treatAsArtifact);
    }
}

