/*
 * 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.awt.Dimension;
import java.awt.Rectangle;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

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

import org.apache.xmlgraphics.image.loader.ImageException;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.util.ImageUtil;

import org.apache.fop.ResourceEventProducer;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.area.AreaTreeHandler;
import org.apache.fop.area.Block;
import org.apache.fop.area.BodyRegion;
import org.apache.fop.area.CTM;
import org.apache.fop.area.LineArea;
import org.apache.fop.area.PageSequence;
import org.apache.fop.area.PageViewport;
import org.apache.fop.area.RegionViewport;
import org.apache.fop.area.inline.Image;
import org.apache.fop.area.inline.InlineViewport;
import org.apache.fop.datatypes.FODimension;
import org.apache.fop.datatypes.URISpecification;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.extensions.ExternalDocument;
import org.apache.fop.layoutmgr.inline.ImageLayout;
import org.apache.fop.traits.WritingMode;

/**
 * LayoutManager for an external-document extension element.  This class is instantiated by
 * area.AreaTreeHandler for each fo:external-document found in the
 * input document.
 */
public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutManager {

    private static Log log = LogFactory.getLog(ExternalDocumentLayoutManager.class);

    private ImageLayout imageLayout;

    /**
     * Constructor
     *
     * @param ath the area tree handler object
     * @param document fox:external-document to process
     */
    public ExternalDocumentLayoutManager(AreaTreeHandler ath, ExternalDocument document) {
        super(ath, document);
    }

    /**
     * @return the ExternalDocument being managed by this layout manager
     */
    protected ExternalDocument getExternalDocument() {
        return (ExternalDocument)pageSeq;
    }

    /** {@inheritDoc} */
    public PageSequenceLayoutManager getPSLM() {
        throw new IllegalStateException("getPSLM() is illegal for " + getClass().getName());
    }

    /** {@inheritDoc} */
    public void activateLayout() {
        initialize();

        FOUserAgent userAgent = pageSeq.getUserAgent();
        ImageManager imageManager = userAgent.getImageManager();

        String uri = URISpecification.getURL(getExternalDocument().getSrc());
        Integer firstPageIndex = ImageUtil.getPageIndexFromURI(uri);
        boolean hasPageIndex = (firstPageIndex != null);

        try {
            ImageInfo info = imageManager.getImageInfo(uri, userAgent.getImageSessionContext());

            Object moreImages = info.getCustomObjects().get(ImageInfo.HAS_MORE_IMAGES);
            boolean hasMoreImages = moreImages != null && !Boolean.FALSE.equals(moreImages);

            Dimension intrinsicSize = info.getSize().getDimensionMpt();
            ImageLayout layout = new ImageLayout(getExternalDocument(), this, intrinsicSize);

            PageSequence pageSequence = new PageSequence(null);
            transferExtensions(pageSequence);
            areaTreeHandler.getAreaTreeModel().startPageSequence(pageSequence);
            if (log.isDebugEnabled()) {
                log.debug("Starting layout");
            }

            makePageForImage(info, layout);

            if (!hasPageIndex && hasMoreImages) {
                if (log.isTraceEnabled()) {
                    log.trace("Starting multi-page processing...");
                }
                URI originalURI;
                try {
                    originalURI = new URI(URISpecification.escapeURI(uri));
                    int pageIndex = 1;
                    while (hasMoreImages) {
                        URI tempURI = new URI(originalURI.getScheme(),
                                originalURI.getSchemeSpecificPart(),
                                "page=" + Integer.toString(pageIndex + 1));
                        if (log.isTraceEnabled()) {
                            log.trace("Subimage: " + tempURI.toASCIIString());
                        }
                        ImageInfo subinfo = imageManager.getImageInfo(
                                tempURI.toASCIIString(), userAgent.getImageSessionContext());

                        moreImages = subinfo.getCustomObjects().get(ImageInfo.HAS_MORE_IMAGES);
                        hasMoreImages = moreImages != null && !Boolean.FALSE.equals(moreImages);

                        intrinsicSize = subinfo.getSize().getDimensionMpt();
                        layout = new ImageLayout(
                                getExternalDocument(), this, intrinsicSize);

                        makePageForImage(subinfo, layout);

                        pageIndex++;
                    }
                } catch (URISyntaxException e) {
                    getResourceEventProducer().uriError(this, uri, e,
                            getExternalDocument().getLocator());
                }
            }
        } catch (FileNotFoundException fnfe) {
            getResourceEventProducer().imageNotFound(this, uri, fnfe,
                    getExternalDocument().getLocator());
        } catch (IOException ioe) {
            getResourceEventProducer().imageIOError(this, uri, ioe,
                    getExternalDocument().getLocator());
        } catch (ImageException ie) {
            getResourceEventProducer().imageError(this, uri, ie,
                    getExternalDocument().getLocator());
        }
    }

    private ResourceEventProducer getResourceEventProducer() {
        return ResourceEventProducer.Provider.get(
                getExternalDocument().getUserAgent().getEventBroadcaster());
    }

    private void makePageForImage(ImageInfo info, ImageLayout layout) {
        this.imageLayout = layout;
        curPage = makeNewPage(false);
        fillPage(info.getOriginalURI());
        finishPage();
    }

    private void fillPage(String uri) {

        Dimension imageSize = this.imageLayout.getViewportSize();

        Block blockArea = new Block();
        blockArea.setChangeBarList(getChangeBarList());
        blockArea.setIPD(imageSize.width);
        LineArea lineArea = new LineArea();

        Image imageArea = new Image(uri);
        TraitSetter.setProducerID(imageArea, fobj.getId());
        transferForeignAttributes(imageArea);

        InlineViewport vp = new InlineViewport(imageArea, fobj.getBidiLevel());
        TraitSetter.setProducerID(vp, fobj.getId());
        vp.setIPD(imageSize.width);
        vp.setBPD(imageSize.height);
        vp.setContentPosition(imageLayout.getPlacement());
        vp.setBlockProgressionOffset(0);

        //Link them all together...
        lineArea.addInlineArea(vp);
        lineArea.updateExtentsFromChildren();
        blockArea.addLineArea(lineArea);
        curPage.getPageViewport().getCurrentFlow().addBlock(blockArea);
        curPage.getPageViewport().getCurrentSpan().notifyFlowsFinished();
    }

    /** {@inheritDoc} */
    public void finishPageSequence() {
        if (pageSeq.hasId()) {
            idTracker.signalIDProcessed(pageSeq.getId());
        }

        pageSeq.getRoot().notifyPageSequenceFinished(currentPageNum,
                (currentPageNum - startPageNum) + 1);
        areaTreeHandler.notifyPageSequenceFinished(pageSeq,
                (currentPageNum - startPageNum) + 1);

        if (log.isDebugEnabled()) {
            log.debug("Ending layout");
        }
    }

    /** {@inheritDoc} */
    protected Page createPage(int pageNumber, boolean isBlank) {
        String pageNumberString = pageSeq.makeFormattedPageNumber(pageNumber);

        Dimension imageSize = this.imageLayout.getViewportSize();

        // Set up the CTM on the page reference area based on writing-mode
        // and reference-orientation
        Rectangle referenceRect;
        if (pageSeq.getReferenceOrientation() % 180 == 0) {
            referenceRect = new Rectangle(0, 0, imageSize.width, imageSize.height);
        } else {
            referenceRect = new Rectangle(0, 0, imageSize.height, imageSize.width);
        }
        FODimension reldims = new FODimension(0, 0);
        // [TBD] BIDI ALERT
        CTM pageCTM = CTM.getCTMandRelDims(pageSeq.getReferenceOrientation(),
                                           WritingMode.LR_TB, referenceRect, reldims);

        Page page = new Page(referenceRect, pageNumber, pageNumberString, isBlank);

        PageViewport pv = page.getPageViewport();
        org.apache.fop.area.Page pageArea = new org.apache.fop.area.Page();
        pv.setPage(pageArea);

        RegionViewport rv = new RegionViewport(referenceRect);

        if (pageSeq.getReferenceOrientation() % 180 == 0) {
            rv.setIPD(referenceRect.width);
            rv.setBPD(referenceRect.height);
        }  else {
            rv.setIPD(referenceRect.height);
            rv.setBPD(referenceRect.width);
        }
        rv.setClip(true);

        BodyRegion body = new BodyRegion(Constants.FO_REGION_BODY,
                "fop-image-region", rv, 1, 0);
        body.setIPD(imageSize.width);
        body.setBPD(imageSize.height);
        body.setCTM(pageCTM);
        rv.setRegionReference(body);
        pageArea.setRegionViewport(
                Constants.FO_REGION_BODY, rv);
        //Set unique key obtained from the AreaTreeHandler
        pv.setKey(areaTreeHandler.generatePageViewportKey());

        //Also creates first normal flow region
        pv.createSpan(false);

        return page;
    }

}
