import netscape_beta.application.*;
import netscape_beta.util.*;

/**
 * A class representing a traversal.
 *
 * @version        1.0 12 Dec 1996
 * @author         Andrew Miller
 */
public class Traversal
{
    protected TreeNode  m_start = null;
    protected Vector    m_throughlist = new Vector();
    protected Vector    m_bypasslist = new Vector();
    protected Vector    m_endlist = new Vector();
    protected String    m_name = null;

    /**
     * Create a new traversal.
     *
     * @param strName   Traversal name.
     */
    public Traversal(String strName) { m_name = strName; }

    /**
     * Add a start node to a traversal.  Each traversal may 
     * have one start node and traversals must start at 
     * a TreeNode.
     *
     * @param start   Start node.
     */
    public void addStartNode(TreeNode start)
    {
        m_start = start;
    }

    /**
     * Add a through node to a traversal.  Each traversal may 
     * have multiple through nodes which may consist of TreeNodes
     * and TreeEdges.
     *
     * @param through   New through node/edge.
     */
    public void addThroughNode(VisitorHost through)
    {
        m_throughlist.addElement(through);
    }

    /**
     * Add a bypass node to a traversal.  Each traversal may 
     * have multiple bypass nodes which may consist of TreeNodes
     * and TreeEdges.
     *
     * @param bypass   New bypass node/edge.
     */
    public void addBypassNode(VisitorHost bypass)
    {
        m_bypasslist.addElement(bypass);
    }

    /**
     * Add a end node to a traversal.  Each traversal may 
     * have multiple end nodes which may consist only of TreeNodes.
     *
     * @param end   New through node/edge.
     */
    public void addEndNode(TreeNode end)
    {
        m_endlist.addElement(end);
    }

    /**
     * Returns the name of the traversal's starting class.
     *
     * @return  Traversal's starting class name.
     */
    public String startClassName()
    {
        return m_start.getNameForTraversal();
    }

    /**
     * Returns the name of the traversal.
     *
     * @return  Traversal's name.
     */
    public String traversalName()
    {
        return m_name;
    }

    /**
     * Returns the traversal as a DemJava behavior string.
     *
     * @param owner     Visitor containing the traversal.    
     * @return          Traversals as a DemJava behavior string.
     */
    public String toTraversalString(Visitor owner)
    {
        String buffer = new String();
        buffer = "\ttraversal " + m_name + "(" + owner.getNodeName() + " " + owner.getNodeName().toLowerCase() + ")\n";
        buffer += "\t{\n";

        Enumeration e = null;

        // through-nodes?
        e = m_throughlist.elements();
        if(e.hasMoreElements())
        {
            buffer += "\t\tthrough {";
            while (e.hasMoreElements())  
            {	
                buffer += ((TreeNode)e.nextElement()).getNameForTraversal();
                if(e.hasMoreElements())
                {
                    buffer += " , ";
                }
            }
            buffer += " }\n";
        }

        // bypassing nodes?
        e = m_bypasslist.elements();
        if(e.hasMoreElements())
        {
            buffer += "\t\tbypassing {";
            while (e.hasMoreElements())  
            {	
                buffer += ((TreeNode)e.nextElement()).getNameForTraversal();
                if(e.hasMoreElements())
                {
                    buffer += " , ";
                }
            }
            buffer += " }\n";
        }

        // end nodes?
        e = m_endlist.elements();
        if(e.hasMoreElements())
        {
            buffer += "\t\tto {";
            while (e.hasMoreElements())  
            {	
                buffer += ((TreeNode)e.nextElement()).getNameForTraversal();
                if(e.hasMoreElements())
                {
                    buffer += " , ";
                }
            }
            buffer += " };\n";
        }

        buffer += "\t}\n";

        return buffer;
    }

    /**
     * Displays or hides the traversal in the provided view.
     *
     * @param owner     Visitor containing the traversal.    
     * @param view      View in which to display traversal
     * @param bShow     true = show traversal, false = hide traversal
     */
    public void show(Visitor owner, View view, boolean bShow)
    {
       	Visitor visitor = null;

        // are we showing a traversal or hiding one?
        if(bShow == true)
        {
            visitor = owner;
        }

        // update the start node
        m_start.host(visitor);

        Enumeration e = null;

        // update the through nodes
        for  (e = m_throughlist.elements(); e.hasMoreElements()  ;)  
        {	
            ((TreeNode)e.nextElement()).host(visitor);
        }

        // update the bypass nodes
        for  (e = m_bypasslist.elements(); e.hasMoreElements()  ;)  
        {	
            ((TreeNode)e.nextElement()).host(visitor);
        }
        
        // update the end nodes
        for  (e = m_endlist.elements(); e.hasMoreElements()  ;)  
        {	
            ((TreeNode)e.nextElement()).host(visitor);
        }

    }
}
