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

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Paint;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;

import org.w3c.dom.Document;

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.ImageSessionContext;

import org.apache.fop.ResourceEventProducer;
import org.apache.fop.fonts.CustomFont;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.LazyFont;
import org.apache.fop.fonts.MultiByteFont;
import org.apache.fop.fonts.SingleByteFont;
import org.apache.fop.fonts.Typeface;
import org.apache.fop.pdf.PDFArray;
import org.apache.fop.pdf.PDFDictionary;
import org.apache.fop.pdf.PDFName;
import org.apache.fop.pdf.PDFNumber;
import org.apache.fop.pdf.PDFStructElem;
import org.apache.fop.pdf.PDFTextUtil;
import org.apache.fop.pdf.PDFXObject;
import org.apache.fop.render.RenderingContext;
import org.apache.fop.render.intermediate.AbstractIFPainter;
import org.apache.fop.render.intermediate.BorderPainter;
import org.apache.fop.render.intermediate.GraphicsPainter;
import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFState;
import org.apache.fop.render.intermediate.IFUtil;
import org.apache.fop.render.pdf.PDFLogicalStructureHandler.MarkedContentInfo;
import org.apache.fop.traits.BorderProps;
import org.apache.fop.traits.Direction;
import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.CharUtilities;

/**
 * IFPainter implementation that produces PDF.
 */
public class PDFPainter extends AbstractIFPainter<PDFDocumentHandler> {

    /** The current content generator */
    protected PDFContentGenerator generator;

    private final GraphicsPainter graphicsPainter;

    private final BorderPainter borderPainter;

    private boolean accessEnabled;

    private MarkedContentInfo imageMCI;

    private PDFLogicalStructureHandler logicalStructureHandler;

    private final LanguageAvailabilityChecker languageAvailabilityChecker;

    private static class LanguageAvailabilityChecker {

        private final IFContext context;

        private final Set<String> reportedLocations = new HashSet<String>();

        LanguageAvailabilityChecker(IFContext context) {
            this.context = context;
        }

        private void checkLanguageAvailability(String text) {
            Locale locale = context.getLanguage();
            if (locale == null && containsLettersOrDigits(text)) {
                String location = context.getLocation();
                if (!reportedLocations.contains(location)) {
                    PDFEventProducer.Provider.get(context.getUserAgent().getEventBroadcaster())
                            .unknownLanguage(this, location);
                    reportedLocations.add(location);
                }
            }
        }

        private boolean containsLettersOrDigits(String text) {
            for (int i = 0; i < text.length(); i++) {
                if (Character.isLetterOrDigit(text.charAt(i))) {
                    return true;
                }
            }
            return false;
        }

    }

    /**
     * Default constructor.
     * @param documentHandler the parent document handler
     * @param logicalStructureHandler the logical structure handler
     */
    public PDFPainter(PDFDocumentHandler documentHandler,
            PDFLogicalStructureHandler logicalStructureHandler) {
        super(documentHandler);
        this.logicalStructureHandler = logicalStructureHandler;
        this.generator = documentHandler.getGenerator();
        this.graphicsPainter = new PDFGraphicsPainter(this.generator);
        this.borderPainter = new BorderPainter(this.graphicsPainter);
        this.state = IFState.create();
        accessEnabled = this.getUserAgent().isAccessibilityEnabled();
        languageAvailabilityChecker = accessEnabled
                ? new LanguageAvailabilityChecker(documentHandler.getContext())
                : null;
    }

    /** {@inheritDoc} */
    public void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect)
            throws IFException {
        generator.saveGraphicsState();
        generator.concatenate(toPoints(transform));
        if (clipRect != null) {
            clipRect(clipRect);
        }
    }

    /** {@inheritDoc} */
    public void endViewport() throws IFException {
        generator.restoreGraphicsState();
    }

    /** {@inheritDoc} */
    public void startGroup(AffineTransform transform, String layer) throws IFException {
        generator.saveGraphicsState(layer);
        generator.concatenate(toPoints(transform));
    }

    /** {@inheritDoc} */
    public void endGroup() throws IFException {
        generator.restoreGraphicsState();
    }

    /** {@inheritDoc} */
    public void drawImage(String uri, Rectangle rect)
            throws IFException {
        PDFXObject xobject = getDocumentHandler().getPDFDocument().getXObject(uri);
        addStructTreeBBox(rect);
        if (xobject != null) {
            if (accessEnabled) {
                PDFStructElem structElem = (PDFStructElem) getContext().getStructureTreeElement();
                prepareImageMCID(structElem);
                placeImageAccess(rect, xobject);
            } else {
                placeImage(rect, xobject);
            }
        } else {
            drawImageUsingURI(uri, rect);
            if (!getDocumentHandler().getPDFDocument().isLinearizationEnabled()) {
                flushPDFDoc();
            }
        }
    }

    private void addStructTreeBBox(Rectangle rect) {
        if (accessEnabled && getDocumentHandler().getPDFDocument().getProfile().getPDFUAMode().isEnabled()) {
            PDFStructElem structElem = (PDFStructElem) getContext().getStructureTreeElement();
            if (structElem != null) { //structElem is null if the image is marked as an artifact
                PDFDictionary d = new PDFDictionary();
                int x = rect.x / 1000;
                int y = rect.y / 1000;
                int w = rect.width / 1000;
                int h = rect.height / 1000;
                d.put("BBox", new PDFArray(x, y, w, h));
                d.put("O", new PDFName("Layout"));
                structElem.put("A", d);
            }
        }
    }

    @Override
    protected void drawImageUsingURI(String uri, Rectangle rect) {
        ImageManager manager = getUserAgent().getImageManager();
        ImageInfo info = null;
        try {
            ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
            info = manager.getImageInfo(uri, sessionContext);
            if (accessEnabled) {
                PDFStructElem structElem = (PDFStructElem) getContext().getStructureTreeElement();
                String mimeType = info.getMimeType();
                if (!mimeType.equalsIgnoreCase("application/pdf")) {
                    prepareImageMCID(structElem);
                }
            }
            drawImageUsingImageHandler(info, rect);
        } catch (ImageException ie) {
            ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
                    getUserAgent().getEventBroadcaster());
            eventProducer.imageError(this, (info != null ? info.toString() : uri), ie, null);
        } catch (FileNotFoundException fe) {
            ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
                    getUserAgent().getEventBroadcaster());
            eventProducer.imageNotFound(this, (info != null ? info.toString() : uri), fe, null);
        } catch (IOException ioe) {
            ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
                    getUserAgent().getEventBroadcaster());
            eventProducer.imageIOError(this, (info != null ? info.toString() : uri), ioe, null);
        }
    }

    private void prepareImageMCID(PDFStructElem structElem) {
        imageMCI = logicalStructureHandler.addImageContentItem(structElem);
        if (structElem != null) {
            languageAvailabilityChecker.checkLanguageAvailability((String) structElem.get("Alt"));
        }
    }

    /** {@inheritDoc} */
    @Override
    protected RenderingContext createRenderingContext() {
        PDFRenderingContext pdfContext = new PDFRenderingContext(
                getUserAgent(), generator, getDocumentHandler().getCurrentPage(), getFontInfo());
        pdfContext.setMarkedContentInfo(imageMCI);
        pdfContext.setPageNumbers(getDocumentHandler().getPageNumbers());
        pdfContext.setPdfLogicalStructureHandler(logicalStructureHandler);
        pdfContext.setCurrentSessionStructElem((PDFStructElem) getContext().getStructureTreeElement());
        return pdfContext;
    }

    /**
     * Places a previously registered image at a certain place on the page.
     * @param rect the rectangle for the image
     * @param xobj the image XObject
     */
    private void placeImage(Rectangle rect, PDFXObject xobj) {
        generator.saveGraphicsState();
        generator.add(format(rect.width) + " 0 0 "
                          + format(-rect.height) + " "
                          + format(rect.x) + " "
                          + format(rect.y + rect.height)
                          + " cm " + xobj.getName() + " Do\n");
        generator.restoreGraphicsState();
    }
    /**
     * Places a previously registered image at a certain place on the page - Accessibility version
     * @param rect the rectangle for the image
     * @param xobj the image XObject
     */
    private void placeImageAccess(Rectangle rect, PDFXObject xobj) {
        generator.saveGraphicsState(imageMCI.tag, imageMCI.mcid);
        generator.add(format(rect.width) + " 0 0 "
                          + format(-rect.height) + " "
                          + format(rect.x) + " "
                          + format(rect.y + rect.height)
                          + " cm " + xobj.getName() + " Do\n");
        generator.restoreGraphicsStateAccess();
    }

    /** {@inheritDoc} */
    public void drawImage(Document doc, Rectangle rect) throws IFException {
        if (accessEnabled) {
            PDFStructElem structElem = (PDFStructElem) getContext().getStructureTreeElement();
            prepareImageMCID(structElem);
            addStructTreeBBox(rect);
        }
        drawImageUsingDocument(doc, rect);
        if (!getDocumentHandler().getPDFDocument().isLinearizationEnabled()) {
            flushPDFDoc();
        }
    }

    private void flushPDFDoc() throws IFException {
        // output new data
        try {
            generator.flushPDFDoc();
        } catch (IOException ioe) {
            throw new IFException("I/O error flushing the PDF document", ioe);
        }
    }

    /**
     * Formats a integer value (normally coordinates in millipoints) to a String.
     * @param value the value (in millipoints)
     * @return the formatted value
     */
    protected static String format(int value) {
        return PDFNumber.doubleOut(value / 1000f);
    }

    /** {@inheritDoc} */
    public void clipRect(Rectangle rect) throws IFException {
        generator.endTextObject();
        generator.clipRect(rect);
    }

    /** {@inheritDoc} */
    public void clipBackground(Rectangle rect,
            BorderProps bpsBefore, BorderProps bpsAfter,
            BorderProps bpsStart, BorderProps bpsEnd) throws IFException {

        try {
            borderPainter.clipBackground(rect,
                    bpsBefore,  bpsAfter, bpsStart,  bpsEnd);
        } catch (IOException ioe) {
            throw new IFException("I/O error while clipping background", ioe);
        }

    }

    /** {@inheritDoc} */
    public void fillRect(Rectangle rect, Paint fill) throws IFException {
        if (fill == null) {
            return;
        }
        if (rect.width != 0 && rect.height != 0) {
            generator.endTextObject();
            if (accessEnabled && getUserAgent().isPdfUAEnabled()) {
                generator.beginMarkedContentSequence(null, 0, null);
            }
            if (fill != null) {
                if (fill instanceof Color) {
                    generator.updateColor((Color)fill, true, null);
                } else {
                    throw new UnsupportedOperationException("Non-Color paints NYI");
                }
            }
            StringBuffer sb = new StringBuffer();
            sb.append(format(rect.x)).append(' ');
            sb.append(format(rect.y)).append(' ');
            sb.append(format(rect.width)).append(' ');
            sb.append(format(rect.height)).append(" re");
            if (fill != null) {
                sb.append(" f");
            }
            /* Removed from method signature as it is currently not used
            if (stroke != null) {
                sb.append(" S");
            }*/
            sb.append('\n');
            generator.add(sb.toString());
            if (accessEnabled && getUserAgent().isPdfUAEnabled()) {
                generator.endMarkedContentSequence();
            }
        }
    }

    /** {@inheritDoc} */
    @Override
    public void drawBorderRect(Rectangle rect, BorderProps top, BorderProps bottom,
            BorderProps left, BorderProps right, Color innerBackgroundColor) throws IFException {
        if (top != null || bottom != null || left != null || right != null) {
            generator.endTextObject();
            if (accessEnabled && getUserAgent().isPdfUAEnabled()) {
                generator.beginMarkedContentSequence(null, 0, null);
            }
            this.borderPainter.drawBorders(rect, top, bottom, left, right, innerBackgroundColor);
            if (accessEnabled && getUserAgent().isPdfUAEnabled()) {
                generator.endMarkedContentSequence();
            }
        }
    }

    /** {@inheritDoc} */
    @Override
    public void drawLine(Point start, Point end, int width, Color color, RuleStyle style)
        throws IFException {
        generator.endTextObject();
        if (accessEnabled && getUserAgent().isPdfUAEnabled()) {
            generator.beginMarkedContentSequence(null, 0, null);
        }
        try {
            this.graphicsPainter.drawLine(start, end, width, color, style);
        } catch (IOException ioe) {
            throw new IFException("Cannot draw line", ioe);
        }
        if (accessEnabled && getUserAgent().isPdfUAEnabled()) {
            generator.endMarkedContentSequence();
        }
    }

    private Typeface getTypeface(String fontName) {
        if (fontName == null) {
            throw new NullPointerException("fontName must not be null");
        }
        Typeface tf = getFontInfo().getFonts().get(fontName);
        if (tf instanceof LazyFont) {
            tf = ((LazyFont)tf).getRealFont();
        }
        return tf;
    }

    /** {@inheritDoc} */
    public void drawText(int x, int y, int letterSpacing, int wordSpacing, int[][] dp,
            String text)
            throws IFException {
        if (accessEnabled) {
            PDFStructElem structElem = (PDFStructElem) getContext().getStructureTreeElement();
            languageAvailabilityChecker.checkLanguageAvailability(text);
            MarkedContentInfo mci = logicalStructureHandler.addTextContentItem(structElem);
            String actualText = getContext().isHyphenated() ? text.substring(0, text.length() - 1) : null;
            generator.endTextObject();
            generator.updateColor(state.getTextColor(), true, null);
            generator.beginTextObject(mci.tag, mci.mcid, actualText);
        } else {
            generator.updateColor(state.getTextColor(), true, null);
            generator.beginTextObject();
        }

        FontTriplet triplet = new FontTriplet(
                state.getFontFamily(), state.getFontStyle(), state.getFontWeight());
        String fontKey = getFontInfo().getInternalFontKey(triplet);
        Typeface typeface = getTypeface(fontKey);
        if (typeface instanceof MultiByteFont && ((MultiByteFont) typeface).hasSVG()) {
            drawSVGText((MultiByteFont) typeface, triplet, x, y, text, state);
        } else if ((dp == null) || IFUtil.isDPOnlyDX(dp)) {
            drawTextWithDX(x, y, text, triplet, letterSpacing,
                             wordSpacing, IFUtil.convertDPToDX(dp));
        } else {
            drawTextWithDP(x, y, text, triplet, letterSpacing,
                             wordSpacing, dp);
        }
    }

    public void drawText(int x, int y, int letterSpacing, int wordSpacing, int[][] dp, String text, boolean nextIsSpace)
            throws IFException {
        if (accessEnabled && nextIsSpace) {
            text += ' ';
        }
        drawText(x, y, letterSpacing, wordSpacing, dp, text);
    }

    private void drawTextWithDX(int x, int y, String text, FontTriplet triplet,
            int letterSpacing, int wordSpacing, int[] dx) throws IFException {
        //TODO Ignored: state.getFontVariant()
        //TODO Opportunity for font caching if font state is more heavily used
        String fontKey = getFontKey(triplet);
        int sizeMillipoints = state.getFontSize();
        float fontSize = sizeMillipoints / 1000f;

        // This assumes that *all* CIDFonts use a /ToUnicode mapping
        Typeface tf = getTypeface(fontKey);
        Font font = getFontInfo().getFontInstance(triplet, sizeMillipoints);
        String fontName = font.getFontName();

        PDFTextUtil textutil = generator.getTextUtil();
        textutil.updateTf(fontKey, fontSize, tf.isMultiByte(), tf.isCID());

        double shear = 0;
        boolean simulateStyle = tf instanceof CustomFont && ((CustomFont) tf).getSimulateStyle();
        if (simulateStyle) {
            if (triplet.getWeight() == 700) {
                generator.add("q\n");
                generator.add("2 Tr 0.31543 w\n");
            }
            if (triplet.getStyle().equals("italic")) {
                shear = 0.3333;
            }
        }

        generator.updateCharacterSpacing(letterSpacing / 1000f);

        textutil.writeTextMatrix(new AffineTransform(1, 0, shear, -1, x / 1000f, y / 1000f));
        int l = text.length();
        int dxl = (dx != null ? dx.length : 0);

        if (dx != null && dxl > 0 && dx[0] != 0) {
            textutil.adjustGlyphTJ(-dx[0] / fontSize);
        }
        for (int i = 0; i < l; i++) {
            int orgChar = text.charAt(i);
            int ch;

            // surrogate pairs have to be merged in a single code point
            if (CharUtilities.containsSurrogatePairAt(text, i)) {
                orgChar = Character.toCodePoint((char) orgChar, text.charAt(++i));
            }

            float glyphAdjust = 0;
            if (font.hasCodePoint(orgChar)) {
                ch = font.mapCodePoint(orgChar);
                ch = selectAndMapSingleByteFont(tf, fontName, fontSize, textutil, ch);
                if ((wordSpacing != 0) && CharUtilities.isAdjustableSpace(orgChar)) {
                    glyphAdjust += wordSpacing;
                }
            } else {
                if (CharUtilities.isFixedWidthSpace(orgChar)) {
                    //Fixed width space are rendered as spaces so copy/paste works in a reader
                    ch = font.mapChar(CharUtilities.SPACE);
                    int spaceDiff = font.getCharWidth(CharUtilities.SPACE) - font.getCharWidth(orgChar);
                    glyphAdjust = -spaceDiff;
                } else {
                    ch = font.mapCodePoint(orgChar);
                    if ((wordSpacing != 0) && CharUtilities.isAdjustableSpace(orgChar)) {
                        glyphAdjust += wordSpacing;
                    }
                }
                ch = selectAndMapSingleByteFont(tf, fontName, fontSize, textutil, ch);
            }
            textutil.writeTJMappedCodePoint(ch);

            if (dx != null && i < dxl - 1) {
                glyphAdjust += dx[i + 1];
            }

            if (glyphAdjust != 0) {
                textutil.adjustGlyphTJ(-glyphAdjust / fontSize);
            }

        }
        textutil.writeTJ();
        if (simulateStyle && triplet.getWeight() == 700) {
            generator.add("Q\n");
        }
    }

    private static int[] paZero = new int[4];

    private void drawTextWithDP(int x, int y, String text, FontTriplet triplet,
                                  int letterSpacing, int wordSpacing, int[][] dp) {
        assert text != null;
        assert triplet != null;
        assert dp != null;
        String          fk              = getFontInfo().getInternalFontKey(triplet);
        Typeface        tf              = getTypeface(fk);
        if (tf.isMultiByte() || tf.isCID()) {
            int         fs              = state.getFontSize();
            float       fsPoints        = fs / 1000f;
            Font        f               = getFontInfo().getFontInstance(triplet, fs);
            PDFTextUtil tu              = generator.getTextUtil();
            double      xc              = 0f;
            double      yc              = 0f;
            double      xoLast          = 0f;
            double      yoLast          = 0f;
            double      wox             = wordSpacing;

            // FOP-2810
            boolean simulateStyle = tf instanceof CustomFont && ((CustomFont) tf).getSimulateStyle();
            double shear = 0;

            if (simulateStyle) {
                if (triplet.getWeight() == 700) {
                    generator.add("q\n");
                    generator.add("2 Tr 0.31543 w\n");
                }
                if (triplet.getStyle().equals("italic")) {
                    shear = 0.3333;
                }
            }

            tu.writeTextMatrix(new AffineTransform(1, 0, shear, -1, x / 1000f, y / 1000f));
            tu.updateTf(fk, fsPoints, tf.isMultiByte(), true);
            generator.updateCharacterSpacing(letterSpacing / 1000f);
            for (int i = 0, n = text.length(); i < n; i++) {
                char    ch              = text.charAt(i);
                int[]   pa              = ((i >= dp.length) || (dp[i] == null)) ? paZero : dp[i];
                double  xo              = xc + pa[0];
                double  yo              = yc + pa[1];
                double  xa              = f.getCharWidth(ch) + maybeWordOffsetX(wox, ch, null);
                double  ya              = 0;
                double  xd              = (xo - xoLast) / 1000f;
                double  yd              = (yo - yoLast) / 1000f;
                tu.writeTd(xd, yd);
                tu.writeTj(f.mapChar(ch), tf.isMultiByte(), true);
                xc += xa + pa[2];
                yc += ya + pa[3];
                xoLast = xo;
                yoLast = yo;
            }
        }
    }

    private double maybeWordOffsetX(double wox, char ch, Direction dir) {
        if ((wox != 0)
             && CharUtilities.isAdjustableSpace(ch)
             && ((dir == null) || dir.isHorizontal())) {
            return wox;
        } else {
            return 0;
        }
    }

    /*
    private double maybeWordOffsetY ( double woy, char ch, Direction dir ) {
        if ( ( woy != 0 )
             && CharUtilities.isAdjustableSpace ( ch ) && dir.isVertical()
             && ( ( dir != null ) && dir.isVertical() ) ) {
            return woy;
        } else {
            return 0;
        }
    }
    */

    private int selectAndMapSingleByteFont(Typeface tf, String fontName, float fontSize, PDFTextUtil textutil,
                                            int ch) {
        if ((tf instanceof SingleByteFont && ((SingleByteFont)tf).hasAdditionalEncodings()) || tf.isCID()) {
            int encoding = ch / 256;
            if (encoding == 0) {
                textutil.updateTf(fontName, fontSize, tf.isMultiByte(), tf.isCID());
            } else {
                textutil.updateTf(fontName + "_" + Integer.toString(encoding),
                        fontSize, tf.isMultiByte(), tf.isCID());
                ch = (char)(ch % 256);
            }
        }
        return ch;
    }

}
