//
//  Color.h
//  Meteor
//
//  Created by Cesar Parent on 13/07/2015.
//  Copyright (c) 2015 Cesar Parent. All rights reserved.
//

#ifndef __Meteor__CPColor__
#define __Meteor__CPColor__

#include "../defines.h"

NS_BEGIN

/**
 * @class           Color
 * @ingroup         Graphics
 * @brief           An object that representins an RGB color and its opacity (_alpha_).
 */
class Color {
    
public:
    
    /**
     * @name        Creating Colors
     * @{
     */
    
    /*!
     * @brief       A color object whose red, green and blue components are set to
     *              <code>1.0</code> (plain white).
     */
    static const Color
    whiteColor;
    
    /*!
     * @brief       A color object whose red, green and blue components are set to
     *              <code>0.0</code> (plain black).
     */
    static const Color
    blackColor;
    
    /*!
     * @brief       A color object whose color components and opacity are set to <code>0.0</code>
     *              (transparent).
     */
    static const Color
    clearColor;
    
    /*!
     * @brief       A color object representing a primary red.
     */
    static const Color
    redColor;
    
    /*!
     * @brief       A color object representing a primary green.
     */
    static const Color
    greenColor;
    
    /*!
     * @brief       A color object representing a primary blue.
     */
    static const Color
    blueColor;
    
    /*!
     * @brief       A color object whose red, green and blue components are set to random values.
     */
    static Color
    randomColor();
    
    /*!
     * @brief       Creates a color from Hue, Saturation and Brightness values.
     * @param       hue         The color's hue.
     * @param       saturation  The color's saturation.
     * @param       brightness  The color's brightness.
     * @return      A new color object.
     */
    static Color
    colorFromHSB(float hue = 0, float saturation = 1, float brightness = 1);
    
    /*!
     * @brief       Creates a color object.
     * @param       red     Red component.
     * @param       green   Green component.
     * @param       blue    Blue component.
     * @param       alpha   Alpha component.
     */
    Color(float red = 0, float green = 0, float blue = 0, float alpha = 1.f);
    
    /**
     * @}
     */
    
    /*!
     * @internal
     * @brief       Equality comparison operator.
     * @param       rhs     Color to compare <code>this</code> to.
     */
    bool
    operator==(const Color& rhs) const {
        return (red == rhs.red && green == rhs.green && blue == rhs.blue && alpha == rhs.alpha);
    }
    
    /*!
     * @internal
     * @brief       Inequality comparison operator.
     * @param       rhs     Color to compare <code>this</code> to.
     */
    bool
    operator!=(const Color& rhs) const {
        return !(*this == rhs);
    }
    
    /*!
     * @internal
     * @brief       Get the difference between two colours.
     * @param       rhs     Color removed from <code>this</code>.
     */
    Color&
    operator-=(const Color& rhs) {
        red -= rhs.red;
        green -= rhs.green;
        blue -= rhs.blue;
        alpha -= rhs.alpha;
        
        return *this;
    }
    
    /*!
     * @internal
     * @brief       Add a color to <code>this</code>.
     * @param       rhs     Color removed from <code>this</code>.
     */
    Color&
    operator+=(const Color& rhs) {
        red += rhs.red;
        green += rhs.green;
        blue += rhs.blue;
        alpha += rhs.alpha;
        
        return *this;
    }
    
    /*!
     * @internal
     */
    Color&
    operator*=(float scalar) {
        red *= scalar;
        green *= scalar;
        blue *= scalar;
        alpha *= scalar;
        
        return *this;
    }
    
    /*!
     * @internal
     */
    Color&
    operator/=(float scalar) {
        red /= scalar;
        green /= scalar;
        blue /= scalar;
        alpha /= scalar;
        
        return *this;
    }
    
    /*!
     * @internal
     * @brief       Binary - operator
     */
    const Color
    operator-(const Color& rhs) const {
        Color c(*this);
        return c -= rhs;
    }
    
    /*!
     * @internal
     * @brief       Binary + operator
     */
    const Color
    operator+(const Color& rhs) const {
        Color c(*this);
        return c += rhs;
    }
    
    /*!
     * @internal
     * @brief       Binary * operator
     */
    const Color
    operator*(float scalar) const {
        Color c(*this);
        return c *= scalar;
    }
    
    /*!
     * @internal
     * @brief       Binary / operator
     */
    const Color
    operator/(float scalar) const {
        Color c(*this);
        return c /= scalar;
    }
    
    /*!
     * @internal
     * @brief       unary - operator
     */
    const Color
    operator-() const {
        Color c(*this);
        return c * -1;
    }
    
    /*!
     * @brief       The color's red component.
     */
    float           red;
    
    /*!
     * @brief       The color's green component.
     */
    float           green;
    
    /*!
     * @brief       The color's blue component.
     */
    float           blue;
    
    /*!
     * @brief       The color's alpha component.
     */
    float           alpha;
};

NS_END

#endif /* defined(__Meteor__CPColor__) */
