using System;
using System.Collections.Generic;
using System.Text;
namespace mustache
{
///
/// Builds text by combining the output of other generators.
///
internal sealed class CompoundGenerator : IGenerator
{
private readonly TagDefinition _definition;
private readonly ArgumentCollection _arguments;
private readonly LinkedList _primaryGenerators;
private IGenerator _subGenerator;
///
/// Initializes a new instance of a CompoundGenerator.
///
/// The tag that the text is being generated for.
/// The arguments that were passed to the tag.
public CompoundGenerator(TagDefinition definition, ArgumentCollection arguments)
{
_definition = definition;
_arguments = arguments;
_primaryGenerators = new LinkedList();
}
///
/// Adds the given generator.
///
/// The generator to add.
public void AddGenerator(IGenerator generator)
{
addGenerator(generator, false);
}
///
/// Adds the given generator, determining whether the generator should
/// be part of the primary generators or added as an secondary generator.
///
/// The tag that the generator is generating text for.
/// The generator to add.
public void AddGenerator(TagDefinition definition, IGenerator generator)
{
bool isSubGenerator = _definition.ShouldCreateSecondaryGroup(definition);
addGenerator(generator, isSubGenerator);
}
///
/// Creates a StaticGenerator from the given value and adds it.
///
/// The static generators to add.
public void AddStaticGenerators(IEnumerable generators)
{
foreach (StaticGenerator generator in generators)
{
LinkedListNode node = _primaryGenerators.AddLast(generator);
generator.Node = node;
}
}
private void addGenerator(IGenerator generator, bool isSubGenerator)
{
if (isSubGenerator)
{
_subGenerator = generator;
}
else
{
_primaryGenerators.AddLast(generator);
}
}
string IGenerator.GetText(IFormatProvider provider, KeyScope scope)
{
StringBuilder builder = new StringBuilder();
Dictionary arguments = _arguments.GetArguments(scope);
IEnumerable scopes = _definition.GetChildScopes(scope, arguments);
LinkedList generators;
if (_definition.ShouldGeneratePrimaryGroup(arguments))
{
generators = _primaryGenerators;
}
else
{
generators = new LinkedList();
if (_subGenerator != null)
{
generators.AddLast(_subGenerator);
}
}
foreach (KeyScope childScope in scopes)
{
foreach (IGenerator generator in generators)
{
builder.Append(generator.GetText(provider, childScope));
}
}
string innerText = builder.ToString();
string outerText = _definition.Decorate(provider, innerText, arguments);
return outerText;
}
}
}