using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RuriLib.LS
{
///
/// Provides useful functions for writing a block as a piece of LoliScript code.
///
public class BlockWriter : StringWriter
{
private bool Indented { get; set; }
private Type Type { get; set; }
private object Block { get; set; }
private bool Disabled { get; set; }
///
/// Creates a new BlockWriter for the given block type and with the given settings.
///
/// The Type of the block to write
/// Whether the code can be indented on multiple lines for readability
/// Whether the block to write is disabled
public BlockWriter(Type blockType, bool indented = true, bool disabled = false)
{
Type = blockType;
Block = Activator.CreateInstance(blockType);
Indented = indented;
Disabled = disabled;
if (Disabled) Write("!");
}
///
/// Writes any type of variable as a token (by calling its default ToString method) and a space.
///
/// The variable to write
/// The name of the property of the block. If the value is the default one, it will not be written. Do not set this parameter to always write the variable.
/// The BlockWriter itself
public BlockWriter Token(dynamic token, string property = "")
{
if (property != "" && CheckDefault(token, property)) return this;
Write($"{token.ToString()} ");
return this;
}
///
/// Writes an integer value and a space.
///
/// The integer value to write
/// The name of the property of the block. If the value is the default one, it will not be written. Do not set this parameter to always write the variable.
/// The BlockWriter itself
public BlockWriter Integer(int integer, string property = "")
{
if (property != "" && CheckDefault(integer, property)) return this;
Write($"{integer} ");
return this;
}
///
/// Writes a literal value (with escaped double-quotes) wrapped by double-quotes and a space.
///
/// The literal value to write
/// The name of the property of the block. If the value is the default one, it will not be written. Do not set this parameter to always write the variable.
/// The BlockWriter itself
public BlockWriter Literal(string literal, string property = "")
{
if (property != "" && CheckDefault(literal, property)) return this;
Write($"\"{literal.Replace("\\", "\\\\").Replace("\"", "\\\"")}\" ");
return this;
}
///
/// Writes an Arrow (->) and a space.
///
/// The BlockWriter itself
public BlockWriter Arrow()
{
Write("-> ");
return this;
}
///
/// Writes a block label as a # sign, the label name and a space.
///
/// The label of the block
/// The BlockWriter itself
public BlockWriter Label(string label)
{
if (CheckDefault(label, "Label")) return this;
Write($"#{label.Replace(" ", "_")} ");
return this;
}
///
/// Writes a boolean with the syntax Name=Value and a space.
///
/// The boolean value to write
/// The name of the property
///
public BlockWriter Boolean(bool boolean, string property)
{
if (property != "" && CheckDefault(boolean, property)) return this;
Write($"{property}={boolean.ToString().ToUpper()} ");
return this;
}
///
/// Writes a linebreak and a given number of spaces on the next line.
///
/// The amount of spacing to perform. A spacing of value 1 means two blank space characters, 2 means 4 etc.
///
public BlockWriter Indent(int spacing = 1)
{
if (Indented)
{
WriteLine();
if (Disabled) Write("!");
for (var i = 0; i < spacing; i++)
Write(" ");
}
return this;
}
///
/// Writes a linebreak.
///
///
public BlockWriter Return()
{
WriteLine();
return this;
}
///
/// Checks if a property has the default value.
///
/// The value that needs to be checked
/// The name of the property that contains that value
/// Whether the property has the default value or not
public bool CheckDefault(object value, string property)
{
var prop = Type.GetProperty(property);
var val = prop.GetValue(Block);
return value.Equals(val);
}
}
}