package com.hammurapi.extract;


/**
 * Extractor which maps arguments to the target extractor.
 * @author Pavel Vlasov
 *
 * @param <T>
 * @param <V>
 * @param <C>
 */
public class MappedPredicate<T, C> extends MappedExtractor<T, Boolean, C> implements Predicate<T, C> {

	/**
	 * @param target Target extractor
	 * @param map Index map, e.g. if it is {5, 3} then the first argument
	 * of this extractor becomes the sixth argument of the target extractor
	 * and the second argument of this extractor becomes the 4th argument
	 * of the target extractor. 
	 */
	protected MappedPredicate(Predicate<T, C> target, int[] map) {
		super(target, map);
	}
	
	public static <T,C> Predicate<T,C> mapPredicate(Predicate<T,C> target, int[] map) {
		if (ComparisonResult.isOneToOneMapping(map)) {
			return target;
		}
		
		// Target is not index-dependent (e.g. constant).
		if (target.parameterIndices().isEmpty()) {
			return target;
		}
		if (target instanceof Mappable) {
			@SuppressWarnings("unchecked")
			Extractor<T, Boolean, C> ret = ((Mappable<T,Boolean,C>) target).map(map);
			if (ret!=null) {
				return ExtractorUtil.wrap(ret);
			}
		}
		
		return new MappedPredicate<T, C>(target, map);
	}
	

}
