/*
 * StringToXmlComposerCommon.h
 *
 *  Created on: Nov 23, 2013
 *      Author: Jan Travnciek
 */

#pragma once

#include <alib/deque>
#include <sax/Token.h>
#include <alib/set>
#include <alib/vector>
#include <core/xmlApi.hpp>

namespace string {

/**
 * This class contains methods to print Xml representation of string to the output stream.
 */
class StringToXmlComposerCommon {
public:
	template < class SymbolType >
	static void composeAlphabet ( ext::deque < sax::Token > & out, const ext::set < SymbolType > & alphabet );
	template < class SymbolType >
	static void composeContent ( ext::deque < sax::Token > & out, const ext::vector < SymbolType > & content );
    template < class SymbolType >
    static void composeSpecialSymbol ( ext::deque < sax::Token > & out, const std::string & tagName, const SymbolType & symbol );

	template < class SymbolType >
	static void composeWildcard ( ext::deque < sax::Token > & out, const SymbolType & wildcard ) {
        composeSpecialSymbol ( out, "wildcard", wildcard );
    }

    template < class SymbolType >
    static void composeTerminatingSymbol ( ext::deque < sax::Token > & out, const SymbolType & terminatingSymbol ) {
        composeSpecialSymbol ( out, "terminatingSymbol", terminatingSymbol );
    }
};

template < class SymbolType >
void StringToXmlComposerCommon::composeAlphabet ( ext::deque < sax::Token > & out, const ext::set < SymbolType > & alphabet ) {
	out.emplace_back ( "alphabet", sax::Token::TokenType::START_ELEMENT );

	for ( const SymbolType & symbol : alphabet )
		core::xmlApi < SymbolType >::compose ( out, symbol );

	out.emplace_back ( "alphabet", sax::Token::TokenType::END_ELEMENT );
}

template < class SymbolType >
void StringToXmlComposerCommon::composeContent ( ext::deque < sax::Token > & out, const ext::vector < SymbolType > & content ) {
	out.emplace_back ( "content", sax::Token::TokenType::START_ELEMENT );

	for ( const SymbolType & symbol : content )
		core::xmlApi < SymbolType >::compose ( out, symbol );

	out.emplace_back ( "content", sax::Token::TokenType::END_ELEMENT );
}

template < class SymbolType >
void StringToXmlComposerCommon::composeSpecialSymbol ( ext::deque < sax::Token > & out, const std::string & tagName,
                                                       const SymbolType & symbol ) {
	out.emplace_back ( tagName, sax::Token::TokenType::START_ELEMENT );

	core::xmlApi < SymbolType >::compose ( out, symbol );

	out.emplace_back ( tagName, sax::Token::TokenType::END_ELEMENT );
}

} /* namespace string */

