/**********************************************************************
 * Copyright (c) 2017, 2018 Ericsson
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License 2.0 which
 * accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 **********************************************************************/

package org.eclipse.tracecompass.tmf.core.presentation;

import org.eclipse.jdt.annotation.Nullable;

/**
 * This class represents a color with its red, green and blue component. The
 * red, green and blue values must be between 0 and 255.
 *
 * @author Yonni Chen
 * @since 4.0
 */
public class RGBAColor {

    /**
     * Size of a circle in radians
     */
    public static final double TAU = Math.PI * 2;

    private static final int BYTEMASK = 0xFF;
    private final short fRed;
    private final short fGreen;
    private final short fBlue;
    private final short fAlpha;

    /**
     * Generate an RGBColor from an HSV (or HSB) value
     *
     * @param hue
     *            the hue
     * @param saturation
     *            the saturation
     * @param brightness
     *            the brightness
     * @param alpha
     *            the alpha
     * @return the color
     */
    public static final RGBAColor fromHSBA(float hue, float saturation, float brightness, float alpha) {
        if (hue < 0 || hue > TAU || saturation < 0 || saturation > 1 ||
                brightness < 0 || brightness > 1) {
            throw new IllegalArgumentException(String.format("Invalid color value (%f,%f,%f,%f)", hue, saturation, brightness, alpha)); //$NON-NLS-1$
        }
        double r, g, b;
        if (saturation == 0) {
            r = g = b = brightness;
        } else {
            double min = Math.min(TAU, hue);
            double quadHue = (min / (Math.PI / 3.0));
            int i = (int) quadHue;
            double f = quadHue - i;
            double p = brightness * (1 - saturation);
            double q = brightness * (1 - saturation * f);
            double t = brightness * (1 - saturation * (1 - f));
            switch (i) {
            case 0:
                r = brightness;
                g = t;
                b = p;
                break;
            case 1:
                r = q;
                g = brightness;
                b = p;
                break;
            case 2:
                r = p;
                g = brightness;
                b = t;
                break;
            case 3:
                r = p;
                g = q;
                b = brightness;
                break;
            case 4:
                r = t;
                g = p;
                b = brightness;
                break;
            case 5:
            default:
                r = brightness;
                g = p;
                b = q;
                break;
            }
        }
        return new RGBAColor((int) Math.round(r * 255), (int) Math.round(g * 255), (int) Math.round(b * 255), Math.round(alpha * 255));
    }

    /**
     * String parser, parses the output of {@link RGBAColor#toString()}
     *
     * @param toString
     *            the color
     * @return the RGBA or null if invalid
     * @since 4.1
     */
    public static @Nullable RGBAColor fromString(String toString) {
        try {
            return new RGBAColor(Long.decode(toString).intValue());
        } catch (NumberFormatException ne) {
            return null;
        }
    }

    /**
     * Constructor
     *
     * @param red
     *            The red component of the color
     * @param green
     *            The green component of the color
     * @param blue
     *            The blue component of the color
     * @param alpha
     *            The alpha (transparency) component of the color
     */
    public RGBAColor(int red, int green, int blue, int alpha) {
        if (red > 255 || red < 0) {
            throw new IllegalArgumentException("Red component must be between 0 and 255. Was : " + red); //$NON-NLS-1$
        }

        if (green > 255 || green < 0) {
            throw new IllegalArgumentException("Green component must be between 0 and 255. Was : " + green); //$NON-NLS-1$
        }

        if (blue > 255 || blue < 0) {
            throw new IllegalArgumentException("Blue component must be between 0 and 255. Was : " + blue); //$NON-NLS-1$
        }

        if (alpha > 255 || alpha < 0) {
            throw new IllegalArgumentException("Alpha component must be between 0 and 255. Was : " + alpha); //$NON-NLS-1$
        }

        fRed = (short) red;
        fGreen = (short) green;
        fBlue = (short) blue;
        fAlpha = (short) alpha;
    }

    /**
     * Constructor
     *
     * @param red
     *            The red component of the color
     * @param green
     *            The green component of the color
     * @param blue
     *            The blue component of the color
     */
    public RGBAColor(int red, int green, int blue) {
        this(red, green, blue, BYTEMASK);
    }

    /**
     * Constructor. This constructor extract RGB components from an integer.
     *
     * <li>0 maps to 0x00000000 or rgba(0, 0, 0, 0)</li>
     * <li>-1 maps to 0xFFFFFFFF or rgba(255, 255, 255, 255)</li> <br/>
     *
     * @param color
     *            The color as an integer
     */
    public RGBAColor(int color) {
        fRed = (short) ((color >> 24) & BYTEMASK);
        fGreen = (short) ((color >> 16) & BYTEMASK);
        fBlue = (short) ((color >> 8) & BYTEMASK);
        fAlpha = (short) (color & BYTEMASK);
    }

    /**
     * Gets the red component of the color
     *
     * @return The red component of the color
     */
    public short getRed() {
        return fRed;
    }

    /**
     * Gets the green component of the color
     *
     * @return The green component of the color
     */
    public short getGreen() {
        return fGreen;
    }

    /**
     * Gets the blue component of the color
     *
     * @return The blue component of the color
     */
    public short getBlue() {
        return fBlue;
    }

    /**
     * Gets the alpha component of the color
     *
     * @return the alpha component of the color
     */
    public short getAlpha() {
        return fAlpha;
    }

    /**
     * Get the HSBA in encoded floats
     *
     * @return a <em>float[]</em> of size 4
     *         <ol>
     *         <li>the hue in radians</li>
     *         <li>the saturation between 0 and 1</li>
     *         <li>the brightness or value between 0 and 1</li>
     *         <li>the alpha between 0 and 1</li>
     *         </ol>
     */
    public float[] getHSBA() {
        float r = fRed / 255f;
        float g = fGreen / 255f;
        float b = fBlue / 255f;
        float max = Math.max(Math.max(r, g), b);
        float min = Math.min(Math.min(r, g), b);
        float delta = max - min;
        float hue = 0;
        float brightness = max;
        float saturation = max == 0 ? 0 : (max - min) / max;
        if (delta != 0) {
            if (r == max) {
                hue = (g - b) / delta;
            } else {
                if (g == max) {
                    hue = 2 + (b - r) / delta;
                } else {
                    hue = 4 + (r - g) / delta;
                }
            }
            hue *= TAU / 6;
            if (hue < 0) {
                hue += TAU;
            }
        }
        return new float[] { hue, saturation, brightness, fAlpha / 255f };
    }

    /**
     * Get the integer (web color) representation of an RGBColor
     *
     * @return the integer representation of a color
     */
    public int toInt() {
        return (getRed() << 24) | (getGreen() << 16) | (getBlue() << 8) | getAlpha();
    }

    @Override
    public String toString() {
        return String.format("#%08X", toInt()); //$NON-NLS-1$
    }
}
