package ac.essex.ooechs.ecj.ecj2java.nodes;

import ec.gp.GPNode;
import ec.gp.GPIndividual;
import ec.EvolutionState;
import ec.util.Parameter;

/**
 * <p>
 * An abstract class which allows us to save a node and run it again at a later time.
 * It is able to interface the GP node class with the parseableNode class. The only code
 * that your GP code needs to make is to add the "getJavaCode()" function to your class and
 * implement this abstract class.
 * </p>
 *
 * <p/>
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version,
 * provided that any use properly credits the author.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details at http://www.gnu.org
 * </p>
 *
 * @author Olly Oechsle, University of Essex, Date: 05-Sep-2006
 * @version 1.0
 */

public abstract class ParseableGPNode extends GPNode implements ParseableNode {

    /** The amount of children this node is SUPPOSED to have **/
    int numChildren;

    /** The type of node - Terminal, Function or ERC - used by the JavaWriter **/
    int type;

    /** The name of this node - text is used by the GPNode's toString function **/
    String text;

    /**
     * Initialises the GP node and sets the type as a function.
     * @param text
     * @param numChildren
     */
    public ParseableGPNode(String text, int numChildren) {
        this(text, numChildren, ParseableNode.FUNCTION);
    }


    public ParseableGPNode(String text, int numChildren, int type) {
        this.numChildren = numChildren;
        this.text = text;
        this.type = type;
        variableName = "";
    }

    public void checkConstraints(final EvolutionState state, final int tree, final GPIndividual typicalIndividual, final Parameter individualBase) {
        super.checkConstraints(state, tree, typicalIndividual, individualBase);
        if (children.length != numChildren)
            state.output.error("Incorrect number of children for node " + toStringForError() + " at " + individualBase + " (" + children.length + " != " + numChildren + ")");
    }

    /**
     * Returns a string representation of the java statement represented by this node.
     */
    public abstract String getJavaCode();

    public String getEndJavaCode() {
        return "";
    }

    public String toString() {
        return text;
    }

    public ParseableNode getChild(int index) {
        return (ParseableNode) children[index];
    }

    public int countChildren() {
        return children.length;
    }

    String variableName;

    /**
     * When the java writer uses this node, it may use a variable name to describe it.
     */
    public String getVariableName() {
        return variableName;
    }
    /**
     * Attaches a variable name to this node, used by JavaWriter
     */
    public void setVariableName(String name) {
        this.variableName = name;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getValue() {
        return null;
    }

    public abstract int getObjectType();

    public String getLineComment() {
        return null;
    }

}

