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

#ifndef _XML_UNBOUNDED_REGEXP_H_
#define _XML_UNBOUNDED_REGEXP_H_

#include <regexp/unbounded/UnboundedRegExp.h>
#include <regexp/xml/UnboundedRegExpStructure.h>
#include <core/xmlApi.hpp>

#include <regexp/xml/common/RegExpFromXmlParser.h>
#include <regexp/xml/common/RegExpToXmlComposer.h>

namespace core {

template < typename SymbolType >
struct xmlApi < regexp::UnboundedRegExp < SymbolType > > {
	static regexp::UnboundedRegExp < 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 regexp::UnboundedRegExp < SymbolType > & input );
};

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

	ext::set < SymbolType > alphabet = regexp::RegExpFromXmlParser::parseAlphabet < SymbolType > ( input );

	regexp::UnboundedRegExpStructure < SymbolType > structure ( core::xmlApi < regexp::UnboundedRegExpStructure < SymbolType > >::parse ( input ) );
	regexp::UnboundedRegExp < SymbolType > regexp ( std::move ( alphabet ), std::move ( structure ) );

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

	return regexp;
}

template < typename SymbolType >
bool xmlApi < regexp::UnboundedRegExp < 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 < regexp::UnboundedRegExp < SymbolType > >::xmlTagName ( ) {
	return "UnboundedRegExp";
}

template < typename SymbolType >
void xmlApi < regexp::UnboundedRegExp < SymbolType > >::compose ( ext::deque < sax::Token > & output, const regexp::UnboundedRegExp < SymbolType > & input ) {
	output.emplace_back ( xmlTagName(), sax::Token::TokenType::START_ELEMENT );
	regexp::RegExpToXmlComposer::composeAlphabet ( output, input.getAlphabet ( ) );
	core::xmlApi < regexp::UnboundedRegExpStructure < SymbolType > >::compose ( output, input.getRegExp ( ) );
	output.emplace_back ( xmlTagName(), sax::Token::TokenType::END_ELEMENT );
}

} /* namespace core */

#endif /* _XML_UNBOUNDED_REGEXP_H_ */
