
// SPDX-License-Identifier: CC-BY-NC-SA-4.0
//
// Copyright (C) 2026 Bit by Bit Signal Processing LLC (https://bxbsp.com)
//
// This work is placed under the "Creative Commons Attribution
// NonCommercial ShareAlike 4.0 International" license, known
// by the shortened acronym "CC-BY-NC-SA-4.0".
//
// This work is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// A CC-BY-NC-SA-4.0 license allows you to use this work for
// noncommercial purposes so long as attribution is made to the
// original author.  Modified versions of this work may be distributed,
// but only under the same license.  For further details, see the
// Creative Commons License "CC-BY-NC-SA-4.0".
//
// You should have received a copy of the CC-BY-NC-SA-4.0 license
// along with this work. If not, see
// <https://creativecommons.org/licenses/by-nc-sa/4.0/>.
//

//

#ifndef COLOR_HH
#define COLOR_HH

#include <stdint.h>

// 5 bits Red, 6 bits Green, 5 bits Blue


typedef uint16_t color;

#define color_from_floats(r,g,b)       (((int((r)*31)&31)<<11) + ((int((g)*63)&63)<<5) + (int((b)*31)&31))
#define color_from_exact_ints(r,g,b)   (((r&31)<<11) + ((g&63)<<5) + (b&31))

//
// RGB() converts 8-bit 888 color numbers to 565.
//
#define RGB(R,G,B)  ( (((R>>3)&0x1f)<<11) +(((G>>2)&0x3f)<<5) + ((B>>3)&0x1f) ) 

inline float red_float   (color c) { return ((c >>11) & 31)/31.0; }
inline float green_float (color c) { return ((c >>5)  & 63)/63.0; }
inline float blue_float  (color c) { return (   c     & 31)/31.0; }

inline int red_exact_int   (color c)  { return ((c >>11) & 31); }
inline int green_exact_int (color c)  { return ((c >>5)  & 63); }
inline int blue_exact_int  (color c)  { return ( c       & 31); }

//                                   Move RED                             Move Green                         Move Blue
#define RGB_to_RGBA(RGB) ( ((uint32_t(RGB)&0x0000F800)<<16) | ((uint32_t(RGB)&0x000007E0)<<13) |  ((uint32_t(RGB)&0x0000001F)<<11) |  0x0000FF )

inline color scale(color c, color bg, float afrac)
{
  int r, g, b;
  float invfrac = 1.0-afrac;
  
  r = red_exact_int(c)   * afrac + red_exact_int(bg)   * invfrac;
  g = green_exact_int(c) * afrac + green_exact_int(bg) * invfrac;
  b = blue_exact_int(c)  * afrac + blue_exact_int(bg)  * invfrac;
  
  return color_from_exact_ints(r, g, b);
}


constexpr  color RED            = 0xF800;
constexpr  color GREEN          = 0x07E0;
constexpr  color BLUE           = RGB( 0,  65, 255);
constexpr  color ORANGE         = RGB(255, 140,   0);
constexpr  color BLUEGREEN      = 0x07FF;
constexpr  color PURPLE         = 0xF81F;
constexpr  color YELLOW         = 0xFFE0;
//constexpr  color GREY           = 0x7DEF;
constexpr  color GREY           = RGB( 32,  32,  32);

constexpr  color BLUEBLUE       = RGB(  0,   0, 255);

constexpr  color BLUEGREY7      = 0x6198;
constexpr  color BLUEGREY6      = 0x4110;
constexpr  color BLUEGREY5      = 0x30CC;
constexpr  color BLUEGREY4      = 0x2088;
constexpr  color BLUEGREY3      = 0x1866;
constexpr  color BLUEGREY2      = 0x1044;
constexpr  color BLUEGREY1      = 0x0822;
constexpr  color BLUEGREY0      = 0x0411;

constexpr  color WHITE          = 0xFFFF;
constexpr  color GREY9          = RGB(196, 196, 196);
constexpr  color GREY8          = RGB(158, 158, 158);
constexpr  color GREY7          = RGB(110, 110, 110);
constexpr  color GREY6          = RGB( 90,  90,  90);
constexpr  color GREY5          = RGB( 70,  70,  70);
constexpr  color GREY4          = RGB( 54,  54,  54);
constexpr  color GREY3          = RGB( 40,  40,  40);
constexpr  color GREY2          = RGB( 32,  32,  32);
constexpr  color GREY1          = RGB( 22,  22,  22);
constexpr  color GREY0          = RGB( 16,  16,  16);
constexpr  color BLACK          = 0x0000;

constexpr  color BLUE9          = RGB( 88,  98, 255);
constexpr  color BLUE8          = RGB( 68,  82, 200);
constexpr  color BLUE7          = RGB( 44,  55, 158);
constexpr  color BLUE6          = RGB( 38,  45, 110);
constexpr  color BLUE5          = RGB( 29,  35,  90);
constexpr  color BLUE4          = RGB( 20,  26,  70);
constexpr  color BLUE3          = RGB( 15,  20,  54);
constexpr  color BLUE2          = RGB( 12,  16,  40);
constexpr  color BLUE1          = RGB(  9,  11,  32);
constexpr  color BLUE0          = RGB(  6,   8,  22);

constexpr  color RED9           = RGB(255, 196, 196);
constexpr  color RED8           = RGB(196, 158, 158);
constexpr  color RED7           = RGB(158, 110, 110);
constexpr  color RED6           = RGB(110,  90,  90);
constexpr  color RED5           = RGB( 90,  70,  70);
constexpr  color RED4           = RGB( 70,  54,  54);
constexpr  color RED3           = RGB( 54,  40,  40);
constexpr  color RED2           = RGB( 40,  32,  32);
constexpr  color RED1           = RGB( 32,  22,  22);
constexpr  color RED0           = RGB( 22,  16,  16);

constexpr  color GREEN9         = RGB(196, 255, 196);
constexpr  color GREEN8         = RGB(158, 255, 158);
constexpr  color GREEN7         = RGB(110, 196, 110);
constexpr  color GREEN6         = RGB( 90, 158,  90);
constexpr  color GREEN5         = RGB( 70, 110,  70);
constexpr  color GREEN4         = RGB( 54,  90,  54);
constexpr  color GREEN3         = RGB( 40,  70,  40);
constexpr  color GREEN2         = RGB( 32,  54,  32);
constexpr  color GREEN1         = RGB( 22,  40,  22);
constexpr  color GREEN0         = RGB( 16,  32,  16);


constexpr  color REDRED9        = RGB(196,   0,   0);
constexpr  color REDRED8        = RGB(158,   0,   0);
constexpr  color REDRED7        = RGB(110,   0,   0);
constexpr  color REDRED6        = RGB( 90,   0,   0);
constexpr  color REDRED5        = RGB( 70,   0,   0);
constexpr  color REDRED4        = RGB( 54,   0,   0);
constexpr  color REDRED3        = RGB( 40,   0,   0);
constexpr  color REDRED2        = RGB( 32,   0,   0);
constexpr  color REDRED1        = RGB( 22,   0,   0);
constexpr  color REDRED0        = RGB( 16,   0,   0);

#endif
