using SharedLibraryCore.Interfaces; using System; using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.Linq; using System.Threading.Tasks; namespace WebfrontCore.Middleware { public class CustomCssAccentMiddlewareAction : IMiddlewareAction { private readonly List ColorReplacements = new List(); private class ColorMap { public Color Original { get; set; } public Color Replacement { get; set; } } public CustomCssAccentMiddlewareAction(string originalPrimaryColor, string originalSecondaryColor, string primaryColor, string secondaryColor) { primaryColor = string.IsNullOrWhiteSpace(primaryColor) ? originalPrimaryColor : primaryColor; secondaryColor = string.IsNullOrWhiteSpace(secondaryColor) ? originalSecondaryColor : secondaryColor; try { ColorReplacements.AddRange(new[] { new ColorMap() { Original = Color.FromArgb(Convert.ToInt32(originalPrimaryColor.Substring(1).ToString(), 16)), Replacement = Color.FromArgb(Convert.ToInt32(primaryColor.Substring(1).ToString(), 16)) }, new ColorMap() { Original = Color.FromArgb(Convert.ToInt32(originalSecondaryColor.Substring(1).ToString(), 16)), Replacement = Color.FromArgb(Convert.ToInt32(secondaryColor.Substring(1).ToString(), 16)) } }); } catch (FormatException) { } } public Task Invoke(string original) { foreach (var color in ColorReplacements) { foreach (var shade in new[] { 0, -19, -25 }) { original = original .Replace(ColorToHex(LightenDarkenColor(color.Original, shade)), ColorToHex(LightenDarkenColor(color.Replacement, shade)), StringComparison.OrdinalIgnoreCase) .Replace(ColorToDec(LightenDarkenColor(color.Original, shade)), ColorToDec(LightenDarkenColor(color.Replacement, shade)), StringComparison.OrdinalIgnoreCase); } } return Task.FromResult(original); } /// /// converts color to the hex string representation /// /// /// private string ColorToHex(Color color) => $"#{color.R.ToString("X2")}{color.G.ToString("X2")}{color.B.ToString("X2")}"; /// /// converts color to the rgb tuples representation /// /// /// private string ColorToDec(Color color) => $"{(int)color.R}, {(int)color.G}, {(int)color.B}"; /// /// lightens or darkens a color on the given amount /// Based off SASS darken/lighten function /// /// /// /// private Color LightenDarkenColor(Color color, float amount) { int r = color.R + (int)((amount / 100.0f) * color.R); if (r > 255) r = 255; else if (r < 0) r = 0; int g = color.G + (int)((amount / 100.0f) * color.G); if (g > 255) g = 255; else if (g < 0) g = 0; int b = color.B + (int)((amount / 100.0f) * color.B); if (b > 255) b = 255; else if (b < 0) b = 0; return Color.FromArgb(r, g, b); } } }