namespace InnovEnergy.Lib.Utils; public class TextBlock { public static TextBlock Empty { get; } = new TextBlock(Array.Empty()); public IReadOnlyList Lines { get; } public Int32 Width => Lines.Count == 0 ? 0 : Lines.Max(l=>l.Length); public Int32 Height => Lines.Count; public TextBlock(IReadOnlyList lines) => Lines = lines; public TextBlock AlignLeft (Int32 width = -1) => AlignHorizontal((l, w) => l.PadRight(w), width); public TextBlock AlignRight (Int32 width = -1) => AlignHorizontal((l, w) => l.PadLeft(w), width); public TextBlock AlignHCenter(Int32 width = -1) => AlignHorizontal((l, w) => l.PadLeft((w + l.Length) / 2).PadRight(w), width); public TextBlock AlignTop (Int32 height) => Lines.Concat(EmptyLines(height)).Take(height).ToArray(height); public TextBlock AlignBottom (Int32 height) => EmptyLines(Lines.Count - height).Concat(Lines).Take(height).ToArray(height); //public TextBlock AlignVCenter(Int32 height) => EmptyLines(height/2).Concat(Lines).Take(height).ToArray(height); //public TextBlock AlignVCenter(Int32 height) => AlignHorizontal((l, w) => l.PadLeft((w + l.Length) / 2).PadRight(w), width); private static IEnumerable EmptyLines(Int32 height) { return height > 0 ? Enumerable.Repeat("", height) : Enumerable.Empty(); } public static TextBlock HSpace(Int32 width ) => new TextBlock(new []{"".PadRight(width)}); public static TextBlock VSpace(Int32 height) => new TextBlock(Enumerable.Repeat("", height).ToArray(height)); public static TextBlock Space(Int32 width, Int32 height) { var lines = Enumerable .Repeat("".PadRight(width), height) .ToArray(height); return new TextBlock(lines); } private TextBlock AlignHorizontal(Func alignLine, Int32 width = -1) { if (!Lines.Any()) return Empty; var strings = Lines .SelectMany(GetLines) .ToList(); width = width < 0 ? strings.Max(l => l.Length) : width; var aligned = strings .Select(l => l.Length > width ? l.Substring(0, width) : l) .Select(l => alignLine(l, width)) .ToArray(strings.Count); return new TextBlock(aligned); } private static IReadOnlyList GetLines(Object l) { return l is TextBlock tb ? tb.Lines : l.ToString()?.SplitLines() ?? new[] { "" }; } public override String ToString() => String.Join(Environment.NewLine, Lines); public static implicit operator TextBlock(String[] lines) => new TextBlock(lines); }