import com.sun.sgs.app.*;
import java.io.Serializable;

/**
 * @author Jeff Kesselman
 */
public abstract class InOrderTreeNode implements Serializable, ManagedObject,
    Task
{

    protected abstract void preDescentEvaluation();

    protected abstract InOrderTreeNode nextChild(Object object);

    protected abstract void postDescentEvaluation(); 

    public static final long SerialVersionUID = 1L;
    ManagedReference parentRef;
    
    public InOrderTreeNode(InOrderTreeNode parent){
        if (parent != null ){
            parentRef = AppContext.getDataManager().createReference(parent);
        }
        
    }
    
    public void evaluate(){
        preDescentEvaluation();
        doNextChild(null);
    }
    
    private void doNextChild(InOrderTreeNode lastChild) {
        InOrderTreeNode child = nextChild(lastChild);
        if (child == null) { // done with children
            postDescentEvaluation();
            if (!isRoot()){
                parentRef.get(InOrderTreeNode.class).doNextChild(this);
            }
        } else {
            AppContext.getTaskManager().scheduleTask(child);
        }
    }
    
    public boolean isRoot(){
        return parentRef == null;
    }
    
    public void run(){
        evaluate();
    }

    
    
}
