/* ====================================================================
   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.
==================================================================== */

package org.apache.poi.sl.draw;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.MultipleGradientPaint.ColorSpaceType;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.Paint;
import java.awt.RadialGradientPaint;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;

import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
import org.apache.poi.sl.usermodel.PlaceableShape;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;


/**
 * This class handles color transformations.
 * 
 * @see <a href="https://tips4java.wordpress.com/2009/07/05/hsl-color/">HSL code taken from Java Tips Weblog</a>
 */
public class DrawPaint {
    // HSL code is public domain - see https://tips4java.wordpress.com/contact-us/
    
    private static final POILogger LOG = POILogFactory.getLogger(DrawPaint.class);

    private static final Color TRANSPARENT = new Color(1f,1f,1f,0f);
    
    protected PlaceableShape<?,?> shape;
    
    public DrawPaint(PlaceableShape<?,?> shape) {
        this.shape = shape;
    }

    private static class SimpleSolidPaint implements SolidPaint {
        private final ColorStyle solidColor;

        SimpleSolidPaint(final Color color) {
            if (color == null) {
                throw new NullPointerException("Color needs to be specified");
            }
            this.solidColor = new ColorStyle(){
                    public Color getColor() {
                        return new Color(color.getRed(), color.getGreen(), color.getBlue());
                    }
                    public int getAlpha() { return (int)Math.round(color.getAlpha()*100000./255.); }
                    public int getHueOff() { return -1; }
                    public int getHueMod() { return -1; }
                    public int getSatOff() { return -1; }
                    public int getSatMod() { return -1; }
                    public int getLumOff() { return -1; }
                    public int getLumMod() { return -1; }
                    public int getShade() { return -1; }
                    public int getTint() { return -1; }
                };
        }

        SimpleSolidPaint(ColorStyle color) {
            if (color == null) {
                throw new NullPointerException("Color needs to be specified");
            }
            this.solidColor = color;
        }
        
        public ColorStyle getSolidColor() {
            return solidColor;
        }
    }
    
    public static SolidPaint createSolidPaint(final Color color) {
        return (color == null) ? null : new SimpleSolidPaint(color);
    }
    
    public static SolidPaint createSolidPaint(final ColorStyle color) {
        return (color == null) ? null : new SimpleSolidPaint(color);
    }
    
    public Paint getPaint(Graphics2D graphics, PaintStyle paint) {
        if (paint instanceof SolidPaint) {
            return getSolidPaint((SolidPaint)paint, graphics);
        } else if (paint instanceof GradientPaint) {
            return getGradientPaint((GradientPaint)paint, graphics);
        } else if (paint instanceof TexturePaint) {
            return getTexturePaint((TexturePaint)paint, graphics);
        }
        return null;
    }
    
    protected Paint getSolidPaint(SolidPaint fill, Graphics2D graphics) {
        return applyColorTransform(fill.getSolidColor());
    }

    protected Paint getGradientPaint(GradientPaint fill, Graphics2D graphics) {
        switch (fill.getGradientType()) {
        case linear:
            return createLinearGradientPaint(fill, graphics);
        case circular:
            return createRadialGradientPaint(fill, graphics);
        case shape:
            return createPathGradientPaint(fill, graphics);
        default:
            throw new UnsupportedOperationException("gradient fill of type "+fill+" not supported.");
        }
    }

    protected Paint getTexturePaint(TexturePaint fill, Graphics2D graphics) {
        InputStream is = fill.getImageData();
        if (is == null) return null;
        assert(graphics != null);
        
        ImageRenderer renderer = DrawPictureShape.getImageRenderer(graphics, fill.getContentType());

        try {
            try {
                renderer.loadImage(is, fill.getContentType());
            } finally {
                is.close();
            }
        } catch (IOException e) {
            LOG.log(POILogger.ERROR, "Can't load image data - using transparent color", e);
            return null;
        }

        int alpha = fill.getAlpha();
        if (0 <= alpha && alpha < 100000) {
            renderer.setAlpha(alpha/100000.f);
        }
        
        Rectangle2D textAnchor = shape.getAnchor();
        BufferedImage image;
        if ("image/x-wmf".equals(fill.getContentType())) {
            // don't rely on wmf dimensions, use dimension of anchor
            // TODO: check pixels vs. points for image dimension 
            image = renderer.getImage(new Dimension((int)textAnchor.getWidth(), (int)textAnchor.getHeight()));
        } else {
            image = renderer.getImage();
        }

        if(image == null) {
            LOG.log(POILogger.ERROR, "Can't load image data");
            return null;
        }
        Paint paint = new java.awt.TexturePaint(image, textAnchor);

        return paint;
    }
    
    /**
     * Convert color transformations in {@link ColorStyle} to a {@link Color} instance
     * 
     * @see <a href="https://msdn.microsoft.com/en-us/library/dd560821%28v=office.12%29.aspx">Using Office Open XML to Customize Document Formatting in the 2007 Office System</a>
     * @see <a href="https://social.msdn.microsoft.com/Forums/office/en-US/040e0a1f-dbfe-4ce5-826b-38b4b6f6d3f7/saturation-modulation-satmod">saturation modulation (satMod)</a>
     * @see <a href="http://stackoverflow.com/questions/6754127/office-open-xml-satmod-results-in-more-than-100-saturation">Office Open XML satMod results in more than 100% saturation</a>
     */
    public static Color applyColorTransform(ColorStyle color){
        // TODO: The colors don't match 100% the results of Powerpoint, maybe because we still
        // operate in sRGB and not scRGB ... work in progress ...
        if (color == null || color.getColor() == null) {
            return TRANSPARENT;
        }
        
        Color result = color.getColor();

        double alpha = getAlpha(result, color);
        double hsl[] = RGB2HSL(result); // values are in the range [0..100] (usually ...)
        applyHslModOff(hsl, 0, color.getHueMod(), color.getHueOff());
        applyHslModOff(hsl, 1, color.getSatMod(), color.getSatOff());
        applyHslModOff(hsl, 2, color.getLumMod(), color.getLumOff());
        applyShade(hsl, color);
        applyTint(hsl, color);

        result = HSL2RGB(hsl[0], hsl[1], hsl[2], alpha);
        
        return result;
    }

    private static double getAlpha(Color c, ColorStyle fc) {
        double alpha = c.getAlpha()/255d;
        int fcAlpha = fc.getAlpha();
        if (fcAlpha != -1) {
            alpha *= fcAlpha/100000d;
        }
        return Math.min(1, Math.max(0, alpha));
    }
    
    /**
     * Apply the modulation and offset adjustments to the given HSL part
     * 
     * Example for lumMod/lumOff:
     * The lumMod value is the percent luminance. A lumMod value of "60000",
     * is 60% of the luminance of the original color.
     * When the color is a shade of the original theme color, the lumMod
     * attribute is the only one of the tags shown here that appears.
     * The <a:lumOff> tag appears after the <a:lumMod> tag when the color is a
     * tint of the original. The lumOff value always equals 1-lumMod, which is used in the tint calculation
     * 
     * Despite having different ways to display the tint and shade percentages,
     * all of the programs use the same method to calculate the resulting color.
     * Convert the original RGB value to HSL ... and then adjust the luminance (L)
     * with one of the following equations before converting the HSL value back to RGB.
     * (The % tint in the following equations refers to the tint, themetint, themeshade,
     * or lumMod values, as applicable.)
     * 
     * @param hsl the hsl values
     * @param hslPart the hsl part to modify [0..2]
     * @param mod the modulation adjustment
     * @param off the offset adjustment
     * @return the modified hsl value
     * 
     */
    private static void applyHslModOff(double hsl[], int hslPart, int mod, int off) {
        if (mod == -1) mod = 100000;
        if (off == -1) off = 0;
        if (!(mod == 100000 && off == 0)) {
            double fOff = off / 1000d;
            double fMod = mod / 100000d;
            hsl[hslPart] = hsl[hslPart]*fMod+fOff;
        }
    }
    
    /**
     * Apply the shade
     * 
     * For a shade, the equation is luminance * %tint.
     */
    private static void applyShade(double hsl[], ColorStyle fc) {
        int shade = fc.getShade();
        if (shade == -1) return;
        
        double fshade = shade / 100000.d;
        
        hsl[2] *= fshade;
    }

    /**
     * Apply the tint
     * 
     * For a tint, the equation is luminance * %tint + (1-%tint).
     * (Note that 1-%tint is equal to the lumOff value in DrawingML.)
     */
    private static void applyTint(double hsl[], ColorStyle fc) {
        int tint = fc.getTint();
        if (tint == -1) return;
        
        double ftint = tint / 100000.f;

        hsl[2] = hsl[2] * ftint + (100 - ftint*100.);
    }
    

    protected Paint createLinearGradientPaint(GradientPaint fill, Graphics2D graphics) {
        double angle = fill.getGradientAngle();
        Rectangle2D anchor = DrawShape.getAnchor(graphics, shape);

        AffineTransform at = AffineTransform.getRotateInstance(
            Math.toRadians(angle),
            anchor.getX() + anchor.getWidth() / 2,
            anchor.getY() + anchor.getHeight() / 2);

        double diagonal = Math.sqrt(anchor.getHeight() * anchor.getHeight() + anchor.getWidth() * anchor.getWidth());
        Point2D p1 = new Point2D.Double(anchor.getX() + anchor.getWidth() / 2 - diagonal / 2,
                anchor.getY() + anchor.getHeight() / 2);
        p1 = at.transform(p1, null);

        Point2D p2 = new Point2D.Double(anchor.getX() + anchor.getWidth(), anchor.getY() + anchor.getHeight() / 2);
        p2 = at.transform(p2, null);
        
        snapToAnchor(p1, anchor);
        snapToAnchor(p2, anchor);

        if (p1.equals(p2)) {
            // gradient paint on the same point throws an exception ... and doesn't make sense
            return null;
        }

        float[] fractions = fill.getGradientFractions();
        Color[] colors = new Color[fractions.length];
        
        int i = 0;
        for (ColorStyle fc : fill.getGradientColors()) {
            // if fc is null, use transparent color to get color of background
            colors[i++] = (fc == null) ? TRANSPARENT : applyColorTransform(fc);
        }

        AffineTransform grAt  = new AffineTransform();
        if(fill.isRotatedWithShape()) {
            double rotation = shape.getRotation();
            if (rotation != 0.) {
                double centerX = anchor.getX() + anchor.getWidth() / 2;
                double centerY = anchor.getY() + anchor.getHeight() / 2;

                grAt.translate(centerX, centerY);
                grAt.rotate(Math.toRadians(-rotation));
                grAt.translate(-centerX, -centerY);
            }
        }

        return new LinearGradientPaint
            (p1, p2, fractions, colors, CycleMethod.NO_CYCLE, ColorSpaceType.SRGB, grAt);
    }

    protected Paint createRadialGradientPaint(GradientPaint fill, Graphics2D graphics) {
        Rectangle2D anchor = DrawShape.getAnchor(graphics, shape);

        Point2D pCenter = new Point2D.Double(anchor.getX() + anchor.getWidth()/2,
                anchor.getY() + anchor.getHeight()/2);

        float radius = (float)Math.max(anchor.getWidth(), anchor.getHeight());

        float[] fractions = fill.getGradientFractions();
        Color[] colors = new Color[fractions.length];

        int i=0;
        for (ColorStyle fc : fill.getGradientColors()) {
            colors[i++] = applyColorTransform(fc);
        }

        return new RadialGradientPaint(pCenter, radius, fractions, colors);
    }

    protected Paint createPathGradientPaint(GradientPaint fill, Graphics2D graphics) {
        // currently we ignore an eventually center setting
        
        float[] fractions = fill.getGradientFractions();
        Color[] colors = new Color[fractions.length];

        int i=0;
        for (ColorStyle fc : fill.getGradientColors()) {
            colors[i++] = applyColorTransform(fc);
        }

        return new PathGradientPaint(colors, fractions);
    }
    
    protected void snapToAnchor(Point2D p, Rectangle2D anchor) {
        if (p.getX() < anchor.getX()) {
            p.setLocation(anchor.getX(), p.getY());
        } else if (p.getX() > (anchor.getX() + anchor.getWidth())) {
            p.setLocation(anchor.getX() + anchor.getWidth(), p.getY());
        }

        if (p.getY() < anchor.getY()) {
            p.setLocation(p.getX(), anchor.getY());
        } else if (p.getY() > (anchor.getY() + anchor.getHeight())) {
            p.setLocation(p.getX(), anchor.getY() + anchor.getHeight());
        }
    }

    /**
     *  Convert HSL values to a RGB Color.
     *
     *  @param h Hue is specified as degrees in the range 0 - 360.
     *  @param s Saturation is specified as a percentage in the range 1 - 100.
     *  @param l Luminance is specified as a percentage in the range 1 - 100.
     *  @param alpha  the alpha value between 0 - 1
     *
     *  @return the RGB Color object
     */
    public static Color HSL2RGB(double h, double s, double l, double alpha) {
        // we clamp the values, as it possible to come up with more than 100% sat/lum
        // (see links in applyColorTransform() for more info)
        s = Math.max(0, Math.min(100, s));
        l = Math.max(0, Math.min(100, l));

        if (alpha <0.0f || alpha > 1.0f) {
            String message = "Color parameter outside of expected range - Alpha: " + alpha;
            throw new IllegalArgumentException( message );
        }

        //  Formula needs all values between 0 - 1.

        h = h % 360.0f;
        h /= 360f;
        s /= 100f;
        l /= 100f;

        double q = (l < 0.5d)
            ? l * (1d + s)
            : (l + s) - (s * l);

        double p = 2d * l - q;

        double r = Math.max(0, HUE2RGB(p, q, h + (1.0d / 3.0d)));
        double g = Math.max(0, HUE2RGB(p, q, h));
        double b = Math.max(0, HUE2RGB(p, q, h - (1.0d / 3.0d)));

        r = Math.min(r, 1.0d);
        g = Math.min(g, 1.0d);
        b = Math.min(b, 1.0d);

        return new Color((float)r, (float)g, (float)b, (float)alpha);
    }

    private static double HUE2RGB(double p, double q, double h) {
        if (h < 0d) h += 1d;

        if (h > 1d) h -= 1d;

        if (6d * h < 1d) {
            return p + ((q - p) * 6d * h);
        }

        if (2d * h < 1d) {
            return q;
        }

        if (3d * h < 2d) {
            return p + ( (q - p) * 6d * ((2.0d / 3.0d) - h) );
        }

        return p;
    }


    /**
     *  Convert a RGB Color to it corresponding HSL values.
     *
     *  @return an array containing the 3 HSL values.
     */
    private static double[] RGB2HSL(Color color)
    {
        //  Get RGB values in the range 0 - 1

        float[] rgb = color.getRGBColorComponents( null );
        double r = rgb[0];
        double g = rgb[1];
        double b = rgb[2];

        //  Minimum and Maximum RGB values are used in the HSL calculations

        double min = Math.min(r, Math.min(g, b));
        double max = Math.max(r, Math.max(g, b));

        //  Calculate the Hue

        double h = 0;

        if (max == min) {
            h = 0;
        } else if (max == r) {
            h = ((60d * (g - b) / (max - min)) + 360d) % 360d;
        } else if (max == g) {
            h = (60d * (b - r) / (max - min)) + 120d;
        } else if (max == b) {
            h = (60d * (r - g) / (max - min)) + 240d;
        }

        //  Calculate the Luminance

        double l = (max + min) / 2d;

        //  Calculate the Saturation

        double s = 0;

        if (max == min) {
            s = 0;
        } else if (l <= .5d) {
            s = (max - min) / (max + min);
        } else {
            s = (max - min) / (2d - max - min);
        }

        return new double[] {h, s * 100, l * 100};
    }
    
    /**
     * Convert sRGB float component [0..1] from sRGB to linear RGB [0..100000]
     * 
     * @see Color#getRGBColorComponents(float[])
     */
    public static int srgb2lin(float sRGB) {
        // scRGB has a linear gamma of 1.0, scale the AWT-Color which is in sRGB to linear RGB
        // see https://en.wikipedia.org/wiki/SRGB (the reverse transformation)
        if (sRGB <= 0.04045d) {
            return (int)Math.rint(100000d * sRGB / 12.92d);
        } else {
            return (int)Math.rint(100000d * Math.pow((sRGB + 0.055d) / 1.055d, 2.4d));
        }
    }
    
    /**
     * Convert linear RGB [0..100000] to sRGB float component [0..1]
     * 
     * @see Color#getRGBColorComponents(float[])
     */
    public static float lin2srgb(int linRGB) {
        // color in percentage is in linear RGB color space, i.e. needs to be gamma corrected for AWT color
        // see https://en.wikipedia.org/wiki/SRGB (The forward transformation)
        if (linRGB <= 0.0031308d) {
            return (float)(linRGB / 100000d * 12.92d);
        } else {
            return (float)(1.055d * Math.pow(linRGB / 100000d, 1.0d/2.4d) - 0.055d);
        }
    }
}
