package org.jcon.param.tree;

import org.jcon.util.TNode;

/**
 * Represents a node in a data hierarchy. Subclasses are a
 * particular subsystem such as those defining a Param.
 *
 * @author Jack Harich
 */
public abstract class Datum {

//---------- Private Fields ------------------------------
protected TNode         node = new TNode(this);
protected String        myName; // null if none
protected DatumContext  context;

//---------- Abstract Methods ----------------------------
public abstract boolean isLeaf();

// The text to be displayed in the tree
public abstract String toString();

// An extensible approach, better than (String command)
public abstract void performCommand(DatumCommand command);

//---------- Properties ----------------------------------
/**
 * Sets the context for the Datum. This need only be done
 * for the root, since setParentDatum() automatically sets
 * the datum's context to its parent's. This way the entire
 * tree has the same context with a minimum of fuss.
 */
public void setDatumContext(DatumContext context) {
    this.context = context;
}
//----- myName
public void setName(String myName) {
    this.myName = myName;
}
/**
 * Returns the name displayed or null if none. Not all
 * Datums have a name, such as a line or element.
 */
public String getName() {
    return myName;
}
//----- Parent
public void setParentDatum(Datum parentDatum) {
    node.removeFromTree();
    if (parentDatum != null) {
        parentDatum.getNode().add(node);
        context = parentDatum.context;
    }
}
public Datum getParentDatum() {
    TNode parentNode = node.getParentNode();
    if (parentNode == null) {
        return null;
    } else {
        return (Datum)parentNode.getUserObject();
    }
}
//----- Node related
public TNode getNode() {
    return node;
}
public TNode getRootNode() {
    return node.getRootNode();
}
public boolean isRoot() {
    return (node.getParentNode() == null ? true : false);
}
public Datum getRootDatum() {
    return (Datum)getRootNode().getUserObject();
}
/**
 * Returns a period delimited path of datum names. This
 * starts at the root if includeRoot is true. otherwise
 * starts at this Datum.
 */
public String getNamePath(boolean includeRoot) {
    String path = "";
    TNode[] nodes = node.getPathNodes();
    int first = (includeRoot ? 0 : 1);
    for (int i = first; i < nodes.length; i++) {
        if (i > first) path += ".";
        Datum datum = (Datum)nodes[i].getUserObject();
        path += datum.getName(); // "null" if null
    }
    return path;
}
public void removeFromTree() {
    node.removeFromTree();
}
//---------- Public Methods ------------------------------



//---------- Private Methods -----------------------------
//--- Std
private static void print(String text) {
    System.out.println("Datum" + text);
}

} // End class
