using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IRIGCh10
{
///
/// this is the base class for sections in the TMATS document
/// each section is made of a bunch of attributes and values
///
///
public abstract class TMATSSection where T : Enum
{
private Dictionary _values = new Dictionary();
///
/// Sets the given tag to a given value
///
///
///
public void SetValue(T tag, string value) => _values[tag] = value;
///
/// returns given value for a given tag
/// value will be null if value was never set
///
///
///
public string GetValue(T tag) => _values.ContainsKey(tag)?_values[tag]: null;
///
/// sets a given tag to a given date, or an empty string if date is null
///
///
///
public void SetDate(T tag, DateTime? value)
{
if (null == value)
{
SetValueWithLength(tag, string.Empty);
}
var dt = (DateTime) value;
SetValueWithLength(tag, $"{dt.Month:00}-{dt.Day:00}-{dt.Year:0000}");
}
///
/// gets a date for a tag, or null if date isn't set
///
///
///
public DateTime? GetDate(T tag)
{
var value = GetValue(tag);
if( string.IsNullOrWhiteSpace(value) ){ return null; }
if (DateTime.TryParseExact(value, "MM-DD-YYYY", System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.None,
out var dt))
{
return dt;
}
return null;
}
///
/// gets a int value for tag, or null if tag was never set
///
///
///
public int? GetIntOrNull(T tag)
{
var val = GetValue(tag);
if( string.IsNullOrWhiteSpace(val)){ return null; }
if (int.TryParse(val, out var iTmp))
{
return iTmp;
}
return null;
}
///
/// sets tag value
///
///
///
public void SetIntOrNull(T tag, int? val)
{
if (null == val)
{
SetValueWithLength(tag, string.Empty);
}
else
{
SetValueWithLength(tag, ((int) val).ToString());
}
}
///
/// originally designed to check the length of values against the max length in spec
/// however no longer checks length as max length is just a suggestion in the spec...
///
///
///
public void SetValueWithLength(T tag, string value)
{
var maxLength = MaxLengthDecoder.GetMaxLength(tag);
//apprently maxlength is just a suggestion ...
//if (maxLength < value.Length)
//{
// throw new FormatException($"{tag.ToString()} must be {maxLength} characters or less");
//}
SetValue(tag, value);
}
///
/// returns all fields in the section for the tmats document
///
///
public virtual string Serialize()
{
var tags = Enum.GetValues(typeof(T)).Cast().ToArray();
var sb = new StringBuilder();
foreach (var tag in tags)
{
var s = Serialize(tag);
if( string.IsNullOrWhiteSpace(s)){ continue; }
sb.AppendLine(s);
}
return sb.ToString();
}
///
/// some attributes have to be associated with a number, like P-x\N:1 where x is
/// the channel number, this keeps track of the number for all attributes
///
private int _number = -1;
private AttributeIdentifiers _attribute = AttributeIdentifiers.GeneralInformation;
///
/// serializes just one tag/value to a string
///
///
///
protected string Serialize(T tag)
{
var value = GetValue(tag);
if( string.IsNullOrWhiteSpace(value)){ return null; }
var attrib = DescriptionDecoder.GetDescription(tag);
var attributeIdentifier = DescriptionDecoder.GetDescription(_attribute);
if (_number < 0)
{
return $"{attributeIdentifier}\\{attrib}:{value};";
}
return $"{attributeIdentifier}-{_number}\\{attrib}:{value};";
}
///
/// generic constructor for attributes which don't need to be associated with a number,
/// like General Information
///
public TMATSSection()
{
}
///
/// constructor for attributes that are associated with a specific number, like PCM
/// being associated with a channel number
///
///
///
public TMATSSection(AttributeIdentifiers attribute, int number)
{
_attribute = attribute;
_number = number;
}
}
}