using System;
using System.Collections.Generic;
namespace StardewModdingAPI.Internal.ConsoleWriting
{
/// Provides a wrapper for writing color-coded text to the console.
internal class ColorfulConsoleWriter
{
/*********
** Properties
*********/
/// The console text color for each log level.
private readonly IDictionary Colors;
/// Whether the current console supports color formatting.
private readonly bool SupportsColor;
/*********
** Public methods
*********/
/// Construct an instance.
/// The target platform.
/// The console color scheme to use.
public ColorfulConsoleWriter(Platform platform, MonitorColorScheme colorScheme)
{
this.SupportsColor = this.TestColorSupport();
this.Colors = this.GetConsoleColorScheme(platform, colorScheme);
}
/// Write a message line to the log.
/// The message to log.
/// The log level.
public void WriteLine(string message, ConsoleLogLevel level)
{
if (this.SupportsColor)
{
if (level == ConsoleLogLevel.Critical)
{
Console.BackgroundColor = ConsoleColor.Red;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(message);
Console.ResetColor();
}
else
{
Console.ForegroundColor = this.Colors[level];
Console.WriteLine(message);
Console.ResetColor();
}
}
else
Console.WriteLine(message);
}
/*********
** Private methods
*********/
/// Test whether the current console supports color formatting.
private bool TestColorSupport()
{
try
{
Console.ForegroundColor = Console.ForegroundColor;
return true;
}
catch (Exception)
{
return false; // Mono bug
}
}
/// Get the color scheme to use for the current console.
/// The target platform.
/// The console color scheme to use.
private IDictionary GetConsoleColorScheme(Platform platform, MonitorColorScheme colorScheme)
{
// auto detect color scheme
if (colorScheme == MonitorColorScheme.AutoDetect)
{
colorScheme = platform == Platform.Mac
? MonitorColorScheme.LightBackground // MacOS doesn't provide console background color info, but it's usually white.
: ColorfulConsoleWriter.IsDark(Console.BackgroundColor) ? MonitorColorScheme.DarkBackground : MonitorColorScheme.LightBackground;
}
// get colors for scheme
switch (colorScheme)
{
case MonitorColorScheme.DarkBackground:
return new Dictionary
{
[ConsoleLogLevel.Trace] = ConsoleColor.DarkGray,
[ConsoleLogLevel.Debug] = ConsoleColor.DarkGray,
[ConsoleLogLevel.Info] = ConsoleColor.White,
[ConsoleLogLevel.Warn] = ConsoleColor.Yellow,
[ConsoleLogLevel.Error] = ConsoleColor.Red,
[ConsoleLogLevel.Alert] = ConsoleColor.Magenta,
[ConsoleLogLevel.Success] = ConsoleColor.DarkGreen
};
case MonitorColorScheme.LightBackground:
return new Dictionary
{
[ConsoleLogLevel.Trace] = ConsoleColor.DarkGray,
[ConsoleLogLevel.Debug] = ConsoleColor.DarkGray,
[ConsoleLogLevel.Info] = ConsoleColor.Black,
[ConsoleLogLevel.Warn] = ConsoleColor.DarkYellow,
[ConsoleLogLevel.Error] = ConsoleColor.Red,
[ConsoleLogLevel.Alert] = ConsoleColor.DarkMagenta,
[ConsoleLogLevel.Success] = ConsoleColor.DarkGreen
};
default:
throw new NotSupportedException($"Unknown color scheme '{colorScheme}'.");
}
}
/// Get whether a console color should be considered dark, which is subjectively defined as 'white looks better than black on this text'.
/// The color to check.
private static bool IsDark(ConsoleColor color)
{
switch (color)
{
case ConsoleColor.Black:
case ConsoleColor.Blue:
case ConsoleColor.DarkBlue:
case ConsoleColor.DarkMagenta: // Powershell
case ConsoleColor.DarkRed:
case ConsoleColor.Red:
return true;
default:
return false;
}
}
}
}