using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using LibreHardwareMonitor.Hardware;
using PCPalConfigurator.Rendering;
using PCPalConfigurator.Rendering.Elements;
namespace PCPalConfigurator.Core
{
///
/// Parses OLED markup into renderable elements
///
public class MarkupParser
{
private readonly Dictionary sensorValues;
public MarkupParser(Dictionary sensorValues)
{
this.sensorValues = sensorValues ?? new Dictionary();
}
///
/// Processes sensor variables in markup
///
public string ProcessVariables(string markup)
{
if (string.IsNullOrEmpty(markup))
return string.Empty;
// Replace variables with actual values
foreach (var sensor in sensorValues)
{
// Look for {variable} syntax in the markup
string variablePattern = $"{{{sensor.Key}}}";
// Format value based on type (integers vs decimals)
string formattedValue;
if (Math.Abs(sensor.Value - Math.Round(sensor.Value)) < 0.01)
{
formattedValue = $"{sensor.Value:F0}";
}
else
{
formattedValue = $"{sensor.Value:F1}";
}
markup = markup.Replace(variablePattern, formattedValue);
}
return markup;
}
///
/// Parses markup and returns a list of preview elements
///
public List ParseMarkup(string markup)
{
var elements = new List();
if (string.IsNullOrEmpty(markup))
return elements;
// Process variables in the markup first
markup = ProcessVariables(markup);
// Parse text elements - Hello
foreach (Match match in Regex.Matches(markup, @"([^<]*)"))
{
elements.Add(new TextElement
{
X = int.Parse(match.Groups[1].Value),
Y = int.Parse(match.Groups[2].Value),
Size = match.Groups[3].Success ? int.Parse(match.Groups[3].Value) : 1,
Text = match.Groups[4].Value
});
}
// Parse bar elements -
foreach (Match match in Regex.Matches(markup, @""))
{
elements.Add(new BarElement
{
X = int.Parse(match.Groups[1].Value),
Y = int.Parse(match.Groups[2].Value),
Width = int.Parse(match.Groups[3].Value),
Height = int.Parse(match.Groups[4].Value),
Value = int.Parse(match.Groups[5].Value)
});
}
// Parse rect elements -
foreach (Match match in Regex.Matches(markup, @""))
{
elements.Add(new RectElement
{
X = int.Parse(match.Groups[1].Value),
Y = int.Parse(match.Groups[2].Value),
Width = int.Parse(match.Groups[3].Value),
Height = int.Parse(match.Groups[4].Value),
Filled = false
});
}
// Parse box elements -
foreach (Match match in Regex.Matches(markup, @""))
{
elements.Add(new RectElement
{
X = int.Parse(match.Groups[1].Value),
Y = int.Parse(match.Groups[2].Value),
Width = int.Parse(match.Groups[3].Value),
Height = int.Parse(match.Groups[4].Value),
Filled = true
});
}
// Parse line elements -
foreach (Match match in Regex.Matches(markup, @""))
{
elements.Add(new LineElement
{
X1 = int.Parse(match.Groups[1].Value),
Y1 = int.Parse(match.Groups[2].Value),
X2 = int.Parse(match.Groups[3].Value),
Y2 = int.Parse(match.Groups[4].Value)
});
}
// Parse icon elements -
foreach (Match match in Regex.Matches(markup, @""))
{
elements.Add(new IconElement
{
X = int.Parse(match.Groups[1].Value),
Y = int.Parse(match.Groups[2].Value),
Name = match.Groups[3].Value
});
}
return elements;
}
///
/// Creates an example OLED markup using available sensors
///
public static string CreateExampleMarkup(SensorManager sensorManager)
{
StringBuilder markup = new StringBuilder();
string cpuLoad = sensorManager.FindFirstSensorOfType(HardwareType.Cpu, SensorType.Load);
string cpuTemp = sensorManager.FindFirstSensorOfType(HardwareType.Cpu, SensorType.Temperature);
string gpuLoad = sensorManager.FindFirstSensorOfType(HardwareType.GpuNvidia, SensorType.Load);
string gpuTemp = sensorManager.FindFirstSensorOfType(HardwareType.GpuNvidia, SensorType.Temperature);
string ramUsed = sensorManager.FindFirstSensorOfType(HardwareType.Memory, SensorType.Data);
markup.AppendLine("System Monitor");
if (!string.IsNullOrEmpty(cpuLoad) && !string.IsNullOrEmpty(cpuTemp))
{
markup.AppendLine($"CPU: {{{cpuLoad}}}% ({{{cpuTemp}}}°C)");
markup.AppendLine($"");
}
else if (!string.IsNullOrEmpty(cpuLoad))
{
markup.AppendLine($"CPU: {{{cpuLoad}}}%");
markup.AppendLine($"");
}
if (!string.IsNullOrEmpty(gpuLoad) && !string.IsNullOrEmpty(gpuTemp))
{
markup.AppendLine($"GPU: {{{gpuLoad}}}% ({{{gpuTemp}}}°C)");
markup.AppendLine($"");
}
else if (!string.IsNullOrEmpty(gpuLoad))
{
markup.AppendLine($"GPU: {{{gpuLoad}}}%");
markup.AppendLine($"");
}
if (!string.IsNullOrEmpty(ramUsed))
{
markup.AppendLine($"RAM: {{{ramUsed}}} GB");
}
return markup.ToString();
}
}
}