/*
 *  ====================================================================
 *    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.xslf.usermodel;

import java.awt.Color;

import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.PresetColor;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTFontReference;
import org.openxmlformats.schemas.drawingml.x2006.main.CTHslColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveFixedPercentage;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTScRgbColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSystemColor;
import org.w3c.dom.Node;

/**
 * Encapsulates logic to read color definitions from DrawingML and convert them to java.awt.Color
 */
@Beta
@Internal
public class XSLFColor {
    private final static POILogger LOGGER = POILogFactory.getLogger(XSLFColor.class);
    
    private XmlObject _xmlObject;
    private Color _color;
    private CTSchemeColor _phClr;

    public XSLFColor(XmlObject obj, XSLFTheme theme, CTSchemeColor phClr) {
        _xmlObject = obj;
        _phClr = phClr;
        _color = toColor(obj, theme);
    }

    @Internal
    public XmlObject getXmlObject() {
        return _xmlObject;
    }

    /**
     *
     * @return  the displayed color as a Java Color.
     * If not color information was found in the supplied xml object then a null is returned.
     */
    public Color getColor() {
        return DrawPaint.applyColorTransform(getColorStyle());
    }

    public ColorStyle getColorStyle() {
        return new ColorStyle() {
            public Color getColor() {
                return _color;
            }

            public int getAlpha() {
                return getRawValue("alpha");
            }

            public int getHueOff() {
                return getRawValue("hueOff");
            }

            public int getHueMod() {
                return getRawValue("hueMod");
            }

            public int getSatOff() {
                return getRawValue("satOff");
            }

            public int getSatMod() {
                return getRawValue("satMod");
            }

            public int getLumOff() {
                return getRawValue("lumOff");
            }

            public int getLumMod() {
                return getRawValue("lumMod");
            }

            public int getShade() {
                return getRawValue("shade");
            }

            public int getTint() {
                return getRawValue("tint");
            }
        };
    }
    
    Color toColor(XmlObject obj, XSLFTheme theme) {
        Color color = null;
        for (XmlObject ch : obj.selectPath("*")) {
            if (ch instanceof CTHslColor) {
                CTHslColor hsl = (CTHslColor)ch;
                int h = hsl.getHue2();
                int s = hsl.getSat2();
                int l = hsl.getLum2();
                color = DrawPaint.HSL2RGB(h / 60000d, s / 1000d, l / 1000d, 1d);
            } else if (ch instanceof CTPresetColor) {
                CTPresetColor prst = (CTPresetColor)ch;
                String colorName = prst.getVal().toString();
                PresetColor pc = PresetColor.valueOfOoxmlId(colorName);
                if (pc != null) {
                    color = pc.color;
                }
            } else if (ch instanceof CTSchemeColor) {
                CTSchemeColor schemeColor = (CTSchemeColor)ch;
                String colorRef = schemeColor.getVal().toString();
                if(_phClr != null) {
                    // context color overrides the theme
                    colorRef = _phClr.getVal().toString();
                }
                // find referenced CTColor in the theme and convert it to java.awt.Color via a recursive call
                CTColor ctColor = theme.getCTColor(colorRef);
                if(ctColor != null) color = toColor(ctColor, null);
            } else if (ch instanceof CTScRgbColor) {
                // color in percentage is in linear RGB color space, i.e. needs to be gamma corrected for AWT color
                CTScRgbColor scrgb = (CTScRgbColor)ch;
                color = new Color(DrawPaint.lin2srgb(scrgb.getR()), DrawPaint.lin2srgb(scrgb.getG()), DrawPaint.lin2srgb(scrgb.getB()));
            } else if (ch instanceof CTSRgbColor) {
                // color in sRGB color space, i.e. same as AWT Color
                CTSRgbColor srgb = (CTSRgbColor)ch;
                byte[] val = srgb.getVal();
                color = new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
            } else if (ch instanceof CTSystemColor) {
                CTSystemColor sys = (CTSystemColor)ch;
                if(sys.isSetLastClr()) {
                    byte[] val = sys.getLastClr();
                    color = new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
                } else {
                    String colorName = sys.getVal().toString();
                    PresetColor pc = PresetColor.valueOfOoxmlId(colorName);
                    if (pc != null) {
                        color = pc.color;
                    }
                    if (color == null) {
                        color = Color.black;
                    }
                }
            } else if (ch instanceof CTFontReference) {
                // try next ...
                continue;
            } else {
                throw new IllegalArgumentException("Unexpected color choice: " + ch.getClass());
            }
        }
        return color;
    }

    /**
     * Sets the solid color
     *
     * @param color solid color
     */
    @Internal
    protected void setColor(Color color) {
        if (!(_xmlObject instanceof CTSolidColorFillProperties)) {
            LOGGER.log(POILogger.ERROR, "XSLFColor.setColor currently only supports CTSolidColorFillProperties");
            return;
        }
        CTSolidColorFillProperties fill = (CTSolidColorFillProperties)_xmlObject;
        if (fill.isSetSrgbClr()) {
            fill.unsetSrgbClr();
        }

        if (fill.isSetScrgbClr()) {
            fill.unsetScrgbClr();
        }
        
        if (fill.isSetHslClr()) {
            fill.unsetHslClr();
        }
        
        if (fill.isSetPrstClr()) {
            fill.unsetPrstClr();
        }
        
        if (fill.isSetSchemeClr()) {
            fill.unsetSchemeClr();
        }
        
        if (fill.isSetSysClr()) {
            fill.unsetSysClr();
        }

        float[] rgbaf = color.getRGBComponents(null);
        boolean addAlpha = (rgbaf.length == 4 && rgbaf[3] < 1f);
        CTPositiveFixedPercentage alphaPct;
        
        // see office open xml part 4 - 5.1.2.2.30 and 5.1.2.2.32
        if (isInt(rgbaf[0]) && isInt(rgbaf[1]) && isInt(rgbaf[2])) {
            // sRGB has a gamma of 2.2
            CTSRgbColor rgb = fill.addNewSrgbClr();
            
            byte rgbBytes[] = { (byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue() };
            rgb.setVal(rgbBytes);
            alphaPct = (addAlpha) ? rgb.addNewAlpha() : null;
        } else {
            CTScRgbColor rgb = fill.addNewScrgbClr();
            rgb.setR(DrawPaint.srgb2lin(rgbaf[0]));
            rgb.setG(DrawPaint.srgb2lin(rgbaf[1]));
            rgb.setB(DrawPaint.srgb2lin(rgbaf[2]));
            alphaPct = (addAlpha) ? rgb.addNewAlpha() : null;
        }

        // alpha (%)
        if (alphaPct != null) {
            alphaPct.setVal((int)(100000 * rgbaf[3]));
        }
    }
    
    /**
     * @return true, if this is an integer color value
     */
    private static boolean isInt(float f) {
        return Math.abs((f*255f) - Math.rint(f*255f)) < 0.00001f;
    }
    
    private int getRawValue(String elem) {
        String query = "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' $this//a:" + elem;

        XmlObject[] obj;

        // first ask the context color and if not found, ask the actual color bean
        if (_phClr != null){
            obj = _phClr.selectPath(query);
            if (obj.length == 1){
                Node attr = obj[0].getDomNode().getAttributes().getNamedItem("val");
                if(attr != null) {
                    return Integer.parseInt(attr.getNodeValue());
                }
            }
        }

        obj = _xmlObject.selectPath(query);
        if (obj.length == 1){
            Node attr = obj[0].getDomNode().getAttributes().getNamedItem("val");
            if(attr != null) {
                return Integer.parseInt(attr.getNodeValue());
            }
        }

        return -1;        
    }
    
    /**
     * Read a perecentage value from the supplied xml bean.
     * Example:
     *   <a:tint val="45000"/>
     *
     * the returned value is 45
     *
     * @return  the percentage value in the range [0 .. 100]
     */
    private int getPercentageValue(String elem){
        int val = getRawValue(elem);
        return (val == -1) ? val : (val / 1000);
    }

    private int getAngleValue(String elem){
        int val = getRawValue(elem);
        return (val == -1) ? val : (val / 60000);
    }

    /**
     * the opacity as expressed by a percentage value
     *
     * @return  opacity in percents in the range [0..100]
     * or -1 if the value is not set
     */
    int getAlpha(){
        return getPercentageValue("alpha");        
    }

    /**
     * the opacity as expressed by a percentage relative to the input color
     *
     * @return  opacity in percents in the range [0..100]
     * or -1 if the value is not set
     */
    int getAlphaMod(){
        return getPercentageValue("alphaMod");
    }

    /**
     * the opacity as expressed by a percentage offset increase or decrease relative to
     * the input color. Increases will never increase the opacity beyond 100%, decreases will
     * never decrease the opacity below 0%.
     *
     * @return  opacity shift in percents in the range [0..100]
     * or -1 if the value is not set
     */
    int getAlphaOff(){
        return getPercentageValue("alphaOff");
    }


    int getHue(){
        return getAngleValue("hue");
    }

    int getHueMod(){
        return getPercentageValue("hueMod");
    }

    int getHueOff(){
        return getPercentageValue("hueOff");
    }

    /**
     * specifies the input color with the specified luminance,
     * but with its hue and saturation unchanged.
     *
     * @return  luminance in percents in the range [0..100]
     * or -1 if the value is not set
     */
    int getLum(){
        return getPercentageValue("lum");
    }

    /**
     * the luminance as expressed by a percentage relative to the input color
     *
     * @return  luminance in percents in the range [0..100]
     * or -1 if the value is not set
     */
    int getLumMod(){
        return getPercentageValue("lumMod");
    }

    /**
     * the luminance shift as expressed by a percentage relative to the input color
     *
     * @return  luminance shift in percents in the range [0..100]
     * or -1 if the value is not set
     */
    int getLumOff(){
        return getPercentageValue("lumOff");
    }

    /**
     * specifies the input color with the specified saturation,
     * but with its hue and luminance unchanged.
     *
     * @return  saturation in percents in the range [0..100]
     * or -1 if the value is not set
     */
    int getSat(){
        return getPercentageValue("sat");
    }

    /**
     * the saturation as expressed by a percentage relative to the input color
     *
     * @return  saturation in percents in the range [0..100]
     * or -1 if the value is not set
     */
    int getSatMod(){
        return getPercentageValue("satMod");
    }

    /**
     * the saturation shift as expressed by a percentage relative to the input color
     *
     * @return  saturation shift in percents in the range [0..100]
     * or -1 if the value is not set
     */
    int getSatOff(){
        return getPercentageValue("satOff");
    }

    /**
     * specifies the input color with the specific red component, but with the blue and green color
     * components unchanged
     * 
     * @return the value of the red component specified as a
     * percentage with 0% indicating minimal blue and 100% indicating maximum
     * or -1 if the value is not set
     */
    int getRed(){
        return getPercentageValue("red");
    }

    int getRedMod(){
        return getPercentageValue("redMod");
    }

    int getRedOff(){
        return getPercentageValue("redOff");
    }

    /**
     * specifies the input color with the specific green component, but with the red and blue color
     * components unchanged
     *
     * @return the value of the green component specified as a
     * percentage with 0% indicating minimal blue and 100% indicating maximum
     * or -1 if the value is not set
     */
    int getGreen(){
        return getPercentageValue("green");
    }

    int getGreenMod(){
        return getPercentageValue("greenMod");
    }

    int getGreenOff(){
        return getPercentageValue("greenOff");
    }

    /**
     * specifies the input color with the specific blue component, but with the red and green color
     * components unchanged
     *
     * @return the value of the blue component specified as a
     * percentage with 0% indicating minimal blue and 100% indicating maximum
     * or -1 if the value is not set
     */
    int getBlue(){
        return getPercentageValue("blue");
    }

    int getBlueMod(){
        return getPercentageValue("blueMod");
    }

    int getBlueOff(){
        return getPercentageValue("blueOff");
    }

    /**
     * specifies a darker version of its input color.
     * A 10% shade is 10% of the input color combined with 90% black.
     * 
     * @return the value of the shade specified as a
     * percentage with 0% indicating minimal shade and 100% indicating maximum
     * or -1 if the value is not set
     */
    public int getShade(){
        return getPercentageValue("shade");
    }

    /**
     * specifies a lighter version of its input color.
     * A 10% tint is 10% of the input color combined with 90% white.
     *
     * @return the value of the tint specified as a
     * percentage with 0% indicating minimal tint and 100% indicating maximum
     * or -1 if the value is not set
     */
    public int getTint(){
        return getPercentageValue("tint");
    }
}
