/*
 * FormalRTE.h
 *
 * Created on: Dec 1, 2017
 * Author: Jan Travnicek
 */

#pragma once

#include <rte/formal/FormalRTE.h>
#include <rte/xml/FormalRTEStructure.h>
#include <core/xmlApi.hpp>

#include <rte/xml/common/RTEFromXmlParser.h>
#include <rte/xml/common/RTEToXmlComposer.h>

namespace core {

template < typename SymbolType >
struct xmlApi < rte::FormalRTE < SymbolType > > {
	static rte::FormalRTE < SymbolType > parse ( ext::deque < sax::Token >::iterator & input );
	static bool first ( const ext::deque < sax::Token >::const_iterator & input );
	static std::string xmlTagName ( );
	static void compose ( ext::deque < sax::Token > & output, const rte::FormalRTE < SymbolType > & input );
};

template < typename SymbolType >
rte::FormalRTE < SymbolType > xmlApi < rte::FormalRTE < SymbolType > >::parse ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, xmlTagName ( ) );

	std::pair < ext::set < common::ranked_symbol < SymbolType > >, ext::set < common::ranked_symbol < SymbolType > > > alphabets = rte::RTEFromXmlParser::parseAlphabet < SymbolType > ( input );
	rte::FormalRTEStructure < SymbolType > element ( core::xmlApi < rte::FormalRTEStructure < SymbolType > >::parse ( input ) );
	rte::FormalRTE < SymbolType > rte ( std::move ( alphabets.first ), std::move ( alphabets.second ), std::move ( element ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, xmlTagName ( ) );
	return rte;
}

template < typename SymbolType >
bool xmlApi < rte::FormalRTE < SymbolType > >::first ( const ext::deque < sax::Token >::const_iterator & input ) {
	return sax::FromXMLParserHelper::isToken ( input, sax::Token::TokenType::START_ELEMENT, xmlTagName ( ) );
}

template < typename SymbolType >
std::string xmlApi < rte::FormalRTE < SymbolType > >::xmlTagName ( ) {
	return "FormalRTE";
}

template < typename SymbolType >
void xmlApi < rte::FormalRTE < SymbolType > >::compose ( ext::deque < sax::Token > & output, const rte::FormalRTE < SymbolType > & input ) {
	output.emplace_back ( xmlTagName ( ), sax::Token::TokenType::START_ELEMENT );
	rte::RTEToXmlComposer::composeAlphabet ( output, input.getAlphabet ( ), input.getSubstitutionAlphabet ( ) );
	core::xmlApi < rte::FormalRTEStructure < SymbolType > >::compose ( output, input.getRTE ( ) );
	output.emplace_back ( xmlTagName ( ), sax::Token::TokenType::END_ELEMENT );
}

} /* namespace core */

