/*
 * Map.h
 *
 * Created on: Apr 1, 2013
 * Author: Jan Travnicek
 */

#ifndef _XML_OBJECTS_MAP_H_
#define _XML_OBJECTS_MAP_H_

#include <alib/map>
#include <core/xmlApi.hpp>
#include <container/xml/ObjectsPair.h>

namespace core {

template < typename T, typename R >
struct xmlApi < ext::map < T, R > > {
	static ext::map < T, R > 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 ext::map < T, R > & input );
};

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

	ext::map < T, R > map;

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		map.insert ( core::xmlApi < ext::pair < T, R > >::parse ( input ) );

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

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

template < typename T, typename R >
std::string xmlApi < ext::map < T, R > >::xmlTagName ( ) {
	return "Map";
}

template < typename T, typename R >
void xmlApi < ext::map < T, R > >::compose ( ext::deque < sax::Token > & output, const ext::map < T, R > & input ) {
	output.emplace_back ( xmlTagName ( ), sax::Token::TokenType::START_ELEMENT );

	for ( const std::pair < const T, R > & item : input )
		core::xmlApi < std::pair < const T, R > >::compose ( output, item );

	output.emplace_back ( xmlTagName ( ), sax::Token::TokenType::END_ELEMENT );
}

} /* namespace core */

#endif /* _XML_OBJECTS_MAP_H_ */
