using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace FSO.Common.Utils
{
///
/// In:
/// - String Containing BBCode
///
/// [color=red]Hello![/color]
/// [color=#FF0000]Also [size=20]red[/size][/color]
/// \[ escaped \] square brackets.
///
/// Out:
/// - String Without BBCode
/// - Ordered list of BBCodeCommands, and the index in the converted string they occur at.
///
public class BBCodeParser
{
public string Stripped;
public List Commands = new List();
public BBCodeParser(string input)
{
var stripped = new StringBuilder();
int index = 0;
while (index < input.Length)
{
var newIndex = input.IndexOf('[', index);
if (newIndex == -1)
{
newIndex = input.Length;
//no more commands.
//render the rest of the string and break out.
stripped.Append(input.Substring(index, newIndex - index));
break;
}
stripped.Append(input.Substring(index, newIndex - index));
//we found the start of a bbcode. is it escaped?
if (newIndex > 0 && input[newIndex - 1] == '\\')
{
//draw the bracket.
stripped[stripped.Length - 1] = '['; //replace the backslash with the leftbracket
index = newIndex + 1; //continue after the bracket
} else
{
//find our right bracket
var endIndex = input.IndexOf(']', newIndex);
if (endIndex == -1)
{
//fail safe.
stripped.Append('[');
index = newIndex + 1; //continue after the bracket
} else
{
Commands.Add(new BBCodeCommand(input.Substring(newIndex + 1, (endIndex - newIndex) - 1), stripped.Length));
index = endIndex + 1;
}
}
}
Stripped = stripped.ToString();
}
public static string SanitizeBB(string input)
{
if (input.LastOrDefault() == '\\') input += ' ';
return input.Replace("[", "\\[");
}
}
public class BBCodeCommand
{
public BBCodeCommandType Type;
public string Parameter;
public int Index;
public bool Close;
public BBCodeCommand(string cmd, int index)
{
Index = index;
if (cmd[0] == '/')
{
Close = true;
cmd = cmd.Substring(1);
}
var split = cmd.Split('=');
if (split.Length > 1) Parameter = split[1];
System.Enum.TryParse(split[0], out Type);
}
public Color ParseColor()
{
if (Parameter == null || Parameter.Length == 0) return Color.White;
//todo: search color static members for named colours
//for now we only support hex
if (Parameter.Length == 7 && Parameter[0] == '#')
{
uint rgb;
if (uint.TryParse(Parameter.Substring(1), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out rgb)) {
return new Color((byte)(rgb >> 16), (byte)(rgb >> 8), (byte)(rgb), (byte)255);
}
} else
{
var color = typeof(Color).GetProperties().Where(x => x.PropertyType == typeof(Color) && x.Name.ToLowerInvariant() == Parameter.ToLowerInvariant()).FirstOrDefault();
if (color != null)
{
return (Color)color.GetValue(null);
}
}
return Color.White;
}
}
public enum BBCodeCommandType
{
unknown,
color,
size,
emoji,
s
}
}