using System.Collections.Generic;
using Vellum;
namespace Clave.Vellum
{
///
/// Saves and loads a list of chords with their priorities and enabled states, the way every chord holder here does.
///
public static class SavedChords
{
private struct Entry
{
public SavedChord Saved;
public SaveNode Formula;
public string FormulaText;
}
private static string TextOf(SaveNode formula)
{
var terms = new List(formula.Items.Count);
foreach (SaveNode term in formula.Items)
{
terms.Add(term.Text);
}
return string.Join("\n", terms);
}
// Highest priority first, then by formula, so the same chords save the same whatever order they were added in.
private static int Compare(Entry first, Entry second)
{
if (first.Saved.Priority != second.Saved.Priority)
{
return second.Saved.Priority.CompareTo(first.Saved.Priority);
}
int byFormula = string.CompareOrdinal(first.FormulaText, second.FormulaText);
if (byFormula != 0)
{
return byFormula;
}
return second.Saved.Enabled.CompareTo(first.Saved.Enabled);
}
///
/// Returns a table holding the chords as a list, highest priority first and then by formula. A holder with
/// more to save adds its own entries to it.
///
public static SaveNode Write(IReadOnlyList chords, SaveSession session)
{
var entries = new List(chords.Count);
foreach (SavedChord saved in chords)
{
SaveNode formula = session.ToNode(saved.Chord, typeof(Chord));
entries.Add(new Entry { Saved = saved, Formula = formula, FormulaText = TextOf(formula) });
}
entries.Sort(Compare);
SaveNode list = SaveNode.NewList();
foreach (Entry entry in entries)
{
SaveNode node = SaveNode.NewTable();
node.Entries[ChordSetConverter.ChordKey] = entry.Formula;
node.Entries[ChordSetConverter.PriorityKey] = session.ToNode(entry.Saved.Priority);
node.Entries[ChordSetConverter.EnabledKey] = session.ToNode(entry.Saved.Enabled);
list.Items.Add(node);
}
SaveNode returnMe = SaveNode.NewTable();
returnMe.Entries[ChordSetConverter.ChordsKey] = list;
return returnMe;
}
///
/// Returns the chords of a table that made, in the order saved. A chord with no priority
/// has zero, and one with no enabled state is enabled.
///
public static List Read(SaveNode node, SaveSession session)
{
IReadOnlyList saved = node.RequireEntry(ChordSetConverter.ChordsKey).RequireItems();
new SaveReader(node, session).Skip(ChordSetConverter.ChordsKey);
var returnMe = new List(saved.Count);
for (int i = 0; i < saved.Count; ++i)
{
var reader = new SaveReader(saved[i], session);
Chord chord = reader.Require(ChordSetConverter.ChordKey);
int priority;
reader.TryRead(ChordSetConverter.PriorityKey, out priority);
bool enabled;
if (!reader.TryRead(ChordSetConverter.EnabledKey, out enabled))
{
enabled = true;
}
returnMe.Add(new SavedChord(chord, priority, enabled));
}
return returnMe;
}
///
/// Lists the chords of a table that made as children, and returns false if it isn't one.
///
public static bool TryListChildren(SaveNode node, ChildList children)
{
SaveNode chords;
IReadOnlyList entries;
if (!node.TryGetEntry(ChordSetConverter.ChordsKey, out chords) || !chords.TryGetItems(out entries))
{
return false;
}
foreach (SaveNode entry in entries)
{
SaveNode chord;
if (!entry.TryGetEntry(ChordSetConverter.ChordKey, out chord))
{
return false;
}
children.Add(chord, typeof(Chord));
}
return true;
}
}
}