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

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

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

import org.apache.fop.fo.flow.ChangeBar;
import org.apache.fop.traits.BorderProps;
import org.apache.fop.traits.WritingModeTraitsGetter;

// If the area appears more than once in the output
// or if the area has external data it is cached
// to keep track of it and to minimize rendered output
// renderers can render the output once and display it
// for every occurence
// this should also extend to all outputs (including PDFGraphics2D)
// and all types of renderers

/**
 * Base object for all areas.
 */
public class Area extends AreaTreeObject implements Serializable {

    private static final long serialVersionUID = 6342888466142626492L;

    // orientations for reference areas
    /**
     * Normal orientation
     */
    public static final int ORIENT_0 = 0;

    /**
     * Rotated 90 degrees clockwise
     */
    public static final int ORIENT_90 = 1;

    /**
     * Rotate 180 degrees
     */
    public static final int ORIENT_180 = 2;

    /**
     * Rotated 270 degrees clockwise
     */
    public static final int ORIENT_270 = 3;

    // area class values

    /**
     * Normal class
     */
    public static final int CLASS_NORMAL = 0;

    /**
     * Fixed position class
     */
    public static final int CLASS_FIXED = 1;

    /**
     * Absolute position class
     */
    public static final int CLASS_ABSOLUTE = 2;

    /**
     * Before float class
     */
    public static final int CLASS_BEFORE_FLOAT = 3;

    /**
     * Footnote class
     */
    public static final int CLASS_FOOTNOTE = 4;

    /**
     * Side float class
     */
    public static final int CLASS_SIDE_FLOAT = 5;

    // IMPORTANT: make sure this is the maximum + 1
    /**
     * Maximum class count
     */
    public static final int CLASS_MAX = CLASS_SIDE_FLOAT + 1;

    private int areaClass = CLASS_NORMAL;

    /** the area's inline-progression-dimension */
    protected int ipd;

    /** the area's block-progression-dimension */
    protected int bpd;

    protected int effectiveIPD = -1;

    /**
     * Resolved bidirectional level for area.
     */
    protected int bidiLevel = -1;

    /**
     * Traits for this area.
     */
    protected TreeMap<Integer, Object> traits;

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

    /**
     * The active change bar list
     */
    private List<ChangeBar> changeBarList;

    /**
     * Returns the active change bar list.
     *
     * @return The active change bar list
     */
    public List<ChangeBar> getChangeBarList() {
        return changeBarList;
    }

    /**
     * Sets the active change bar list.
     *
     * @param changeBarList The active change bar list
     */
    public void setChangeBarList(List<ChangeBar> changeBarList) {
        this.changeBarList = changeBarList;
    }

    /**
     * Get the area class of this area.
     *
     * @return the area class
     */
    public int getAreaClass() {
        return this.areaClass;
    }

    /** {@inheritDoc} */
    public Object clone() throws CloneNotSupportedException {
        Area area = (Area) super.clone();
        if (traits != null) {
            area.traits = (TreeMap<Integer, Object>) traits.clone();
        }
        return area;
    }

    /**
     * Set the area class of this area.
     *
     * @param areaClass the area class
     */
    public void setAreaClass(int areaClass) {
        this.areaClass = areaClass;
    }

    /**
     * Set the inline progression dimension of content rectangle
     * for this area.
     *
     * @param ipd the new inline progression dimension
     * @see <a href="http://www.w3.org/TR/xsl/#inline-progression-dimension">ipd</a>
     */
    public void setIPD(int ipd) {
        this.ipd = ipd;
    }

    /**
     * Get the inline progression dimension of the content rectangle
     * for this area.
     *
     * @return the inline progression dimension
     * @see <a href="http://www.w3.org/TR/xsl/#inline-progression-dimension">ipd</a>
     */
    public int getIPD() {
        return ipd;
    }

    /**
     * Set the block progression dimension of the content rectangle
     * for this area.
     *
     * @param bpd the new block progression dimension
     * @see <a href="http://www.w3.org/TR/xsl/#block-progression-dimension">bpd</a>
     */
    public void setBPD(int bpd) {
        this.bpd = bpd;
    }

    /**
     * Get the block progression dimension of the content rectangle
     * for this area.
     *
     * @return the block progression dimension
     * @see <a href="http://www.w3.org/TR/xsl/#block-progression-dimension">bpd</a>
     */
    public int getBPD() {
        return bpd;
    }

    /**
     * Get the allocation inline progression dimension of this area.
     * This adds the content, borders and the padding to find the
     * total allocated IPD.
     *
     * @return the total IPD allocation for this area
     */
    public int getAllocIPD() {
        return getBorderAndPaddingWidthStart() + getIPD() + getBorderAndPaddingWidthEnd();
    }

    public int getEffectiveAllocIPD() {
        return getBorderAndPaddingWidthStart() + getEffectiveIPD() + getBorderAndPaddingWidthEnd();
    }

    /**
     * Get the allocation block progression dimension of this area.
     * This adds the content, borders, padding and spaces to find the
     * total allocated BPD.
     *
     * @return the total BPD allocation for this area
     */
    public int getAllocBPD() {
        return getSpaceBefore() + getBorderAndPaddingWidthBefore() + getBPD()
                + getBorderAndPaddingWidthAfter() + getSpaceAfter();
    }

    /**
     * Set the bidirectional embedding level.
     *
     * @param bidiLevel the bidirectional embedding level
     */
    public void setBidiLevel(int bidiLevel) {
        this.bidiLevel = bidiLevel;
    }

    /**
     * Reset the bidirectional embedding level to default
     * value (-1).
     */
    public void resetBidiLevel() {
        setBidiLevel(-1);
    }

    /**
     * Get the bidirectional embedding level.
     *
     * @return the bidirectional embedding level
     */
    public int getBidiLevel() {
        return bidiLevel;
    }

    /**
     * Return the sum of region border- and padding-before
     *
     * @return width in millipoints
     */
    public int getBorderAndPaddingWidthBefore() {
        int margin = 0;
        BorderProps bps = (BorderProps) getTrait(Trait.BORDER_BEFORE);
        if (bps != null) {
            margin = bps.width;
        }

        Integer padWidth = (Integer) getTrait(Trait.PADDING_BEFORE);
        if (padWidth != null) {
            margin += padWidth;
        }

        return margin;
    }

    /**
     * Return the sum of region border- and padding-after
     *
     * @return width in millipoints
     */
    public int getBorderAndPaddingWidthAfter() {
        int margin = 0;

        BorderProps bps = (BorderProps) getTrait(Trait.BORDER_AFTER);
        if (bps != null) {
            margin = bps.width;
        }

        Integer padWidth = (Integer) getTrait(Trait.PADDING_AFTER);
        if (padWidth != null) {
            margin += padWidth;
        }

        return margin;
    }

    /**
     * Return the sum of region border- and padding-start
     *
     * @return width in millipoints
     */
    public int getBorderAndPaddingWidthStart() {
        int margin = 0;
        BorderProps bps = (BorderProps) getTrait(Trait.BORDER_START);
        if (bps != null) {
            margin = bps.width;
        }

        Integer padWidth = (Integer) getTrait(Trait.PADDING_START);
        if (padWidth != null) {
            margin += padWidth;
        }

        return margin;
    }

    /**
     * Return the sum of region border- and padding-end
     *
     * @return width in millipoints
     */
    public int getBorderAndPaddingWidthEnd() {
        int margin = 0;
        BorderProps bps = (BorderProps) getTrait(Trait.BORDER_END);
        if (bps != null) {
            margin = bps.width;
        }

        Integer padWidth = (Integer) getTrait(Trait.PADDING_END);
        if (padWidth != null) {
            margin += padWidth;
        }

        return margin;
    }

    /**
     * Returns the space before
     *
     * @return width in millipoints
     */
    public int getSpaceBefore() {
        int margin = 0;
        Integer space = (Integer) getTrait(Trait.SPACE_BEFORE);
        if (space != null) {
            margin = space;
        }
        return margin;
    }

    /**
     * Returns the space after
     *
     * @return width in millipoints
     */
    public int getSpaceAfter() {
        int margin = 0;
        Integer space = (Integer) getTrait(Trait.SPACE_AFTER);
        if (space != null) {
            margin = space;
        }
        return margin;
    }

    /**
     * Returns the space start
     *
     * @return width in millipoints
     */
    public int getSpaceStart() {
        int margin = 0;
        Integer space = (Integer) getTrait(Trait.SPACE_START);
        if (space != null) {
            margin = space;
        }
        return margin;
    }

    /**
     * Returns the space end
     *
     * @return width in millipoints
     */
    public int getSpaceEnd() {
        int margin = 0;
        Integer space = (Integer) getTrait(Trait.SPACE_END);
        if (space != null) {
            margin = space;
        }
        return margin;
    }

    /**
     * Add a child to this area.
     * The default is to do nothing. Subclasses must override
     * to do something if they can have child areas.
     *
     * @param child the child area to add
     */
    public void addChildArea(Area child) {
    }

    /**
     * Add a trait to this area.
     *
     * @param traitCode the trait key
     * @param prop the value of the trait
     */
    public void addTrait(Integer traitCode, Object prop) {
        // use treemap since the typical number of traits are less than four
        if (traits == null) {
            traits = new TreeMap<Integer, Object>();
        }
        traits.put(traitCode, prop);
    }

    /**
     * Set traits on this area, copying from an existing traits map.
     *
     * @param traits the map of traits
     */
    public void setTraits(Map traits) {
        if (traits != null) {
            this.traits = new TreeMap<Integer, Object>(traits);
        } else {
            this.traits = null;
        }
    }

    /**
     * Get the map of all traits on this area.
     *
     * @return the map of traits
     */
    public Map<Integer, Object> getTraits() {
        return this.traits;
    }

    /** @return true if the area has traits */
    public boolean hasTraits() {
        return (this.traits != null);
    }

    /**
     * Get a trait from this area.
     *
     * @param traitCode the trait key
     * @return the trait value
     */
    public Object getTrait(Integer traitCode) {
        return (traits != null ? traits.get(traitCode) : null);
    }

    /**
     * Checks whether a certain trait is set on this area.
     * @param traitCode the trait key
     * @return true if the trait is set
     */
    public boolean hasTrait(Integer traitCode) {
        return (getTrait(traitCode) != null);
    }

    /**
     * Get a boolean trait from this area.
     * @param traitCode the trait key
     * @return the trait value
     */
    public boolean getTraitAsBoolean(Integer traitCode) {
        return Boolean.TRUE.equals(getTrait(traitCode));
    }

    /**
     * Get a trait from this area as an integer.
     *
     * @param traitCode the trait key
     * @return the trait value
     */
    public int getTraitAsInteger(Integer traitCode) {
        final Object obj = getTrait(traitCode);
        if (obj instanceof Integer) {
            return (Integer) obj;
        } else {
            throw new IllegalArgumentException("Trait "
                    + traitCode.getClass().getName()
                    + " could not be converted to an integer");
        }
    }

    /**
     * Sets the writing mode traits for this area. Default implementation
     * does nothing.
     * @param wmtg a WM traits getter
     */
    public void setWritingModeTraits(WritingModeTraitsGetter wmtg) {
    }

    /**
     * {@inheritDoc}
     * @return ipd and bpd of area
     */
    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer(super.toString());
        sb.append(" {ipd=").append(Integer.toString(getIPD()));
        sb.append(", bpd=").append(Integer.toString(getBPD()));
        sb.append("}");
        return sb.toString();
    }

    public int getEffectiveIPD() {
        return 0;
    }

    public void activateEffectiveIPD() {
        if (effectiveIPD != -1) {
            ipd = effectiveIPD;
        }
    }
}
