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

import java.awt.Color;
import java.awt.Point;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Map;

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

import org.apache.fop.afp.fonts.AFPFont;
import org.apache.fop.afp.fonts.AFPFontAttributes;
import org.apache.fop.afp.fonts.CharacterSet;
import org.apache.fop.afp.modca.AbstractPageObject;
import org.apache.fop.afp.modca.Document;
import org.apache.fop.afp.modca.InterchangeSet;
import org.apache.fop.afp.modca.Overlay;
import org.apache.fop.afp.modca.PageGroup;
import org.apache.fop.afp.modca.PageObject;
import org.apache.fop.afp.modca.ResourceGroup;
import org.apache.fop.afp.modca.TagLogicalElement;
import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet;
import org.apache.fop.afp.ptoca.PtocaBuilder;
import org.apache.fop.afp.ptoca.PtocaProducer;
import org.apache.fop.fonts.Font;
import org.apache.fop.util.CharUtilities;

/**
 * A data stream is a continuous ordered stream of data elements and objects
 * conforming to a given format. Application programs can generate data streams
 * destined for a presentation service, archive library, presentation device or
 * another application program. The strategic presentation data stream
 * architectures used is Mixed Object Document Content Architecture (MO:DCA).
 *
 * The MO:DCA architecture defines the data stream used by applications to
 * describe documents and object envelopes for interchange with other
 * applications and application services. Documents defined in the MO:DCA format
 * may be archived in a database, then later retrieved, viewed, annotated and
 * printed in local or distributed systems environments. Presentation fidelity
 * is accommodated by including resource objects in the documents that reference
 * them.
 */
public class DataStream {

    /** Static logging instance */
    protected static final Log LOG = LogFactory.getLog("org.apache.xmlgraphics.afp");

    /** Boolean completion indicator */
    private boolean complete;

    /** The AFP document object */
    private Document document;

    /** The current page group object */
    private PageGroup currentPageGroup;

    /** The current page object */
    private PageObject currentPageObject;

    /** The current overlay object */
    private Overlay currentOverlay;

    /** The current page */
    private AbstractPageObject currentPage;

    /** The MO:DCA interchange set in use (default to MO:DCA-P IS/2 set) */
    private InterchangeSet interchangeSet
    = InterchangeSet.valueOf(InterchangeSet.MODCA_PRESENTATION_INTERCHANGE_SET_2);

    private final Factory factory;

    private OutputStream outputStream;

    /** the afp painting state */
    private final AFPPaintingState paintingState;

    /**
     * Default constructor for the AFPDocumentStream.
     *
     * @param factory the resource factory
     * @param paintingState the AFP painting state
     * @param outputStream the outputstream to write to
     */
    public DataStream(Factory factory, AFPPaintingState paintingState, OutputStream outputStream) {
        this.paintingState = paintingState;
        this.factory = factory;
        this.outputStream = outputStream;
    }

    /**
     * Returns the outputstream
     *
     * @return the outputstream
     */
    public OutputStream getOutputStream() {
        return this.outputStream;
    }

    /**
     * Returns the document object
     *
     * @return the document object
     */
    private Document getDocument() {
        return this.document;
    }

    /**
     * Returns the current page
     *
     * @return the current page
     */
    public AbstractPageObject getCurrentPage() {
        return this.currentPage;
    }

    /**
     * The document is started by invoking this method which creates an instance
     * of the AFP Document object.
     *
     * @param name
     *            the name of this document.
     */
    public void setDocumentName(String name) {
        if (name != null) {
            getDocument().setFullyQualifiedName(
                    FullyQualifiedNameTriplet.TYPE_BEGIN_DOCUMENT_REF,
                    FullyQualifiedNameTriplet.FORMAT_CHARSTR, name);
        }
    }

    /**
     * Helper method to mark the end of the current document.
     *
     * @throws IOException thrown if an I/O exception of some sort has occurred
     */
    public void endDocument() throws IOException {
        if (complete) {
            String msg = "Invalid state - document already ended.";
            LOG.warn("endDocument():: " + msg);
            throw new IllegalStateException(msg);
        }

        if (currentPageObject != null) {
            // End the current page if necessary
            endPage();
        }

        if (currentPageGroup != null) {
            // End the current page group if necessary
            endPageGroup();
        }

        // Write out document
        if (document != null) {
            document.endDocument();
            document.writeToStream(this.outputStream);
        }

        this.outputStream.flush();

        this.complete = true;

        this.document = null;

        this.outputStream = null;
    }

    /**
     * Start a new page. When processing has finished on the current page, the
     * {@link #endPage()}method must be invoked to mark the page ending.
     *
     * @param pageWidth
     *            the width of the page
     * @param pageHeight
     *            the height of the page
     * @param pageRotation
     *            the rotation of the page
     * @param pageWidthRes
     *            the width resolution of the page
     * @param pageHeightRes
     *            the height resolution of the page
     */
    public void startPage(int pageWidth, int pageHeight, int pageRotation,
            int pageWidthRes, int pageHeightRes) {
        currentPageObject = factory.createPage(pageWidth, pageHeight,
                pageRotation, pageWidthRes, pageHeightRes);
        currentPage = currentPageObject;
        currentOverlay = null;
    }

    /**
     * Start a new overlay. When processing has finished on the current overlay,
     * the {@link #endOverlay()}method must be invoked to mark the overlay
     * ending.
     *
     * @param x
     *            the x position of the overlay on the page
     * @param y
     *            the y position of the overlay on the page
     * @param width
     *            the width of the overlay
     * @param height
     *            the height of the overlay
     * @param widthRes
     *            the width resolution of the overlay
     * @param heightRes
     *            the height resolution of the overlay
     * @param overlayRotation
     *            the rotation of the overlay
     */
    public void startOverlay(int x, int y, int width, int height, int widthRes,
            int heightRes, int overlayRotation) {
        this.currentOverlay = factory.createOverlay(
                width, height, widthRes, heightRes, overlayRotation);

        String overlayName = currentOverlay.getName();
        currentPageObject.createIncludePageOverlay(overlayName, x, y, 0);
        currentPage = currentOverlay;
    }

    /**
     * Helper method to mark the end of the current overlay.
     *
     * @throws IOException thrown if an I/O exception of some sort has occurred
     */
    public void endOverlay() throws IOException {
        if (currentOverlay != null) {
            currentOverlay.endPage();
            currentOverlay = null;
            currentPage = currentPageObject;
        }
    }

    /**
     * Helper method to save the current page.
     *
     * @return current page object that was saved
     */
    public PageObject savePage() {
        PageObject pageObject = currentPageObject;
        if (currentPageGroup != null) {
            currentPageGroup.addPage(currentPageObject);
        } else {
            document.addPage(currentPageObject);
        }
        currentPageObject = null;
        currentPage = null;
        return pageObject;
    }

    /**
     * Helper method to restore the current page.
     *
     * @param pageObject
     *            page object
     */
    public void restorePage(PageObject pageObject) {
        currentPageObject = pageObject;
        currentPage = pageObject;
    }

    /**
     * Helper method to mark the end of the current page.
     *
     * @throws IOException thrown if an I/O exception of some sort has occurred
     */
    public void endPage() throws IOException {
        if (currentPageObject != null) {
            currentPageObject.endPage();
            if (currentPageGroup != null) {
                currentPageGroup.addPage(currentPageObject);
                currentPageGroup.writeToStream(this.outputStream);
            } else {
                document.addPage(currentPageObject);
                document.writeToStream(this.outputStream);
            }
            currentPageObject = null;
            currentPage = null;
        }
    }

    /**
     * Creates the given page fonts in the current page
     *
     * @param pageFonts
     *            a collection of AFP font attributes
     */
    public void addFontsToCurrentPage(Map pageFonts) {
        for (Object o : pageFonts.values()) {
            AFPFontAttributes afpFontAttributes = (AFPFontAttributes) o;
            createFont(afpFontAttributes.getFontReference(), afpFontAttributes
                    .getFont(), afpFontAttributes.getPointSize());
        }
    }

    /**
     * Helper method to create a map coded font object on the current page, this
     * method delegates the construction of the map coded font object to the
     * active environment group on the current page.
     *
     * @param fontReference
     *            the font number used as the resource identifier
     * @param font
     *            the font
     * @param size
     *            the point size of the font
     */
    public void createFont(int fontReference, AFPFont font, int size) {
        currentPage.createFont(fontReference, font, size);
    }

    /**
     * Returns a point on the current page
     *
     * @param x the X-coordinate
     * @param y the Y-coordinate
     * @return a point on the current page
     */
    private Point getPoint(int x, int y) {
        return paintingState.getPoint(x, y);
    }

    /**
     * Helper method to create text on the current page, this method delegates
     * to the current presentation text object in order to construct the text.
     *
     * @param textDataInfo the afp text data
     * @param letterSpacing letter spacing to draw text with
     * @param wordSpacing word Spacing to draw text with
     * @param font is the font to draw text with
     * @param charSet is the AFP Character Set to use with the text
     * @throws UnsupportedEncodingException thrown if character encoding is not supported
     */
    public void createText(final AFPTextDataInfo textDataInfo, final int letterSpacing,
            final int wordSpacing, final Font font, final CharacterSet charSet)
            throws UnsupportedEncodingException {
        int rotation = paintingState.getRotation();
        if (rotation != 0) {
            textDataInfo.setRotation(rotation);
            Point p = getPoint(textDataInfo.getX(), textDataInfo.getY());
            textDataInfo.setX(p.x);
            textDataInfo.setY(p.y);
        }
        // use PtocaProducer to create PTX records
        PtocaProducer producer = new PtocaProducer() {

            public void produce(PtocaBuilder builder) throws IOException {
                builder.setTextOrientation(textDataInfo.getRotation());
                builder.absoluteMoveBaseline(textDataInfo.getY());
                builder.absoluteMoveInline(textDataInfo.getX());

                builder.setExtendedTextColor(textDataInfo.getColor());
                builder.setCodedFont((byte)textDataInfo.getFontReference());

                int l = textDataInfo.getString().length();
                StringBuffer sb = new StringBuffer();

                int interCharacterAdjustment = 0;
                AFPUnitConverter unitConv = paintingState.getUnitConverter();
                if (letterSpacing != 0) {
                    interCharacterAdjustment = Math.round(unitConv.mpt2units(letterSpacing));
                }
                builder.setInterCharacterAdjustment(interCharacterAdjustment);

                int spaceWidth = font.getCharWidth(CharUtilities.SPACE);
                int spacing = spaceWidth + letterSpacing;
                int fixedSpaceCharacterIncrement = Math.round(unitConv.mpt2units(spacing));
                int varSpaceCharacterIncrement = fixedSpaceCharacterIncrement;
                if (wordSpacing != 0) {
                    varSpaceCharacterIncrement = Math.round(unitConv.mpt2units(
                            spaceWidth + wordSpacing + letterSpacing));
                }
                builder.setVariableSpaceCharacterIncrement(varSpaceCharacterIncrement);

                boolean fixedSpaceMode = false;

                for (int i = 0; i < l; i++) {
                    char orgChar = textDataInfo.getString().charAt(i);
                    float glyphAdjust = 0;
                    if (CharUtilities.isFixedWidthSpace(orgChar)) {
                        flushText(builder, sb, charSet);
                        builder.setVariableSpaceCharacterIncrement(
                                fixedSpaceCharacterIncrement);
                        fixedSpaceMode = true;
                        sb.append(CharUtilities.SPACE);
                        int charWidth = font.getCharWidth(orgChar);
                        glyphAdjust += (charWidth - spaceWidth);
                    } else {
                        if (fixedSpaceMode) {
                            flushText(builder, sb, charSet);
                            builder.setVariableSpaceCharacterIncrement(
                                    varSpaceCharacterIncrement);
                            fixedSpaceMode = false;
                        }
                        char ch;
                        if (orgChar == CharUtilities.NBSPACE) {
                            ch = ' '; //converted to normal space to allow word spacing
                        } else {
                            ch = orgChar;
                        }
                        sb.append(ch);
                    }

                    if (glyphAdjust != 0) {
                        flushText(builder, sb, charSet);
                        int increment = Math.round(unitConv.mpt2units(glyphAdjust));
                        builder.relativeMoveInline(increment);
                    }
                }
                flushText(builder, sb, charSet);
            }

            private void flushText(PtocaBuilder builder, StringBuffer sb,
                    final CharacterSet charSet) throws IOException {
                if (sb.length() > 0) {
                    builder.addTransparentData(charSet.encodeChars(sb));
                    sb.setLength(0);
                }
            }

        };

        currentPage.createText(producer);
    }

    /**
     * Method to create a line on the current page.
     *
     * @param lineDataInfo the line data information.
     */
    public void createLine(AFPLineDataInfo lineDataInfo) {
        currentPage.createLine(lineDataInfo);
    }

    /**
     * This method will create shading on the page using the specified
     * coordinates (the shading contrast is controlled via the red, green, blue
     * parameters, by converting this to grey scale).
     *
     * @param x
     *            the x coordinate of the shading
     * @param y
     *            the y coordinate of the shading
     * @param w
     *            the width of the shaded area
     * @param h
     *            the height of the shaded area
     * @param col
     *            the shading color
     */
    public void createShading(int x, int y, int w, int h, Color col) {
        currentPageObject.createShading(x, y, w, h, col.getRed(), col.getGreen(), col.getBlue());
    }

    /**
     * Helper method which allows creation of the MPO object, via the AEG. And
     * the IPO via the Page. (See actual object for descriptions.)
     *
     * @param name
     *            the name of the static overlay
     * @param x x-coordinate
     * @param y y-coordinate
     */
    public void createIncludePageOverlay(String name, int x, int y) {
        currentPageObject.createIncludePageOverlay(name, x, y, paintingState.getRotation());
        currentPageObject.getActiveEnvironmentGroup().createOverlay(name);
    }

    /**
     * Helper method which allows creation of the IMM object.
     *
     * @param name
     *            the name of the medium map
     */
    public void createInvokeMediumMap(String name) {
        currentPageGroup.createInvokeMediumMap(name);
    }

    /**
     * Creates an IncludePageSegment on the current page.
     *
     * @param name
     *            the name of the include page segment
     * @param x
     *            the x coordinate for the overlay
     * @param y
     *            the y coordinate for the overlay
     * @param width
     *            the width of the image
     * @param height
     *            the height of the image
     */
    public void createIncludePageSegment(String name, int x, int y, int width, int height) {
        int xOrigin;
        int yOrigin;
        int orientation = paintingState.getRotation();
        switch (orientation) {
        case 90:
            xOrigin = x - height;
            yOrigin = y;
            break;
        case 180:
            xOrigin = x - width;
            yOrigin = y - height;
            break;
        case 270:
            xOrigin = x;
            yOrigin = y - width;
            break;
        default:
            xOrigin = x;
            yOrigin = y;
            break;
        }
        boolean createHardPageSegments = true;
        currentPage.createIncludePageSegment(name, xOrigin, yOrigin, createHardPageSegments);
    }



    /**
     * Creates a TagLogicalElement on the current page.
     *
     * @param attributes
     *            the array of key value pairs.
     */

    public void createPageTagLogicalElement(TagLogicalElement.State[] attributes) {
        for (TagLogicalElement.State attribute : attributes) {

            currentPage.createTagLogicalElement(attribute);
        }
    }

    /**
     * Creates a TagLogicalElement on the current page group.
     *
     * @param attributes
     *            the array of key value pairs.
     */
    public void createPageGroupTagLogicalElement(TagLogicalElement.State[] attributes) {
        for (TagLogicalElement.State attribute : attributes) {
            currentPageGroup.createTagLogicalElement(attribute);
        }
    }

    /**
     * Creates a TagLogicalElement on the current page or page group
     *
     * @param name
     *            The tag name
     * @param value
     *            The tag value
     * @param encoding The CCSID character set encoding
     */
    public void createTagLogicalElement(String name, String value, int encoding) {

        TagLogicalElement.State tleState = new  TagLogicalElement.State(name, value, encoding);
        if (currentPage != null) {

            currentPage.createTagLogicalElement(tleState);

        } else {
            currentPageGroup.createTagLogicalElement(tleState);
        }
    }

    /**
     * Creates a NoOperation item
     *
     * @param content
     *            byte data
     */
    public void createNoOperation(String content) {
        if (currentPage != null) {
            currentPage.createNoOperation(content);
        } else if (currentPageGroup != null) {
            currentPageGroup.createNoOperation(content);
        } else {
            document.createNoOperation(content);
        }
    }

    /**
     * Returns the current page group
     *
     * @return the current page group
     */
    public PageGroup getCurrentPageGroup() {
        return this.currentPageGroup;
    }

    /**
     * Start a new document.
     *
     * @throws IOException thrown if an I/O exception of some sort has occurred
     */
    public void startDocument() throws IOException {
        this.document = factory.createDocument();
        document.writeToStream(this.outputStream);
    }

    /**
     * Start a new page group. When processing has finished on the current page
     * group the {@link #endPageGroup()}method must be invoked to mark the page
     * group ending.
     *
     * @throws IOException thrown if an I/O exception of some sort has occurred
     */
    public void startPageGroup() throws IOException {
        endPageGroup();
        this.currentPageGroup = factory.createPageGroup();
    }

    /**
     * Helper method to mark the end of the page group.
     *
     * @throws IOException thrown if an I/O exception of some sort has occurred
     */
    public void endPageGroup() throws IOException {
        if (currentPageGroup != null) {
            currentPageGroup.endPageGroup();
            document.addPageGroup(currentPageGroup);
            currentPageGroup = null;
        }
        document.writeToStream(outputStream); //Flush objects
    }

    /**
     * Sets the MO:DCA interchange set to use
     *
     * @param interchangeSet the MO:DCA interchange set
     */
    public void setInterchangeSet(InterchangeSet interchangeSet) {
        this.interchangeSet = interchangeSet;
    }

    /**
     * Returns the MO:DCA interchange set in use
     *
     * @return the MO:DCA interchange set in use
     */
    public InterchangeSet getInterchangeSet() {
        return this.interchangeSet;
    }

    /**
     * Returns the resource group for a given resource info
     *
     * @param level a resource level
     * @return a resource group for the given resource info
     */
    public ResourceGroup getResourceGroup(AFPResourceLevel level) {
        ResourceGroup resourceGroup = null;
        if (level.isDocument()) {
            resourceGroup = document.getResourceGroup();
        } else if (level.isPageGroup()) {
            resourceGroup = currentPageGroup.getResourceGroup();
        } else if (level.isPage()) {
            resourceGroup = currentPageObject.getResourceGroup();
        }
        return resourceGroup;
    }

}
