/* ====================================================================
   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.ddf;

import org.apache.poi.util.BitField;
import org.apache.poi.util.LittleEndian;

/**
 * An OfficeArtCOLORREF structure entry which also handles color extension opid data
 */
public class EscherColorRef {
    @SuppressWarnings("unused")
    private int opid = -1;
    private int colorRef = 0;

    public enum SysIndexSource {
        /** Use the fill color of the shape. */
        FILL_COLOR(0xF0),
        /** If the shape contains a line, use the line color of the shape. Otherwise, use the fill color. */
        LINE_OR_FILL_COLOR(0xF1),
        /** Use the line color of the shape. */
        LINE_COLOR(0xF2),
        /** Use the shadow color of the shape. */
        SHADOW_COLOR(0xF3),
        /** Use the current, or last-used, color. */
        CURRENT_OR_LAST_COLOR(0xF4),
        /** Use the fill background color of the shape. */
        FILL_BACKGROUND_COLOR(0xF5),
        /** Use the line background color of the shape. */
        LINE_BACKGROUND_COLOR(0xF6),
        /** If the shape contains a fill, use the fill color of the shape. Otherwise, use the line color. */
        FILL_OR_LINE_COLOR(0xF7)
        ;
        private int value;
        SysIndexSource(int value) { this.value = value; }
    }

    /**
     * The following enum specifies values that indicate special procedural properties that
     * are used to modify the color components of another color. These values are combined with
     * those of the {@link SysIndexSource} enum or with a user-specified color.
     * The first six values are mutually exclusive.
     */
    public enum SysIndexProcedure {
        /**
         * Darken the color by the value that is specified in the blue field.
         * A blue value of 0xFF specifies that the color is to be left unchanged,
         * whereas a blue value of 0x00 specifies that the color is to be completely darkened.
         */
        DARKEN_COLOR(0x01),
        /**
         * Lighten the color by the value that is specified in the blue field.
         * A blue value of 0xFF specifies that the color is to be left unchanged,
         * whereas a blue value of 0x00 specifies that the color is to be completely lightened.
         */
        LIGHTEN_COLOR(0x02),
        /**
         * Add a gray level RGB value. The blue field contains the gray level to add:
         * NewColor = SourceColor + gray
         */
        ADD_GRAY_LEVEL(0x03),
        /**
         * Subtract a gray level RGB value. The blue field contains the gray level to subtract:
         * NewColor = SourceColor - gray
         */
        SUB_GRAY_LEVEL(0x04),
        /**
         * Reverse-subtract a gray level RGB value. The blue field contains the gray level from
         * which to subtract:
         * NewColor = gray - SourceColor
         */
        REVERSE_GRAY_LEVEL(0x05),
        /**
         * If the color component being modified is less than the parameter contained in the blue
         * field, set it to the minimum intensity. If the color component being modified is greater
         * than or equal to the parameter, set it to the maximum intensity.
         */
        THRESHOLD(0x06),
        /**
         * After making other modifications, invert the color.
         * This enum value is only for documentation and won't be directly returned.
         */
        INVERT_AFTER(0x20),
        /**
         * After making other modifications, invert the color by toggling just the high bit of each
         * color channel.
         * This enum value is only for documentation and won't be directly returned.
         */
        INVERT_HIGHBIT_AFTER(0x40)
        ;
        private BitField mask;
        SysIndexProcedure(int mask) {
            this.mask = new BitField(mask);
        }
    }
    
    /**
     * A bit that specifies whether the system color scheme will be used to determine the color. 
     * A value of 0x1 specifies that green and red will be treated as an unsigned 16-bit index
     * into the system color table. Values less than 0x00F0 map directly to system colors.
     */
    private static final BitField FLAG_SYS_INDEX     = new BitField(0x10000000);

    /**
     * A bit that specifies whether the current application-defined color scheme will be used
     * to determine the color. A value of 0x1 specifies that red will be treated as an index
     * into the current color scheme table. If this value is 0x1, green and blue MUST be 0x00.
     */
    private static final BitField FLAG_SCHEME_INDEX  = new BitField(0x08000000);
    
    /**
     * A bit that specifies whether the color is a standard RGB color.
     * 0x0 : The RGB color MAY use halftone dithering to display.
     * 0x1 : The color MUST be a solid color.
     */
    private static final BitField FLAG_SYSTEM_RGB    = new BitField(0x04000000);
    
    /**
     * A bit that specifies whether the current palette will be used to determine the color.
     * A value of 0x1 specifies that red, green, and blue contain an RGB value that will be
     * matched in the current color palette. This color MUST be solid.
     */
    private static final BitField FLAG_PALETTE_RGB   = new BitField(0x02000000);

    /**
     * A bit that specifies whether the current palette will be used to determine the color.
     * A value of 0x1 specifies that green and red will be treated as an unsigned 16-bit index into 
     * the current color palette. This color MAY be dithered. If this value is 0x1, blue MUST be 0x00.
     */
    private static final BitField FLAG_PALETTE_INDEX = new BitField(0x01000000);
    
    /**
     * An unsigned integer that specifies the intensity of the blue color channel. A value
     * of 0x00 has the minimum blue intensity. A value of 0xFF has the maximum blue intensity.
     */
    private static final BitField FLAG_BLUE          = new BitField(0x00FF0000);
    
    /**
     * An unsigned integer that specifies the intensity of the green color channel. A value
     * of 0x00 has the minimum green intensity. A value of 0xFF has the maximum green intensity.
     */
    private static final BitField FLAG_GREEN         = new BitField(0x0000FF00);
    
    /**
     * An unsigned integer that specifies the intensity of the red color channel. A value
     * of 0x00 has the minimum red intensity. A value of 0xFF has the maximum red intensity.
     */
    private static final BitField FLAG_RED           = new BitField(0x000000FF);
    
    public EscherColorRef(int colorRef) {
        this.colorRef = colorRef;
    }
    
    public EscherColorRef(byte[] source, int start, int len) {
        assert(len == 4 || len == 6);
        
        int offset = start;
        if (len == 6) {
            opid = LittleEndian.getUShort(source, offset);
            offset += 2;
        }
        colorRef = LittleEndian.getInt(source, offset);
    }
    
    public boolean hasSysIndexFlag() {
        return FLAG_SYS_INDEX.isSet(colorRef);
    }
    
    public void setSysIndexFlag(boolean flag) {
        colorRef = FLAG_SYS_INDEX.setBoolean(colorRef, flag);
    }
    
    public boolean hasSchemeIndexFlag() {
        return FLAG_SCHEME_INDEX.isSet(colorRef);
    }
    
    public void setSchemeIndexFlag(boolean flag) {
        colorRef = FLAG_SCHEME_INDEX.setBoolean(colorRef, flag);
    }
    
    public boolean hasSystemRGBFlag() {
        return FLAG_SYSTEM_RGB.isSet(colorRef);
    }
    
    public void setSystemRGBFlag(boolean flag) {
        colorRef = FLAG_SYSTEM_RGB.setBoolean(colorRef, flag);
    }
    
    public boolean hasPaletteRGBFlag() {
        return FLAG_PALETTE_RGB.isSet(colorRef);
    }
    
    public void setPaletteRGBFlag(boolean flag) {
        colorRef = FLAG_PALETTE_RGB.setBoolean(colorRef, flag);
    }
    
    public boolean hasPaletteIndexFlag() {
        return FLAG_PALETTE_INDEX.isSet(colorRef);
    }
    
    public void setPaletteIndexFlag(boolean flag) {
        colorRef = FLAG_PALETTE_INDEX.setBoolean(colorRef, flag);
    }

    public int[] getRGB() {
        int rgb[] = {
            FLAG_RED.getValue(colorRef),
            FLAG_GREEN.getValue(colorRef),
            FLAG_BLUE.getValue(colorRef)
        };
        return rgb;
    }
    
    /**
     * @return {@link SysIndexSource} if {@link #hasSysIndexFlag()} is {@code true}, otherwise null
     */
    public SysIndexSource getSysIndexSource() {
        if (!hasSysIndexFlag()) return null;
        int val = FLAG_RED.getValue(colorRef);
        for (SysIndexSource sis : SysIndexSource.values()) {
            if (sis.value == val) return sis;
        }
        return null;
    }
    
    /**
     * Return the {@link SysIndexProcedure} - for invert flag use {@link #getSysIndexInvert()}
     * @return {@link SysIndexProcedure} if {@link #hasSysIndexFlag()} is {@code true}, otherwise null
     */
    public SysIndexProcedure getSysIndexProcedure() {
        if (!hasSysIndexFlag()) return null;
        int val = FLAG_GREEN.getValue(colorRef);
        for (SysIndexProcedure sip : SysIndexProcedure.values()) {
            if (sip == SysIndexProcedure.INVERT_AFTER || sip == SysIndexProcedure.INVERT_HIGHBIT_AFTER) continue;
            if (sip.mask.isSet(val)) return sip;
        }
        return null;
    }
    
    /**
     * @return 0 for no invert flag, 1 for {@link SysIndexProcedure#INVERT_AFTER} and
     * 2 for {@link SysIndexProcedure#INVERT_HIGHBIT_AFTER} 
     */
    public int getSysIndexInvert() {
        if (!hasSysIndexFlag()) return 0;
        int val = FLAG_GREEN.getValue(colorRef);
        if ((SysIndexProcedure.INVERT_AFTER.mask.isSet(val))) return 1;
        if ((SysIndexProcedure.INVERT_HIGHBIT_AFTER.mask.isSet(val))) return 2;
        return 0;
    }
    
    /**
     * @return index of the scheme color or -1 if {@link #hasSchemeIndexFlag()} is {@code false}
     * 
     * @see org.apache.poi.hslf.record.ColorSchemeAtom#getColor(int)
     */
    public int getSchemeIndex() {
        if (!hasSchemeIndexFlag()) return -1;
        return FLAG_RED.getValue(colorRef);
    }
    
    /**
     * @return index of current palette (color) or -1 if {@link #hasPaletteIndexFlag()} is {@code false}
     */
    public int getPaletteIndex() {
        return (hasPaletteIndexFlag()) ? getIndex() : -1;
    }

    /**
     * @return index of system color table or -1 if {@link #hasSysIndexFlag()} is {@code false}
     * 
     * @see org.apache.poi.sl.usermodel.PresetColor
     */
    public int getSysIndex() {
        return (hasSysIndexFlag()) ? getIndex() : -1;
    }
    
    private int getIndex() {
        return (FLAG_GREEN.getValue(colorRef) << 8) | FLAG_RED.getValue(colorRef);
    }
}
