/*
 * FirstVariableOffsetFront.h
 *
 *  Created on: 5. 11. 2014
 *      Author: Jan Travnicek
 */

#pragma once

#include <tree/ranked/PrefixRankedPattern.h>
#include <tree/ranked/PrefixRankedNonlinearPattern.h>
#include <tree/ranked/PrefixRankedBarPattern.h>
#include <tree/ranked/PrefixRankedBarNonlinearPattern.h>

namespace tree {

namespace properties {

class FirstVariableOffsetFront {
public:
	template < class SymbolType >
	static size_t offset ( const tree::PrefixRankedPattern < SymbolType > & pattern );
	template < class SymbolType >
	static size_t offset ( const tree::PrefixRankedNonlinearPattern < SymbolType > & pattern );
	template < class SymbolType >
	static size_t offset ( const tree::PrefixRankedBarPattern < SymbolType > & pattern );
	template < class SymbolType >
	static size_t offset ( const tree::PrefixRankedBarNonlinearPattern < SymbolType > & pattern );

};

template < class SymbolType >
size_t FirstVariableOffsetFront::offset ( const tree::PrefixRankedPattern < SymbolType > & pattern ) {
	return offset ( tree::PrefixRankedNonlinearPattern < SymbolType > ( pattern ) );
}

template < class SymbolType >
size_t FirstVariableOffsetFront::offset ( const tree::PrefixRankedNonlinearPattern < SymbolType > & pattern ) {
	 // find the distance between the beginning of the pattern and the index
	 // of the first symbol representing the variable's bar
	size_t res = pattern.getContent ( ).size ( ) + 1;

	for ( int i = ( int ) pattern.getContent ( ).size ( ) - 1; i >= 0; i-- )
		if ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) )
			res = i;

	return res;
}

template < class SymbolType >
size_t FirstVariableOffsetFront::offset ( const tree::PrefixRankedBarPattern < SymbolType > & pattern ) {
	return offset ( tree::PrefixRankedNonlinearPattern < SymbolType > ( pattern ) );
}

template < class SymbolType >
size_t FirstVariableOffsetFront::offset ( const tree::PrefixRankedBarNonlinearPattern < SymbolType > & pattern ) {
	 // find the distance between the beginning of the pattern and the index
	 // of the first symbol representing the variable's bar
	size_t res = pattern.getContent ( ).size ( ) + 1;

	for ( int i = ( int ) pattern.getContent ( ).size ( ) - 1; i >= 0; i-- )
		if ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) )
			res = i;

	return res;
}

} /* namespace properties */

} /* namespace tree */

