package ec.app.semanticGP.func;

import java.util.*;

import ec.*;
import ec.gp.*;
import ec.gp.semantic.*;
import ec.gp.semantic.evaluation.*;
import ec.gp.semantic.func.*;

public abstract class CombinerBase<DataType> extends SimpleNodeBase<DataType> {

	protected final HashMap<EvaluationMode, ISemantics> semantics = new HashMap<EvaluationMode, ISemantics>(2);
	protected final int firstRandomTree;

	public CombinerBase(EvolutionState state, SimpleNodeBase<DataType> parent1, SimpleNodeBase<DataType> parent2,
						SimpleNodeBase<DataType> randomTree) {
		this(state, new SimpleNodeBase[]{parent1, parent2}, new SimpleNodeBase[]{randomTree});
	}

	public CombinerBase(EvolutionState state, SimpleNodeBase[] parents, SimpleNodeBase[] randomTrees) {
		assert (1 << randomTrees.length) >= parents.length : "Number of randomTrees should be ceil(log2(parents))";

		this.state = state;
		this.children = new GPNode[parents.length + randomTrees.length];
		System.arraycopy(parents, 0, this.children, 0, parents.length);
		System.arraycopy(randomTrees, 0, this.children, parents.length, randomTrees.length);
		this.firstRandomTree = parents.length;
	}

	@Override
	public DataType[] invert(DataType output, int missingArgIdx, DataType... restOfArguments) {
		throw new UnsupportedOperationException("Not implemented");
	}

	@Override
	public void resetSemantics() {
		// empty
	}

	@Override
	public void resetSemanticsRecursive() {
		// empty
	}

	@Override
	public void resetNode(EvolutionState state, int thread) {
		// empty
	}

	@Override
	public Object clone() {
		return this;
	}

	@Override
	public GPNode lightClone() {
		return this;
	}

	@Override
	protected ISemantics execute(ISemantics... arguments) {
		throw new UnsupportedOperationException("Use getSemantics() instead");
	}

	@Override
	public boolean isSymmetric() {
		return false;
	}

	@Override
	public String toString() {
		return "combiner";
	}

}
