using System;
using System.Drawing;
namespace PKHeX.Drawing;
///
/// Utility class for manipulating values.
///
public static class ColorUtil
{
/// Clamps absurdly high stats to a reasonable cap.
private const byte MaxStat = 180;
/// Ensures the color does not go below this value.
private const byte MinStat = 0;
/// Shift the color total down a little as the BST floor isn't 0.
private const byte ShiftDownBST = 175;
/// Divide by a fudge factor so that we're roughly within the range of a single stat.
private const float ShiftDivBST = 3;
///
/// Gets the value for the specified value.
///
/// Single stat value
public static Color ColorBaseStat(int stat)
{
// Red to Yellow to Green, no Blue component.
var x = (uint)stat >= MaxStat ? 1f : ((float)stat) / MaxStat;
return GetPastelRYG(x);
}
///
/// Gets the value for the specified value.
///
/// Base Stat Total
public static Color ColorBaseStatTotal(int bst)
{
var sumToSingle = Math.Max(MinStat, bst - ShiftDownBST) / ShiftDivBST;
return ColorBaseStat((int)sumToSingle);
}
///
/// Gets a pastel color from Red to Yellow to Green with a 40%/60% blend with White.
///
/// Percentage of the way from Red to Green [0,1]
public static Color GetPastelRYG(float x)
{
var r = x > .5f ? 510 * (1 - x) : 255;
var g = x > .5f ? 255 : 510 * x;
// Blend with white to make it lighter rather than a darker shade.
const float white = 0.4f;
const byte b = (byte)(0xFF * (1 - white));
var br = (byte)((r * white) + b);
var bg = (byte)((g * white) + b);
return Color.FromArgb(br, bg, b);
}
///
/// Combines two colors together with the specified amount.
///
/// New color to layer atop
/// Original color to layer beneath
/// Amount to prefer over
public static Color Blend(Color color, Color backColor, double amount)
{
byte r = MixComponent(color.R, backColor.R, amount);
byte g = MixComponent(color.G, backColor.G, amount);
byte b = MixComponent(color.B, backColor.B, amount);
return Color.FromArgb(r, g, b);
}
///
/// Combines two color components with the specified first color percent preference [0,1].
///
/// First color's component
/// Second color's component
/// Percent preference of over
public static byte MixComponent(byte a, byte b, double x) => (byte)((a * x) + (b * (1 - x)));
}