Editor/HotCodeEditor/Ui/HotCodeLogo.cs
using Sandbox;
using Editor;
using System;
using System.Linq;

/// <summary>
/// The HotCode flame: red outer flame, orange middle, yellow core, each with a vertical gradient.
/// The outlines are generated by logo/flame.py (HotCodeLogo.Shapes.cs), which also renders the
/// PNGs next to it in logo/, so the painted logo and the images always match.
/// </summary>
public static partial class HotCodeLogo
{
	/// <summary>
	/// Material icon name for places that only take an icon name (EditorApp, menus).
	/// </summary>
	public const string IconName = "local_fire_department";

	private static readonly (Func<Vector2[]> Shape, Color Top, Color Bottom)[] Layers =
	{
		(() => Outer, Hex( "#E21D12" ), Hex( "#FF5A14" )),
		(() => Middle, Hex( "#FF6A10" ), Hex( "#FFA01C" )),
		(() => Core, Hex( "#FFC82A" ), Hex( "#FFF19A" )),
	};

	public static readonly Color BadgeBackground = Hex( "#1c1c1c" );
	public static readonly Color Glow = Hex( "#FF5810" );

	/// <summary>
	/// Draws just the flame, filling <paramref name="rect"/> (keep it square).
	/// </summary>
	public static void PaintFlame( Rect rect )
	{
		Paint.Antialiasing = true;
		Paint.ClearPen();

		foreach ( var (shape, top, bottom) in Layers )
		{
			var points = shape().Select( p => new Vector2( rect.Left + p.x * rect.Width, rect.Top + p.y * rect.Height ) ).ToArray();
			Paint.SetBrushLinear( new Vector2( rect.Left, rect.Top ), new Vector2( rect.Left, rect.Bottom ), top, bottom );
			Paint.DrawPolygon( points );
		}
	}

	/// <summary>
	/// The flame on a dark rounded square with a warm glow, like the package thumbnail.
	/// </summary>
	public static void PaintBadge( Rect rect )
	{
		Paint.Antialiasing = true;
		Paint.ClearPen();
		Paint.SetBrush( BadgeBackground );
		Paint.DrawRect( rect, rect.Width * 0.18f );

		var glow = new Rect( rect.Left + rect.Width * 0.2f, rect.Top + rect.Height * 0.32f, rect.Width * 0.6f, rect.Height * 0.58f );
		Paint.SetBrushRadial( glow.Center, glow.Width * 0.5f, Glow.WithAlpha( 0.35f ), Glow.WithAlpha( 0 ) );
		Paint.DrawRect( glow );

		var inset = rect.Width * 0.15f;
		PaintFlame( new Rect( rect.Left + inset, rect.Top + rect.Height * 0.13f, rect.Width - inset * 2, rect.Height - inset * 2 ) );
	}

	private static Pixmap _windowIcon;

	/// <summary>
	/// The flame as a pixmap, for SetWindowIcon (window title bars and the taskbar).
	/// </summary>
	public static Pixmap WindowIcon
	{
		get
		{
			if ( _windowIcon is not null ) return _windowIcon;

			_windowIcon = new Pixmap( 64, 64 );
			_windowIcon.Clear( Color.Transparent );
			using ( Paint.ToPixmap( _windowIcon ) )
			{
				PaintFlame( new Rect( 0, 0, 64, 64 ) );
			}

			return _windowIcon;
		}
	}

	private static Color Hex( string hex ) => Color.Parse( hex ) ?? Color.White;
}

/// <summary>
/// A widget that just shows the logo: the badge, or the bare flame.
/// </summary>
public class LogoWidget : Widget
{
	private readonly bool _badge;

	public LogoWidget( Widget parent, float size, bool badge ) : base( parent )
	{
		_badge = badge;
		FixedSize = new Vector2( size, size );
		TransparentForMouseEvents = true;
	}

	protected override void OnPaint()
	{
		if ( _badge ) HotCodeLogo.PaintBadge( LocalRect );
		else HotCodeLogo.PaintFlame( LocalRect );
	}
}