package ec.gp.semantic.utils;

import ec.app.semanticGP.func.classification.Cn;
import ec.app.semanticGP.func.classification.If;
import ec.app.semanticGP.func.classification.Neq;
import ec.gp.GPNode;
import ec.gp.semantic.func.SimpleNodeBase;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Tomasz Pawlak
 */
public class ClassifierInstructionJoiner {

    public static SimpleNodeBase<?> join(List<SimpleNodeBase<?>> toJoin) {
        assert toJoin.size() > 0;
        try {
            while (toJoin.size() > 1) {
                assert toJoin.size() >= 2 : "Number of elements in toJoin is not dividable by 2";

                List<SimpleNodeBase<?>> newList = new ArrayList<SimpleNodeBase<?>>();

                SimpleNodeBase<?> top = null;
                int chIndex = 0;

                for (int i = 0; i < toJoin.size() - toJoin.size() % 2; ++i) {
                    if (top == null) {
                        top = new If();
                        top.children = new GPNode[3];
                        top.children[0] = new Neq();
                        top.children[0].children = new GPNode[]{toJoin.get(i), Cn.get(Cn.UNKNOWN_CLASS)};
                        chIndex = 1;
                    }

                    top.children[chIndex++] = toJoin.get(i);

                    if (chIndex >= top.children.length) {
                        newList.add(top);
                        top = null;
                    }
                }

                for (int i = toJoin.size() - toJoin.size() % 2; i < toJoin.size(); ++i) {
                    newList.add(toJoin.get(i));
                }

                toJoin = newList;
            }


            return toJoin.iterator().next();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
