/*
 * 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.Point;
import java.io.IOException;
import java.io.ObjectInputStream;

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

import org.apache.xmlgraphics.java2d.color.ColorConverter;
import org.apache.xmlgraphics.java2d.color.DefaultColorConverter;

import org.apache.fop.afp.fonts.AFPPageFonts;
import org.apache.fop.util.AbstractPaintingState;

/**
 * This keeps information about the current painting state when writing to an
 * AFP datastream.
 */
public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState {

    private static final long serialVersionUID = 8206711712452344473L;

    private static Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");

    /** the portrait rotation */
    private int portraitRotation;

    /** the landscape rotation */
    private int landscapeRotation = 270;

    /** color image support */
    private boolean colorImages;

    /** dithering quality setting (0.0f..1.0f) */
    private float ditheringQuality;

    /** image encoding quality setting (0.0f..1.0f) */
    private float bitmapEncodingQuality;

    /** color image handler */
    private transient ColorConverter colorConverter;

    /**
     * true if certain image formats may be embedded unchanged in their native
     * format.
     */
    private boolean nativeImagesSupported;

    private boolean canEmbedJpeg;

    /**
     * true if CMYK images (requires IOCA FS45 suppport on the target platform)
     * may be generated
     */
    private boolean cmykImagesSupported;

    /** default value for image depth */
    private int bitsPerPixel = 8;

    /** the output resolution */
    private int resolution = 240; // 240 dpi

    /**
     * A configurable value to correct the line width so that the output matches the expected. Different
     * devices may need different values.
     */
    private float lineWidthCorrection = AFPConstants.LINE_WIDTH_CORRECTION;

    /** determines whether GOCA is enabled or disabled  */
    private boolean gocaEnabled = true;
    /** determines whether to stroke text in GOCA mode or to use text operators where possible */
    private boolean strokeGocaText;


    /** use page segment with F11 and F45 images*/
    private boolean pSeg;

    private boolean gocaPSeg;

    /** use FS45 images*/
    private boolean fs45;

    /** the current page */
    private transient AFPPagePaintingState pagePaintingState;

    // /** reference orientation */
    // private int orientation = 0;

    /** a unit converter */
    private final transient AFPUnitConverter unitConv;

    public AFPPaintingState() {
        colorConverter = GrayScaleColorConverter.getInstance();
        pagePaintingState = new AFPPagePaintingState();
        unitConv = new AFPUnitConverter(this);
    }

    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
        ois.defaultReadObject();
    }

    /**
     * Sets the rotation to be used for portrait pages, valid values are 0
     * (default), 90, 180, 270.
     *
     * @param rotation
     *            The rotation in degrees.
     */
    public void setPortraitRotation(int rotation) {
        if (rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270) {
            portraitRotation = rotation;
        } else {
            throw new IllegalArgumentException("The portrait rotation must be one"
                    + " of the values 0, 90, 180, 270");

        }
    }

    /**
     * Returns the rotation to be used for portrait pages
     *
     * @return the rotation to be used for portrait pages
     */
    protected int getPortraitRotation() {
        return this.portraitRotation;
    }

    /**
     * Sets the rotation to be used for landscape pages, valid values are 0, 90,
     * 180, 270 (default).
     *
     * @param rotation
     *            The rotation in degrees.
     */
    public void setLandscapeRotation(int rotation) {
        if (rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270) {
            landscapeRotation = rotation;
        } else {
            throw new IllegalArgumentException("The landscape rotation must be one"
                    + " of the values 0, 90, 180, 270");
        }
    }

    /**
     * Returns the landscape rotation
     *
     * @return the landscape rotation
     */
    protected int getLandscapeRotation() {
        return this.landscapeRotation;
    }

    /**
     * Sets the number of bits used per pixel
     *
     * @param bitsPerPixel
     *            number of bits per pixel
     */
    public void setBitsPerPixel(int bitsPerPixel) {
        switch (bitsPerPixel) {
        case 1:
        case 4:
        case 8:
            this.bitsPerPixel = bitsPerPixel;
            break;
        default:
            log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
            this.bitsPerPixel = 8;
            break;
        }
    }

    /**
     * Returns the number of bits per pixel
     *
     * @return the number of bits per pixel
     */
    public int getBitsPerPixel() {
        return this.bitsPerPixel;
    }

    /**
     * Sets whether images are color or not and instantiates a ColorHandler
     *
     * @param colorImages
     *            color image output
     */
    public void setColorImages(boolean colorImages) {
        this.colorImages = colorImages;

        if (colorImages) {
            this.colorConverter = DefaultColorConverter.getInstance();
        }

    }

    /**
     * Returns true if color images are to be used
     *
     * @return true if color images are to be used
     */
    public boolean isColorImages() {
        return this.colorImages;
    }

    /**
     * Used to convert color in respect of the colorImages flag
     *
     * @return the color converter
     */
    public ColorConverter getColorConverter() {
        return this.colorConverter;
    }

    /**
     * Sets whether images are natively supported or not in the AFP environment
     *
     * @param nativeImagesSupported
     *            true if images are natively supported in this AFP environment
     */
    public void setNativeImagesSupported(boolean nativeImagesSupported) {
        this.nativeImagesSupported = nativeImagesSupported;
    }

    /**
     * Returns true if images are supported natively in this AFP environment
     *
     * @return true if images are supported natively in this AFP environment
     */
    public boolean isNativeImagesSupported() {
        return this.nativeImagesSupported;
    }

    /**
     * Set whether or not JPEG images can be embedded within an AFP document.
     *
     * @param canEmbed true if the JPEG image can be embedded
     */
    public void setCanEmbedJpeg(boolean canEmbed) {
        canEmbedJpeg = canEmbed;
    }

    /**
     * Returns true if JPEGs can be embedded in an AFP document.
     *
     * @return true if JPEG embedding is allowed
     */
    public boolean canEmbedJpeg() {
        return canEmbedJpeg;
    }

    /**
     * Controls whether CMYK images (IOCA FS45) are enabled. By default, support
     * is disabled for wider compatibility. When disabled, any CMYK image is
     * converted to the selected color format.
     *
     * @param value
     *            true to enabled CMYK images
     */
    public void setCMYKImagesSupported(boolean value) {
        this.cmykImagesSupported = value;
    }

    /**
     * Indicates whether CMYK images (IOCA FS45) are enabled.
     *
     * @return true if IOCA FS45 is enabled
     */
    public boolean isCMYKImagesSupported() {
        return this.cmykImagesSupported;
    }

    /**
     * Gets the dithering quality setting to use when converting images to monochrome images.
     * @return the dithering quality (a value between 0.0f and 1.0f)
     */
    public float getDitheringQuality() {
        return this.ditheringQuality;
    }

    /**
     * Sets the dithering quality setting to use when converting images to monochrome images.
     * @param quality Defines the desired quality level for the conversion.
     *                  Valid values: a value between 0.0f (fastest) and 1.0f (best)
     */
    public void setDitheringQuality(float quality) {
        quality = Math.max(quality, 0.0f);
        quality = Math.min(quality, 1.0f);
        this.ditheringQuality = quality;
    }

    /**
     * Gets the image encoding quality setting to use when encoding bitmap images.
     * @return the encoding quality (a value between 0.0f and 1.0f, 1.0 meaning loss-less)
     */
    public float getBitmapEncodingQuality() {
        return this.bitmapEncodingQuality;
    }

    /**
     * Sets the image encoding quality setting to use when encoding bitmap images.
     * @param quality Defines the desired quality level for the conversion.
     *                  Valid values: a value between 0.0f (lowest) and 1.0f (best, loss-less)
     */
    public void setBitmapEncodingQuality(float quality) {
        quality = Math.max(quality, 0.0f);
        quality = Math.min(quality, 1.0f);
        this.bitmapEncodingQuality = quality;
    }

    /**
     * Sets the output/device resolution
     *
     * @param resolution
     *            the output resolution (dpi)
     */
    public void setResolution(int resolution) {
        if (log.isDebugEnabled()) {
            log.debug("renderer-resolution set to: " + resolution + "dpi");
        }
        this.resolution = resolution;
    }

    /**
     * Sets the line width correction
     *
     * @param correction the line width multiplying factor correction
     */
    public void setLineWidthCorrection(float correction) {
        if (log.isDebugEnabled()) {
            log.debug("line width correction set to: " + correction);
        }
        this.lineWidthCorrection = correction;
    }

    /**
     * Returns the output/device resolution.
     *
     * @return the resolution in dpi
     */
    public int getResolution() {
        return this.resolution;
    }

    /**
     * Returns the line width correction.
     * @return the correction
     */
    public float getLineWidthCorrection() {
        return this.lineWidthCorrection;
    }

    /**
     * Controls whether GOCA is enabled or disabled.
     * @param enabled true if GOCA is enabled, false if it is disabled
     */
    public void setGOCAEnabled(boolean enabled) {
        this.gocaEnabled = enabled;
    }

    /**
     * Indicates whether GOCA is enabled or disabled.
     * @return true if GOCA is enabled, false if GOCA is disabled
     */
    public boolean isGOCAEnabled() {
        return this.gocaEnabled;
    }

    /**
     * Controls whether to stroke text in GOCA mode or to use text operators where possible.
     * @param stroke true to stroke, false to paint with text operators where possible
     */
    public void setStrokeGOCAText(boolean stroke) {
        this.strokeGocaText = stroke;
    }

    /**
     * Indicates whether to stroke text in GOCA mode or to use text operators where possible.
     * @return true to stroke, false to paint with text operators where possible
     */
    public boolean isStrokeGOCAText() {
        return this.strokeGocaText;
    }

    /**
     * Whether FS11 and SF45 non-inline images should be wrapped in a page segment
     * @return true iff images should be wrapped
     */
    public boolean getWrapPSeg() {
        return pSeg;
    }

    /**
     * Sets whether FS11 and FS45 non-inline images should be wrapped in a page segment
     * @param pSeg true iff images should be wrapped
     */
    public void setWrapPSeg(boolean pSeg) {
        this.pSeg = pSeg;
    }

    public boolean getWrapGocaPSeg() {
        return gocaPSeg;
    }

    public void setWrapGocaPSeg(boolean pSeg) {
        this.gocaPSeg = pSeg;
    }

    /**
     * gets whether images should be FS45
     * @return true iff images should be FS45
     */
    public boolean getFS45() {
        return fs45;
    }

    /**
     * sets whether images should be FS45
     * @param fs45 true iff images should be FS45
     */
    public void setFS45(boolean fs45) {
        this.fs45 = fs45;
    }



    /** {@inheritDoc} */
    @Override
    protected AbstractData instantiateData() {
        return new AFPData();
    }

    /** {@inheritDoc} */
    @Override
    protected AbstractPaintingState instantiate() {
        return new AFPPaintingState();
    }

    /**
     * Returns the painting state of the current page
     *
     * @return the painting state of the current page
     */
    protected AFPPagePaintingState getPagePaintingState() {
        return this.pagePaintingState;
    }

    /**
     * Gets the current page fonts
     *
     * @return the current page fonts
     */
    public AFPPageFonts getPageFonts() {
        return pagePaintingState.getFonts();
    }

    /**
     * Sets the page width
     *
     * @param pageWidth
     *            the page width
     */
    public void setPageWidth(int pageWidth) {
        pagePaintingState.setWidth(pageWidth);
    }

    /**
     * Returns the page width
     *
     * @return the page width
     */
    public int getPageWidth() {
        return pagePaintingState.getWidth();
    }

    /**
     * Sets the page height
     *
     * @param pageHeight
     *            the page height
     */
    public void setPageHeight(int pageHeight) {
        pagePaintingState.setHeight(pageHeight);
    }

    /**
     * Returns the page height
     *
     * @return the page height
     */
    public int getPageHeight() {
        return pagePaintingState.getHeight();
    }

    /**
     * Returns the page rotation
     *
     * @return the page rotation
     */
    public int getPageRotation() {
        return pagePaintingState.getOrientation();
    }

    /**
     * Sets the uri of the current image
     *
     * @param uri
     *            the uri of the current image
     */
    public void setImageUri(String uri) {
        ((AFPData) getData()).imageUri = uri;
    }

    /**
     * Gets the uri of the current image
     *
     * @return the uri of the current image
     */
    public String getImageUri() {
        return ((AFPData) getData()).imageUri;
    }

    /**
     * Returns the currently derived rotation
     *
     * @return the currently derived rotation
     */
    public int getRotation() {
        return getData().getDerivedRotation();
    }

    /**
     * Returns the unit converter
     *
     * @return the unit converter
     */
    public AFPUnitConverter getUnitConverter() {
        return this.unitConv;
    }

    /**
     * Returns a point on the current page, taking the current painting state
     * into account.
     *
     * @param x
     *            the X-coordinate
     * @param y
     *            the Y-coordinate
     * @return a point on the current page
     */
    public Point getPoint(int x, int y) {
        Point p = new Point();
        int rotation = getRotation();
        switch (rotation) {
        case 90:
            p.x = y;
            p.y = getPageWidth() - x;
            break;
        case 180:
            p.x = getPageWidth() - x;
            p.y = getPageHeight() - y;
            break;
        case 270:
            p.x = getPageHeight() - y;
            p.y = x;
            break;
        default:
            p.x = x;
            p.y = y;
            break;
        }
        return p;
    }

    /** {@inheritDoc} */
    @Override
    public Object clone() {
        AFPPaintingState paintingState = (AFPPaintingState) super.clone();
        paintingState.pagePaintingState = (AFPPagePaintingState) this.pagePaintingState.clone();
        paintingState.portraitRotation = this.portraitRotation;
        paintingState.landscapeRotation = this.landscapeRotation;
        paintingState.bitsPerPixel = this.bitsPerPixel;
        paintingState.colorImages = this.colorImages;
        paintingState.colorConverter = this.colorConverter;
        paintingState.resolution = this.resolution;
        return paintingState;
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        return "AFPPaintingState{" + "portraitRotation=" + portraitRotation
                + ", landscapeRotation=" + landscapeRotation + ", colorImages=" + colorImages
                + ", bitsPerPixel=" + bitsPerPixel + ", resolution=" + resolution + ", pageState="
                + pagePaintingState + super.toString() + "}";
    }

    /**
     * Page level state data
     */
    private class AFPPagePaintingState implements Cloneable {
        /** page width */
        private int width;

        /** page height */
        private int height;

        /** page fonts */
        private AFPPageFonts fonts = new AFPPageFonts();

        /** page font count */
        private int fontCount;

        /** page orientation */
        private int orientation;

        /**
         * Returns the page width
         *
         * @return the page width
         */
        protected int getWidth() {
            return width;
        }

        /**
         * Sets the page width
         *
         * @param width
         *            the page width
         */
        protected void setWidth(int width) {
            this.width = width;
        }

        /**
         * Returns the page height
         *
         * @return the page height
         */
        protected int getHeight() {
            return height;
        }

        /**
         * Sets the page height
         *
         * @param height
         *            the page height
         */
        protected void setHeight(int height) {
            this.height = height;
        }

        /**
         * Returns the page fonts
         *
         * @return the page fonts
         */
        protected AFPPageFonts getFonts() {
            return fonts;
        }

        /**
         * Sets the current page fonts
         *
         * @param fonts
         *            the current page fonts
         */
        protected void setFonts(AFPPageFonts fonts) {
            this.fonts = fonts;
        }

        /**
         * Increments and returns the current page font count
         *
         * @return increment and return the current page font count
         */
        protected int incrementFontCount() {
            return ++fontCount;
        }

        /**
         * Returns the current page orientation
         *
         * @return the current page orientation
         */
        protected int getOrientation() {
            return orientation;
        }

        /**
         * Sets the current page orientation
         *
         * @param orientation
         *            the current page orientation
         */
        protected void setOrientation(int orientation) {
            this.orientation = orientation;
        }

        /** {@inheritDoc} */
        @Override
        public Object clone() {
            AFPPagePaintingState state = new AFPPagePaintingState();
            state.width = this.width;
            state.height = this.height;
            state.orientation = this.orientation;
            state.fonts = new AFPPageFonts(this.fonts);
            state.fontCount = this.fontCount;
            return state;
        }

        /** {@inheritDoc} */
        @Override
        public String toString() {
            return "AFPPagePaintingState{width=" + width + ", height=" + height + ", orientation="
                    + orientation + ", fonts=" + fonts + ", fontCount=" + fontCount + "}";
        }
    }

    /**
     * Block level state data
     */
    // @SuppressFBWarnings("SE_INNER_CLASS")
    private class AFPData extends org.apache.fop.util.AbstractPaintingState.AbstractData {
        private static final long serialVersionUID = -1789481244175275686L;

        /** The current fill status */
        private boolean filled;

        private String imageUri;

        /** {@inheritDoc} */
        @Override
        public Object clone() {
            AFPData obj = (AFPData) super.clone();
            obj.filled = this.filled;
            obj.imageUri = this.imageUri;
            return obj;
        }

        /** {@inheritDoc} */
        @Override
        public String toString() {
            return "AFPData{" + super.toString() + ", filled=" + filled + ", imageUri=" + imageUri
                    + "}";
        }

        /** {@inheritDoc} */
        @Override
        protected AbstractData instantiate() {
            return new AFPData();
        }
    }

}
