/*
 * 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 org.apache.fop.datatypes.Length;
import org.apache.fop.datatypes.LengthBase;
import org.apache.fop.datatypes.SimplePercentBaseContext;
import org.apache.fop.fo.Constants;
import org.apache.fop.fonts.Font;

/**
 * The alignment context is carried within a LayoutContext and as
 * part of the Knuth Inline elements to facilitate proper line building.
 * All measurements are in mpt.
 */
public class AlignmentContext implements Constants {

    /** The height or BPD of this context */
    private int areaHeight;
    /** The computed line-height property value applicable */
    private int lineHeight;
    /** The distance in BPD from the top of the box to the alignmentPoint */
    private int alignmentPoint;
    /** The baseline shift value in effect */
    private int baselineShiftValue;
    /** The computed alignment baseline identifier */
    private int alignmentBaselineIdentifier;
    /** The x height */
    private int xHeight;
    private ScaledBaselineTable scaledBaselineTable = null;
    private ScaledBaselineTable actualBaselineTable = null;
    private AlignmentContext parentAlignmentContext = null;

    /**
     * Creates a new instance of AlignmentContext
     * for graphics areas.
     * @param height the total height of the area
     * @param alignmentAdjust the alignment-adjust property
     * @param alignmentBaseline the alignment-baseline property
     * @param baselineShift the baseline-shift property
     * @param dominantBaseline the dominant-baseline property
     * @param parentAlignmentContext the parent alignment context
     */
    public AlignmentContext(int height
                            , Length alignmentAdjust
                            , int alignmentBaseline
                            , Length baselineShift
                            , int dominantBaseline
                            , AlignmentContext parentAlignmentContext) {

        this.areaHeight = height;
        this.lineHeight = height;
        this.xHeight = height;
        this.parentAlignmentContext = parentAlignmentContext;
        this.scaledBaselineTable = parentAlignmentContext.getScaledBaselineTable();
        setAlignmentBaselineIdentifier(alignmentBaseline
                                       , parentAlignmentContext.getDominantBaselineIdentifier());
        setBaselineShift(baselineShift);
        int dominantBaselineIdentifier = parentAlignmentContext.getDominantBaselineIdentifier();
        boolean newScaledBaselineTableRequired = false;
        if (baselineShiftValue != 0) {
            newScaledBaselineTableRequired = true;
        }
        switch (dominantBaseline) {
            case EN_AUTO:
                newScaledBaselineTableRequired = baselineShiftValue != 0;
                break;
            case EN_USE_SCRIPT: // TODO
                break;
            case EN_NO_CHANGE:
                break;
            case EN_RESET_SIZE:
                newScaledBaselineTableRequired = true;
                break;
            default:
                newScaledBaselineTableRequired = true;
                dominantBaselineIdentifier = dominantBaseline;
                break;
        }
        actualBaselineTable = ScaledBaselineTableFactory.makeGraphicsScaledBaselineTable(
                                                            height,
                                                            dominantBaselineIdentifier,
                                                            scaledBaselineTable.getWritingMode());
        if (newScaledBaselineTableRequired) {
            scaledBaselineTable = ScaledBaselineTableFactory.makeGraphicsScaledBaselineTable(
                                                            height,
                                                            dominantBaselineIdentifier,
                                                            scaledBaselineTable.getWritingMode());
        }
        setAlignmentAdjust(alignmentAdjust);
    }

    /**
     * Creates a new instance of AlignmentContext
     * @param font the font
     * @param lineHeight the computed value of the lineHeight property
     * @param alignmentAdjust the alignment-adjust property
     * @param alignmentBaseline the alignment-baseline property
     * @param baselineShift the baseline-shift property
     * @param dominantBaseline the dominant-baseline property
     * @param parentAlignmentContext the parent alignment context
     */
    public AlignmentContext(Font font
                            , int lineHeight
                            , Length alignmentAdjust
                            , int alignmentBaseline
                            , Length baselineShift
                            , int dominantBaseline
                            , AlignmentContext parentAlignmentContext) {
        this.areaHeight = font.getAscender() - font.getDescender();
        this.lineHeight = lineHeight;
        this.parentAlignmentContext = parentAlignmentContext;
        this.scaledBaselineTable = parentAlignmentContext.getScaledBaselineTable();
        this.xHeight = font.getXHeight();
        setAlignmentBaselineIdentifier(alignmentBaseline
                                       , parentAlignmentContext.getDominantBaselineIdentifier());
        setBaselineShift(baselineShift);
        int dominantBaselineIdentifier = parentAlignmentContext.getDominantBaselineIdentifier();
        boolean newScaledBaselineTableRequired = false;
        if (baselineShiftValue != 0) {
            newScaledBaselineTableRequired = true;
        }
        switch (dominantBaseline) {
            case EN_AUTO:
                newScaledBaselineTableRequired = baselineShiftValue != 0;
                break;
            case EN_USE_SCRIPT: // TODO
                break;
            case EN_NO_CHANGE:
                break;
            case EN_RESET_SIZE:
                newScaledBaselineTableRequired = true;
                break;
            default:
                newScaledBaselineTableRequired = true;
                dominantBaselineIdentifier = dominantBaseline;
                break;
        }
        actualBaselineTable = ScaledBaselineTableFactory.makeFontScaledBaselineTable(font,
                                                            dominantBaselineIdentifier,
                                                            scaledBaselineTable.getWritingMode());
        if (newScaledBaselineTableRequired) {
            scaledBaselineTable = ScaledBaselineTableFactory.makeFontScaledBaselineTable(font,
                                    dominantBaselineIdentifier,
                                    scaledBaselineTable.getWritingMode());
        }
        setAlignmentAdjust(alignmentAdjust);
    }

    /**
     * Creates a new instance of AlignmentContext based simply
     * on the font and the writing mode.
     * @param font the font
     * @param lineHeight the computed value of the lineHeight property
     * @param writingMode the current writing mode
     */
    public AlignmentContext(Font font, int lineHeight, int writingMode) {
        this.areaHeight = font.getAscender() - font.getDescender();
        this.lineHeight = lineHeight;
        this.xHeight = font.getXHeight();
        this.parentAlignmentContext = null;
        this.scaledBaselineTable
                    = ScaledBaselineTableFactory.makeFontScaledBaselineTable(font, writingMode);
        this.actualBaselineTable = scaledBaselineTable;
        this.alignmentBaselineIdentifier = getDominantBaselineIdentifier();
        this.alignmentPoint = font.getAscender();
        this.baselineShiftValue = 0;
    }

    /**
     * Returns the alignment point for this context.
     * This is the point on the start edge of the area this context
     * applies to measured from the before edge of the area.
     * @return the default alignment point
     */
    public int getAlignmentPoint() {
        return alignmentPoint;
    }

    /**
     * Returns the current value of baseline shift in effect.
     * @return the baseline shift
     */
    public int getBaselineShiftValue() {
        return baselineShiftValue;
    }

    /**
     * Returns the current alignment baseline identifier
     * @return the alignment baseline identifier
     */
    public int getAlignmentBaselineIdentifier() {
        return alignmentBaselineIdentifier;
    }

    /**
     * Sets the current alignment baseline identifer. For
     * alignment-baseline values of "auto" and "baseline" this
     * method does the conversion into the appropriate computed
     * value assuming script is "auto" and the fo is not fo:character.
     * @param alignmentBaseline the alignment-baseline property
     * @param parentDominantBaselineIdentifier the dominant baseline of the parent fo
     */
    private void setAlignmentBaselineIdentifier(int alignmentBaseline
                                               , int parentDominantBaselineIdentifier) {
        switch (alignmentBaseline) {
            case EN_AUTO: // fall through
            case EN_BASELINE:
                this.alignmentBaselineIdentifier = parentDominantBaselineIdentifier;
                break;
            case EN_BEFORE_EDGE:
            case EN_TEXT_BEFORE_EDGE:
            case EN_CENTRAL:
            case EN_MIDDLE:
            case EN_AFTER_EDGE:
            case EN_TEXT_AFTER_EDGE:
            case EN_IDEOGRAPHIC:
            case EN_ALPHABETIC:
            case EN_HANGING:
            case EN_MATHEMATICAL:
                this.alignmentBaselineIdentifier = alignmentBaseline;
                break;
        }
    }

    /**
     * Sets the current alignment baseline identifer. For
     * alignment-baseline values of "auto" and "baseline" this
     * method does the conversion into the appropriate computed
     * value assuming script is "auto" and the fo is not fo:character.
     * @param alignmentAdjust the alignment-adjust property
     */
    private void setAlignmentAdjust(Length alignmentAdjust) {
        int beforeEdge = actualBaselineTable.getBaseline(EN_BEFORE_EDGE);
        switch (alignmentAdjust.getEnum()) {
            case EN_AUTO:
                alignmentPoint = beforeEdge
                                    - actualBaselineTable.getBaseline(alignmentBaselineIdentifier);
                break;
            case EN_BASELINE:
                alignmentPoint = beforeEdge;
                break;
            case EN_BEFORE_EDGE:
            case EN_TEXT_BEFORE_EDGE:
            case EN_CENTRAL:
            case EN_MIDDLE:
            case EN_AFTER_EDGE:
            case EN_TEXT_AFTER_EDGE:
            case EN_IDEOGRAPHIC:
            case EN_ALPHABETIC:
            case EN_HANGING:
            case EN_MATHEMATICAL:
                alignmentPoint = beforeEdge
                                    - actualBaselineTable.getBaseline(alignmentAdjust.getEnum());
                break;
            default:
                alignmentPoint = beforeEdge
                    + alignmentAdjust.getValue(new SimplePercentBaseContext(null
                                                        , LengthBase.ALIGNMENT_ADJUST
                                                        , lineHeight));
                break;
        }
    }

    /**
     * Return the scaled baseline table for this context.
     * @return the scaled baseline table
     */
    public ScaledBaselineTable getScaledBaselineTable() {
        return this.scaledBaselineTable;
    }

    /**
     * Return the dominant baseline identifier.
     * @return the dominant baseline identifier
     */
    public int getDominantBaselineIdentifier() {
        return scaledBaselineTable.getDominantBaselineIdentifier();
    }

    /**
     * Return the writing mode.
     * @return the writing mode
     */
    public int getWritingMode() {
        return scaledBaselineTable.getWritingMode();
    }

    /**
     * Calculates the baseline shift value based on the baseline-shift
     * property value.
     * @param baselineShift the baseline shift property value
     * @return the computed baseline shift value
     */
    private void setBaselineShift(Length baselineShift) {
        baselineShiftValue = 0;
        ScaledBaselineTable sbt = null;
        switch (baselineShift.getEnum()) {
            case EN_BASELINE: //Nothing to do
                break;
            case EN_SUB:
                baselineShiftValue = Math.round(-(xHeight / 2)
                                + parentAlignmentContext.getActualBaselineOffset(EN_ALPHABETIC)
                                );
                break;
            case EN_SUPER:
                baselineShiftValue = Math.round(parentAlignmentContext.getXHeight()
                                + parentAlignmentContext.getActualBaselineOffset(EN_ALPHABETIC)
                                );
                break;
            case 0: // A <length> or <percentage> value
                baselineShiftValue = baselineShift.getValue(
                    new SimplePercentBaseContext(null
                                                , LengthBase.CUSTOM_BASE
                                                , parentAlignmentContext.getLineHeight()));
                break;
        }
    }

    /**
     * Return the parent alignment context.
     * @return the parent alignment context
     */
    public AlignmentContext getParentAlignmentContext() {
        return parentAlignmentContext;
    }

    /**
     * Return the offset between the current dominant baseline and
     * the parent dominant baseline.
     * @return the offset in shift direction
     */
    public int getBaselineOffset() {
        if (parentAlignmentContext == null) {
            return 0;
        }
        return parentAlignmentContext.getScaledBaselineTable()
                                    .getBaseline(alignmentBaselineIdentifier)
                - scaledBaselineTable
                    .deriveScaledBaselineTable(parentAlignmentContext.getDominantBaselineIdentifier())
                    .getBaseline(alignmentBaselineIdentifier)
                - scaledBaselineTable
                    .getBaseline(parentAlignmentContext.getDominantBaselineIdentifier())
                + baselineShiftValue;
    }

    /**
     * Return the offset between the current dominant baseline and
     * the outermost parent dominant baseline.
     * @return the offet in shift direction
     */
    public int getTotalBaselineOffset() {
        int offset = 0;
        if (parentAlignmentContext != null) {
            offset = getBaselineOffset() + parentAlignmentContext.getTotalBaselineOffset();
        }
        return offset;
    }

    /**
     * Return the offset between the alignment baseline and
     * the outermost parent dominant baseline.
     * @return the offset in shift direction
     */
    public int getTotalAlignmentBaselineOffset() {
        return getTotalAlignmentBaselineOffset(alignmentBaselineIdentifier);
    }

    /**
     * Return the offset between the given alignment baseline and
     * the outermost parent dominant baseline.
     * @param alignmentBaselineId the alignment baseline
     * @return the offset
     */
    public int getTotalAlignmentBaselineOffset(int alignmentBaselineId) {
        int offset = baselineShiftValue;
        if (parentAlignmentContext != null) {
            offset = parentAlignmentContext.getTotalBaselineOffset()
                    + parentAlignmentContext.getScaledBaselineTable()
                        .getBaseline(alignmentBaselineId)
                    + baselineShiftValue;
        }
        return offset;
    }

    /**
     * Return the offset between the dominant baseline and
     * the given actual baseline
     * @param baselineIdentifier the baseline
     * @return the offset
     */
    public int getActualBaselineOffset(int baselineIdentifier) {
        // This is the offset from the dominant baseline to the alignment baseline
        int offset = getTotalAlignmentBaselineOffset() - getTotalBaselineOffset();
        // Add the offset to the actual baseline we want
        offset += actualBaselineTable.deriveScaledBaselineTable(alignmentBaselineIdentifier)
                    .getBaseline(baselineIdentifier);
        return offset;
    }

    /**
     * Return the offset the outermost parent dominant baseline
     * and the top of this box.
     * @return the offset
     */
    private int getTotalTopOffset() {
        int offset = getTotalAlignmentBaselineOffset() + getAltitude();
        return offset;
    }

    /**
     * Return the total height of the context.
     * @return the height
     */
    public int getHeight() {
        return areaHeight;
    }

    /**
     * Return the line height of the context.
     * @return the height
     */
    public int getLineHeight() {
        return lineHeight;
    }

    /**
     * The altitude of the context that is the height above the
     * alignment point.
     * @return the altitude
     */
    public int getAltitude() {
        return alignmentPoint;
    }

    /**
     * The depth of the context that is the height below
     * alignment point.
     * @return the altitude
     */
    public int getDepth() {
        return getHeight() - alignmentPoint;
    }

    /**
     * The x height of the context.
     * @return the x height
     */
    public int getXHeight() {
        return this.xHeight;
    }

    /**
     * Resizes the line as specified. Assumes that the new alignment point
     * is on the dominant baseline, that is this function should be called for
     * line areas only.
     * @param newLineHeight the new height of the line
     * @param newAlignmentPoint the new alignment point
     */
    public void resizeLine(int newLineHeight, int newAlignmentPoint) {
        areaHeight = newLineHeight;
        alignmentPoint = newAlignmentPoint;
        scaledBaselineTable.setBeforeAndAfterBaselines(alignmentPoint
                                                        , alignmentPoint - areaHeight);
    }

    /**
     * Returns the offset from the before-edge of the parent to
     * this context.
     * @return the offset for rendering
     */
    public int getOffset() {
        int offset = 0;
        if (parentAlignmentContext != null) {
            offset = parentAlignmentContext.getTotalTopOffset() - getTotalTopOffset();
        } else {
            offset = getAltitude() - scaledBaselineTable.getBaseline(EN_TEXT_BEFORE_EDGE);
        }
        return offset;
    }

    /**
     * Returns an indication if we still use the initial baseline table.
     * The initial baseline table is the table generated by the Line LM.
     * @return true if this is still the initial baseline table
     */
    public boolean usesInitialBaselineTable() {
        return parentAlignmentContext == null
               || (scaledBaselineTable == parentAlignmentContext.getScaledBaselineTable()
                    && parentAlignmentContext.usesInitialBaselineTable());
    }

    private boolean isHorizontalWritingMode() {
        return (getWritingMode() == EN_LR_TB || getWritingMode() == EN_RL_TB);
    }

    /** {@inheritDoc} */
    public String toString() {
        StringBuffer sb = new StringBuffer(64);
        sb.append("ah=" + areaHeight);
        sb.append(" lp=" + lineHeight);
        sb.append(" ap=" + alignmentPoint);
        sb.append(" ab=" + alignmentBaselineIdentifier);
        sb.append(" bs=" + baselineShiftValue);
        return sb.toString();
    }

}
