package ec.app.semanticGP.func.logic;

import library.semantics.BitSet;
import ec.gp.GPNode;
import ec.gp.semantic.BooleanSemantics;
import ec.gp.semantic.ISemantics;
import ec.gp.semantic.func.BinaryNode;
import ec.gp.semantic.func.SimpleNodeBase;

public class Averager extends BinaryNode<Boolean> {

	private boolean constant;
	
	// #ifdef NO_SEMANTICS_CACHE
//@		private ISemantics semantics = null;
	// #endif

	public Averager(SimpleNodeBase<Boolean> child1, SimpleNodeBase<Boolean> child2, boolean constant) {
		this.children = new GPNode[] { child1, child2 };
		this.constant = constant;
	}

	// #ifdef NO_SEMANTICS_CACHE
//@		
//@		@Override
//@		public ISemantics getSemantics() {
//@			if (this.semantics == null) {
//@				ISemantics child0Sem = ((SimpleNodeBase<?>)children[0]).getSemantics();
//@				ISemantics child1Sem = ((SimpleNodeBase<?>)children[1]).getSemantics();
//@				
//@				this.semantics = this.execute(child0Sem, child1Sem);
//@			}
//@			
//@			return this.semantics;
//@		}
//@	
//@		@Override
//@		public void resetSemantics() {
//@			this.semantics = null;
//@		}
//@	
	// #endif

	@Override
	public boolean isSymmetric() {
		return false;
	}
	
	@Override
	protected ISemantics execute(ISemantics... arguments) {
		int length = ((BitSet)arguments[0].getValue()).length();
		
		BitSet constant = new BitSet();
		constant.set(0, length, this.constant);
		
		BitSet semantics1 = (BitSet) ((BitSet) arguments[0].getValue()).clone();
		semantics1.and(constant);
		
		BitSet semantics2 = (BitSet) ((BitSet) arguments[1].getValue()).clone();
		semantics2.andNot(constant);
		
		semantics1.or(semantics2);
		return new BooleanSemantics(semantics1);
	}
	
	@Override
	public Boolean[] invert(Boolean output, int missingArgIdx, Boolean... restOfArguments) {
		throw new UnsupportedOperationException("Not implemented");
	}

	@Override
	public String toString() {
		return String.format("and %d or %d and", this.constant ? 1 : 0, this.constant ? 0 : 1);
	}

}
