/*
 * 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.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

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

import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.flow.AbstractRetrieveMarker;
import org.apache.fop.fo.flow.Marker;
import org.apache.fop.fo.flow.Markers;
import org.apache.fop.fo.pagination.SimplePageMaster;
import org.apache.fop.traits.WritingModeTraitsGetter;

import static org.apache.fop.fo.Constants.FO_REGION_BODY;

/**
 * Page viewport that specifies the viewport area and holds the page contents.
 * This is the top level object for a page and remains valid for the life
 * of the document and the area tree.
 * This object may be used as a key to reference a page.
 * This is the level that creates the page.
 * The page (reference area) is then rendered inside the page object
 */
public class PageViewport extends AreaTreeObject implements Resolvable {

    private Page page;
    private Rectangle viewArea;
    private String simplePageMasterName;

    /**
     * Unique key to identify the page. pageNumberString and pageIndex are both no option
     * for this.
     */
    private String pageKey;

    private int pageNumber = -1;
    private String pageNumberString;
    private int pageIndex = -1; //-1 = undetermined
    private boolean blank;

    private transient PageSequence pageSequence;

    // set of IDs that appear first (or exclusively) on this page:
    private Set<String> idFirsts = new java.util.HashSet<String>();

    // this keeps a list of currently unresolved areas or extensions
    // once an idref is resolved it is removed
    // when this is empty the page can be rendered
    private Map<String, List<Resolvable>> unresolvedIDRefs
            = new java.util.HashMap<String, List<Resolvable>>();

    private Map<String, List<PageViewport>> pendingResolved;

    private Markers pageMarkers;

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

    /**
     * Create a page viewport.
     * @param spm SimplePageMaster indicating the page and region dimensions
     * @param pageNumber the page number
     * @param pageStr String representation of the page number
     * @param blank true if this is a blank page
     * @param spanAll true if the first span area spans all columns
     */
    public PageViewport(SimplePageMaster spm, int pageNumber, String pageStr,
            boolean blank, boolean spanAll) {
        this.simplePageMasterName = spm.getMasterName();
        setExtensionAttachments(spm.getExtensionAttachments());
        setForeignAttributes(spm.getForeignAttributes());
        this.blank = blank;
        int pageWidth = spm.getPageWidth().getValue();
        int pageHeight = spm.getPageHeight().getValue();
        this.pageNumber = pageNumber;
        this.pageNumberString = pageStr;
        this.viewArea = new Rectangle(0, 0, pageWidth, pageHeight);
        this.page = new Page(spm);
        createSpan(spanAll);
    }

    /**
     * Create a page viewport.
     * @param spm SimplePageMaster indicating the page and region dimensions
     * @param pageNumber the page number
     * @param pageStr String representation of the page number
     * @param blank true if this is a blank page
     */
    public PageViewport(SimplePageMaster spm, int pageNumber, String pageStr, boolean blank) {
        this(spm, pageNumber, pageStr, blank, false);
    }

    /**
     * Copy constructor.
     * @param original the original PageViewport to copy from
     * @throws FOPException when cloning of the page is not supported
     */
    public PageViewport(PageViewport original) throws FOPException {
        if (original.extensionAttachments != null) {
            setExtensionAttachments(original.extensionAttachments);
        }
        if (original.foreignAttributes != null) {
            setForeignAttributes(original.foreignAttributes);
        }
        this.pageIndex = original.pageIndex;
        this.pageNumber = original.pageNumber;
        this.pageNumberString = original.pageNumberString;
        try {
            this.page = (Page) original.page.clone();
        } catch (CloneNotSupportedException e) {
            throw new FOPException(e);
        }
        this.viewArea = new Rectangle(original.viewArea);
        this.simplePageMasterName = original.simplePageMasterName;
        this.blank = original.blank;
    }

    /**
     * Constructor used by the area tree parser.
     * @param viewArea the view area
     * @param pageNumber the page number
     * @param pageStr String representation of the page number
     * @param simplePageMasterName name of the original simple-page-master that generated this page
     * @param blank true if this is a blank page
     */
    public PageViewport(Rectangle viewArea, int pageNumber, String pageStr,
            String simplePageMasterName, boolean blank) {
        this.viewArea = viewArea;
        this.pageNumber = pageNumber;
        this.pageNumberString = pageStr;
        this.simplePageMasterName = simplePageMasterName;
        this.blank = blank;
    }

    /**
     * Sets the page sequence this page belongs to
     * @param seq the page sequence
     */
    public void setPageSequence(PageSequence seq) {
        this.pageSequence = seq;
    }

    /** @return the page sequence this page belongs to */
    public PageSequence getPageSequence() {
        return this.pageSequence;
    }

    /**
     * Get the view area rectangle of this viewport.
     * @return the rectangle for this viewport
     */
    public Rectangle getViewArea() {
        return viewArea;
    }

    /**
     * Get the page reference area with the contents.
     * @return the page reference area
     */
    public Page getPage() {
        return page;
    }

    /**
     * Sets the page object for this PageViewport.
     * @param page the page
     */
    public void setPage(Page page) {
        this.page = page;
    }

    /**
     * Get the page number of this page.
     * @return the integer value that represents this page
     */
    public int getPageNumber() {
        return pageNumber;
    }

    /**
     * Get the page number of this page.
     * @return the string that represents this page
     */
    public String getPageNumberString() {
        return pageNumberString;
    }

    /**
     * Sets the page index of the page in this rendering run.
     * (This is not the same as the page number!)
     * @param index the page index (zero-based), -1 if it is undetermined
     */
    public void setPageIndex(int index) {
        this.pageIndex = index;
    }

    /**
     * @return the overall page index of the page in this rendering run (zero-based,
     *         -1 if it is undetermined).
     */
    public int getPageIndex() {
        return this.pageIndex;
    }

    /**
     * Sets the unique key for this PageViewport that will be used to reference this page.
     * @param key the unique key.
     */
    public void setKey(String key) {
        this.pageKey = key;
    }

    /**
     * Get the key for this page viewport.
     * This is used so that a serializable key can be used to
     * lookup the page or some other reference.
     *
     * @return a unique page viewport key for this area tree
     */
    public String getKey() {
        if (this.pageKey == null) {
            throw new IllegalStateException("No page key set on the PageViewport: " + toString());
        }
        return this.pageKey;
    }

    /**
     * Add an "ID-first" to this page.
     * This is typically called by the {@link AreaTreeHandler} when associating
     * an ID with a {@link PageViewport}.
     *
     * @param id the id to be registered as first appearing on this page
     */
    public void setFirstWithID(String id) {
        if (id != null) {
            idFirsts.add(id);
        }
    }

    /**
     * Check whether a certain id first appears on this page
     *
     * @param id the id to be checked
     * @return true if this page is the first where the id appears
     */
    public boolean isFirstWithID(String id) {
        return idFirsts.contains(id);
    }

    /**
     * Replace the old view port. This copies all ID related fields from the old view port
     * to the current one.
     * @param oldViewPort old view port
     */
    public void replace(PageViewport oldViewPort) {
        this.idFirsts.addAll(oldViewPort.idFirsts);
        if (oldViewPort.unresolvedIDRefs != null) {
            this.unresolvedIDRefs.putAll(oldViewPort.unresolvedIDRefs);
        }
        if (oldViewPort.pendingResolved != null) {
            this.pendingResolved.putAll(oldViewPort.pendingResolved);
        }
    }

    /**
     * Add an idref to this page.
     * All idrefs found for child areas of this {@link PageViewport} are added
     * to unresolvedIDRefs, for subsequent resolution by {@link AreaTreeHandler}
     * calls to this object's {@code resolveIDRef()}.
     *
     * @param idref the idref
     * @param res the child element of this page that needs this
     *      idref resolved
     */
    public void addUnresolvedIDRef(String idref, Resolvable res) {
        if (unresolvedIDRefs == null) {
            unresolvedIDRefs = new HashMap<String, List<Resolvable>>();
        }
        List<Resolvable> pageViewports = unresolvedIDRefs.get(idref);
        if (pageViewports == null) {
            pageViewports = new ArrayList<Resolvable>();
            unresolvedIDRefs.put(idref, pageViewports);
        }
        pageViewports.add(res);
    }

    /**
     * Check if this page has been fully resolved.
     * @return true if the page is resolved and can be rendered
     */
    public boolean isResolved() {
        return unresolvedIDRefs == null
            || unresolvedIDRefs.size() == 0;
    }

    /**
     * Get the unresolved idrefs for this page.
     * @return String array of idref's that still have not been resolved
     */
    public String[] getIDRefs() {
        return (unresolvedIDRefs == null) ? null
            : unresolvedIDRefs.keySet().toArray(
                new String[unresolvedIDRefs.keySet().size()]);
    }

    /** {@inheritDoc} */
    public void resolveIDRef(String id, List<PageViewport> pages) {
        if (page == null) {
            if (pendingResolved == null) {
                pendingResolved = new HashMap<String, List<PageViewport>>();
            }
            pendingResolved.put(id, pages);
        } else {
            if (unresolvedIDRefs != null) {
                List<Resolvable> todo = unresolvedIDRefs.get(id);
                if (todo != null) {
                    for (Resolvable res : todo) {
                        res.resolveIDRef(id, pages);
                    }
                }
            }
        }
        if (unresolvedIDRefs != null && pages != null) {
            unresolvedIDRefs.remove(id);
            if (unresolvedIDRefs.isEmpty()) {
                unresolvedIDRefs = null;
            }
        }
    }

    /**
     * Register the markers for this page.
     *
     * @param marks the map of markers to add
     * @param starting if the area being added is starting or ending
     * @param isfirst if the area being added has is-first trait
     * @param islast if the area being added has is-last trait
     */
    public void registerMarkers(Map<String, Marker> marks, boolean starting, boolean isfirst, boolean islast) {
        if (pageMarkers == null) {
            pageMarkers = new Markers();
        }
        pageMarkers.register(marks, starting, isfirst, islast);
    }


    /**
     * Resolve a marker from this page.
     * This will retrieve a marker with the class name
     * and position.
     *
     * @param rm    the retrieve-marker instance
     * @return Object the marker found or null
     */
    public Marker resolveMarker(AbstractRetrieveMarker rm) {
        if (pageMarkers == null) {
            return null;
        }
        return pageMarkers.resolve(rm);
    }

    /** Dumps the current marker data to the logger. */
    public void dumpMarkers() {
        if (pageMarkers != null) {
            pageMarkers.dump();
        }
    }

    /**
     * Save the page contents to an object stream.
     * The map of unresolved references are set on the page so that
     * the resolvers can be properly serialized and reloaded.
     * @param out the object output stream to write the contents
     * @throws IOException in case of an I/O error while serializing the page
     */
    public void savePage(ObjectOutputStream out) throws IOException {
        // set the unresolved references so they are serialized
        page.setUnresolvedReferences(unresolvedIDRefs);
        out.writeObject(page);
        page = null;
    }

    /**
     * Load the page contents from an object stream.
     * This loads the page contents from the stream and
     * if there are any unresolved references that were resolved
     * while saved they will be resolved on the page contents.
     * @param in the object input stream to read the page from
     * @throws ClassNotFoundException if a class was not found while loading the page
     * @throws IOException if an I/O error occurred while loading the page
     */
    public void loadPage(ObjectInputStream in) throws IOException, ClassNotFoundException {
        page = (Page) in.readObject();
        unresolvedIDRefs = page.getUnresolvedReferences();
        if (unresolvedIDRefs != null && pendingResolved != null) {
            for (Map.Entry<String, List<PageViewport>> e : pendingResolved.entrySet()) {
                resolveIDRef(e.getKey(), e.getValue());
            }
            pendingResolved = null;
        }
    }

    /** {@inheritDoc} */
    public Object clone() throws CloneNotSupportedException {
        PageViewport pvp = (PageViewport) super.clone();
        pvp.page = (Page) page.clone();
        pvp.viewArea = (Rectangle) viewArea.clone();
        return pvp;
    }

    /**
     * Clear the page contents to save memory.
     * This object is kept for the life of the area tree since
     * it holds id and marker information and is used as a key.
     */
    public void clear() {
        page = null;
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer(64);
        sb.append("PageViewport: page=");
        sb.append(getPageNumberString());
        return sb.toString();
    }

    /** @return the name of the simple-page-master that created this page */
    public String getSimplePageMasterName() {
        return this.simplePageMasterName;
    }

    /** @return True if this is a blank page. */
    public boolean isBlank() {
        return this.blank;
    }

    /**
     * Convenience method to get BodyRegion of this PageViewport
     * @return BodyRegion object
     */
    public BodyRegion getBodyRegion() {
        RegionReference regionReference = getPage().getRegionViewport(FO_REGION_BODY).getRegionReference();
        assert (regionReference instanceof BodyRegion);
        return (BodyRegion) regionReference;
    }

    /**
     * Convenience method to create a new Span for this
     * this PageViewport.
     *
     * @param spanAll whether this is a single-column span
     * @return Span object created
     */
    public Span createSpan(boolean spanAll) {
        return getBodyRegion().getMainReference().createSpan(spanAll);
    }

    /**
     * Convenience method to get the span-reference-area currently
     * being processed
     *
     * @return span currently being processed.
     */
    public Span getCurrentSpan() {
        return getBodyRegion().getMainReference().getCurrentSpan();
    }

    /**
     * Convenience method to get the normal-flow-reference-area
     * currently being processed
     *
     * @return span currently being processed.
     */
    public NormalFlow getCurrentFlow() {
        return getCurrentSpan().getCurrentFlow();
    }

    /**
     * Convenience method to increment the Span to the
     * next NormalFlow to be processed, and to return that flow.
     *
     * @return the next NormalFlow in the Span.
     */
    public NormalFlow moveToNextFlow() {
        return getCurrentSpan().moveToNextFlow();
    }

    /**
     * Convenience method to return a given region-reference-area,
     * keyed by the Constants class identifier for the corresponding
     * formatting object (ie. Constants.FO_REGION_BODY, FO_REGION_START,
     * etc.)
     *
     * @param id the Constants class identifier for the region.
     * @return the corresponding region-reference-area for this page.
     */
    public RegionReference getRegionReference(int id) {
        return getPage().getRegionViewport(id).getRegionReference();
    }

    /**
     * Sets the writing mode traits for the page associated with this viewport.
     * @param wmtg a WM traits getter
     */
    public void setWritingModeTraits(WritingModeTraitsGetter wmtg) {
        if (page != null) {
            page.setWritingModeTraits(wmtg);
        }
    }

}
