/*
 * 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.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.apache.fop.datatypes.FODimension;
import org.apache.fop.datatypes.LengthBase;
import org.apache.fop.datatypes.SimplePercentBaseContext;
import org.apache.fop.fo.pagination.Region;
import org.apache.fop.fo.pagination.RegionBody;
import org.apache.fop.fo.pagination.SimplePageMaster;
import org.apache.fop.fo.properties.CommonMarginBlock;
import org.apache.fop.layoutmgr.TraitSetter;
import org.apache.fop.traits.WritingModeTraitsGetter;

import static org.apache.fop.fo.Constants.FO_REGION_AFTER;
import static org.apache.fop.fo.Constants.FO_REGION_BEFORE;
import static org.apache.fop.fo.Constants.FO_REGION_BODY;
import static org.apache.fop.fo.Constants.FO_REGION_END;
import static org.apache.fop.fo.Constants.FO_REGION_START;
import static org.apache.fop.fo.Constants.EN_ERROR_IF_OVERFLOW;
import static org.apache.fop.fo.Constants.EN_HIDDEN;

/**
 * The page.
 * This holds the contents of the page. Each region is added.
 * The unresolved references area added so that if the page is
 * serialized then it will handle the resolving properly after
 * being reloaded.
 * This is serializable so it can be saved to cache to save
 * memory if there are forward references.
 * The page is cloneable so the page master can make copies of
 * the top level page and regions.
 */
public class Page extends AreaTreeObject implements Serializable, Cloneable {

    private static final long serialVersionUID = 6272157047421543866L;

    // contains before, start, body, end and after regions
    private RegionViewport regionBefore = null;
    private RegionViewport regionStart = null;
    private RegionViewport regionBody = null;
    private RegionViewport regionEnd = null;
    private RegionViewport regionAfter = null;

    // temporary map of unresolved objects used when serializing the page
    private Map<String, List<Resolvable>> unresolved = null;

    /** Set to true to make this page behave as if it were not empty. */
    private boolean fakeNonEmpty = false;

    /**
     *  Empty constructor, for cloning
     */
    public Page() {
    }

    /**
     * Constructor
     * @param spm SimplePageMaster containing the dimensions for this
     *            page-reference-area
     */
    public Page(SimplePageMaster spm) {
        // Width and Height of the page view port
        FODimension pageViewPortDims = new FODimension(spm.getPageWidth().getValue()
                            ,  spm.getPageHeight().getValue());

        // Get absolute margin properties (top, left, bottom, right)
        CommonMarginBlock mProps = spm.getCommonMarginBlock();

        /*
         * Create the page reference area rectangle (0,0 is at top left
         * of the "page media" and y increases
         * when moving towards the bottom of the page.
         * The media rectangle itself is (0,0,pageWidth,pageHeight).
         */
        /* Special rules apply to resolving margins in the page context.
         * Contrary to normal margins in this case top and bottom margin
         * are resolved relative to the height. In the property subsystem
         * all margin properties are configured to using BLOCK_WIDTH.
         * That's why we 'cheat' here and setup a context for the height but
         * use the LengthBase.BLOCK_WIDTH.
         */
        SimplePercentBaseContext pageWidthContext
            = new SimplePercentBaseContext(null, LengthBase.CONTAINING_BLOCK_WIDTH
                                            , pageViewPortDims.ipd);
        SimplePercentBaseContext pageHeightContext
            = new SimplePercentBaseContext(null, LengthBase.CONTAINING_BLOCK_WIDTH
                                            , pageViewPortDims.bpd);

        Rectangle pageRefRect
            =  new Rectangle(mProps.marginLeft.getValue(pageWidthContext)
                            , mProps.marginTop.getValue(pageHeightContext)
                            , pageViewPortDims.ipd
                                - mProps.marginLeft.getValue(pageWidthContext)
                                - mProps.marginRight.getValue(pageWidthContext)
                            , pageViewPortDims.bpd
                                - mProps.marginTop.getValue(pageHeightContext)
                                - mProps.marginBottom.getValue(pageHeightContext));

        // Set up the CTM on the page reference area based on writing-mode
        // and reference-orientation
        FODimension reldims = new FODimension(0, 0);
        CTM pageCTM = CTM.getCTMandRelDims(spm.getReferenceOrientation(),
            spm.getWritingMode(), pageRefRect, reldims);

        // Create a RegionViewport/ reference area pair for each page region
        RegionReference rr;
        for (Region r : spm.getRegions().values()) {
            RegionViewport rvp = makeRegionViewport(r, reldims, pageCTM);
            if (r.getNameId() == FO_REGION_BODY) {
                rr = new BodyRegion((RegionBody) r, rvp);
            } else {
                rr = new RegionReference(r, rvp);
            }
            // set borders and padding traits
            // (a little extensions wrt what prescribed by the specs at 6.4.14)
            TraitSetter.addBorders(rr, r.getCommonBorderPaddingBackground(),
                    false, false, false, false, null);
            TraitSetter.addPadding(rr, r.getCommonBorderPaddingBackground(),
                    false, false, false, false, null);
            setRegionReferencePosition(rr, r, rvp.getViewArea());
            rvp.setRegionReference(rr);
            setRegionViewport(r.getNameId(), rvp);
        }
    }

    /**
     * Call this method to force this page to pretend not to be empty.
     */
    public void fakeNonEmpty() {
        this.fakeNonEmpty = true;
    }

    /**
     * Creates a RegionViewport Area object for this pagination Region.
     * @param r the region the viewport is to be created for
     * @param reldims relative dimensions
     * @param pageCTM page coordinate transformation matrix
     * @return the new region viewport
     */
    private static RegionViewport makeRegionViewport(Region r, FODimension reldims, CTM pageCTM) {
        Rectangle2D relRegionRect = r.getViewportRectangle(reldims);
        Rectangle2D absRegionRect = pageCTM.transform(relRegionRect);
        // Get the region viewport rectangle in absolute coords by
        // transforming it using the page CTM
        RegionViewport rv = new RegionViewport(absRegionRect);
        rv.setBPD((int)relRegionRect.getHeight());
        rv.setIPD((int)relRegionRect.getWidth());
        TraitSetter.addBackground(rv, r.getCommonBorderPaddingBackground(), null);
        rv.setClip(r.getOverflow() == EN_HIDDEN
                || r.getOverflow() == EN_ERROR_IF_OVERFLOW);
        return rv;
    }

    /**
     * Set the region reference position within the region viewport.
     * This sets the transform that is used to place the contents of
     * the region reference.
     *
     * @param rr the region reference area
     * @param r the region-xxx formatting object
     * @param absRegVPRect The region viewport rectangle in "absolute" coordinates
     * where x=distance from left, y=distance from bottom, width=right-left
     * height=top-bottom
     */
    private static void setRegionReferencePosition(RegionReference rr, Region r,
                                  Rectangle2D absRegVPRect) {
        FODimension reldims = new FODimension(0, 0);
        rr.setCTM(CTM.getCTMandRelDims(r.getReferenceOrientation(),
                r.getWritingMode(), absRegVPRect, reldims));
        rr.setIPD(reldims.ipd
                - rr.getBorderAndPaddingWidthStart()
                - rr.getBorderAndPaddingWidthEnd());
        rr.setBPD(reldims.bpd
                - rr.getBorderAndPaddingWidthBefore()
                - rr.getBorderAndPaddingWidthAfter());
    }

    /**
     * Set the region on this page.
     *
     * @param areaclass the area class of the region to set
     * @param port the region viewport to set
     */
    public void setRegionViewport(int areaclass, RegionViewport port) {
        if (areaclass == FO_REGION_BEFORE) {
            regionBefore = port;
        } else if (areaclass == FO_REGION_START) {
            regionStart = port;
        } else if (areaclass == FO_REGION_BODY) {
            regionBody = port;
        } else if (areaclass == FO_REGION_END) {
            regionEnd = port;
        } else if (areaclass == FO_REGION_AFTER) {
            regionAfter = port;
        }
    }

    /**
     * Get the region from this page.
     *
     * @param areaClass the region area class
     * @return the region viewport or null if none
     */
    public RegionViewport getRegionViewport(int areaClass) {
        switch (areaClass) {
        case FO_REGION_BEFORE:
            return regionBefore;
        case FO_REGION_START:
            return regionStart;
        case FO_REGION_BODY:
            return regionBody;
        case FO_REGION_END:
            return regionEnd;
        case FO_REGION_AFTER:
            return regionAfter;
        default:
            throw new IllegalArgumentException("No such area class with ID = " + areaClass);
        }
    }

    /**
     * Indicates whether any FOs have been added to the body region
     *
     * @return whether any FOs have been added to the body region
     */
    public boolean isEmpty() {
        if (fakeNonEmpty) {
            return false;
        } else if (regionBody == null) {
            return true;
        } else {
            BodyRegion body = (BodyRegion)regionBody.getRegionReference();
            return body.isEmpty();
        }
    }

    /**
     * Clone this page.
     * This returns a new page with a clone of all the regions.
     *
     * @return a new clone of this page
     */
    public Object clone() {
        Page p = new Page();
        if (regionBefore != null) {
            p.regionBefore = (RegionViewport)regionBefore.clone();
        }
        if (regionStart != null) {
            p.regionStart = (RegionViewport)regionStart.clone();
        }
        if (regionBody != null) {
            p.regionBody = (RegionViewport)regionBody.clone();
        }
        if (regionEnd != null) {
            p.regionEnd = (RegionViewport)regionEnd.clone();
        }
        if (regionAfter != null) {
            p.regionAfter = (RegionViewport)regionAfter.clone();
        }

        return p;
    }

    /**
     * Set the unresolved references on this page for serializing.
     *
     * @param unres the Map of unresolved objects
     */
    public void setUnresolvedReferences(Map<String, List<Resolvable>> unres) {
        unresolved = unres;
    }

    /**
     * Get the map unresolved references from this page.
     * This should be called after deserializing to retrieve
     * the map of unresolved references that were serialized.
     *
     * @return the de-serialized HashMap of unresolved objects
     */
    public Map<String, List<Resolvable>> getUnresolvedReferences() {
        return unresolved;
    }

    /**
     * Sets the writing mode traits for the region viewports of
     * this page.
     * @param wmtg a WM traits getter
     */
    public void setWritingModeTraits(WritingModeTraitsGetter wmtg) {
        if (regionBefore != null) {
            regionBefore.setWritingModeTraits(wmtg);
        }
        if (regionStart != null) {
            regionStart.setWritingModeTraits(wmtg);
        }
        if (regionBody != null) {
            regionBody.setWritingModeTraits(wmtg);
        }
        if (regionEnd != null) {
            regionEnd.setWritingModeTraits(wmtg);
        }
        if (regionAfter != null) {
            regionAfter.setWritingModeTraits(wmtg);
        }
    }

}


