/*
 * TreeNormalize.h
 *
 *  Created on: Mar 31, 2017
 *      Author: Jan Travnicek
 */

#ifndef TREE_NORMALIZE_H_
#define TREE_NORMALIZE_H_

#include <alib/tree>

#include <common/ranked_symbol.hpp>
#include <alphabet/common/SymbolNormalize.h>

namespace tree {

/**
 * This class contains methods to print XML representation of automata to the output stream.
 */
class TreeNormalize {
public:
	template < class SymbolType >
	static ext::tree < DefaultSymbolType > normalizeTree ( ext::tree < SymbolType > && tree );

	template < class SymbolType >
	static ext::tree < common::ranked_symbol < DefaultSymbolType > > normalizeRankedTree ( ext::tree < common::ranked_symbol < SymbolType > > && tree );

};

template < class SymbolType >
ext::tree < DefaultSymbolType > TreeNormalize::normalizeTree ( ext::tree < SymbolType > && tree ) {
	ext::vector < ext::tree < DefaultSymbolType > > children;

	for ( ext::tree < SymbolType > & child : tree.getChildren ( ) ) {
		children.push_back ( normalizeTree ( std::move ( child ) ) );
	}

	return ext::tree < DefaultSymbolType > ( alphabet::SymbolNormalize::normalizeSymbol ( std::move ( tree.getData ( ) ) ), std::move ( children ) );
}

template < class SymbolType >
ext::tree < common::ranked_symbol < DefaultSymbolType > > TreeNormalize::normalizeRankedTree ( ext::tree < common::ranked_symbol < SymbolType > > && tree ) {
	ext::vector < ext::tree < common::ranked_symbol < DefaultSymbolType > > > children;

	for ( ext::tree < common::ranked_symbol < SymbolType > > & child : tree.getChildren ( ) ) {
		children.push_back ( normalizeRankedTree ( std::move ( child ) ) );
	}

	return ext::tree < common::ranked_symbol < DefaultSymbolType > > ( alphabet::SymbolNormalize::normalizeRankedSymbol ( std::move ( tree.getData ( ) ) ), std::move ( children ) );
}

} /* namespace tree */

#endif /* TREE_NORMALIZE_H_ */

