/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
/* Generated By:JJTree: Do not edit this line. SimpleNode.java */

package org.apache.myfaces.buildtools.maven2.plugin.javascript.javascript20parser;

public class SimpleNode implements Node
{
  protected Node       parent;
  protected Node[]     children;
  protected int        id;
  protected JSParser20 parser;

  protected Token      first;
  protected Token      last;

  public SimpleNode(int i)
  {
    id = i;
  }

  public SimpleNode(JSParser20 p, int i)
  {
    this(i);
    parser = p;
  }

  public void jjtOpen()
  {
    first = parser.getToken(1); // new
  }

  public void jjtClose()
  {
    last = parser.getToken(0); // new
  }

  public Token getFirstToken() { return first; } // new
  public Token getLastToken() { return last; }   // new

  public void jjtSetParent(Node n)
  {
    parent = n;
  }

  public Node jjtGetParent()
  {
    return parent;
  }

  public void jjtAddChild(Node n, int i)
  {

    if (children == null)
    {
      children = new Node[i + 1];
    }
    else if (i >= children.length)
    {
      Node[] c = new Node[i + 1];
      System.arraycopy(children, 0, c, 0, children.length);
      children = c;
    }

    children[i] = n;
  }

  public Node jjtGetChild(int i)
  {
    return children[i];
  }

  public int jjtGetNumChildren()
  {
    return (children == null) ? 0 : children.length;
  }

  /** Accept the visitor. **/
  public Object jjtAccept(JSParser20Visitor visitor, Object data)
  {
    return visitor.visit(this, data);
  }

  /** Accept the visitor. **/
  public Object childrenAccept(JSParser20Visitor visitor, Object data)
  {

    if (children != null)
    {

      for (int i = 0; i < children.length; ++i)
      {
        children[i].jjtAccept(visitor, data);
      }
    }

    return data;
  }

  /* You can override these two methods in subclasses of SimpleNode to
     customize the way the node appears when the tree is dumped.  If
     your output uses more than one line you should override
     toString(String), otherwise overriding toString() is probably all
     you need to do. */

  public String toString()
  {
    return JSParser20TreeConstants.jjtNodeName[id];
  }

  public String toString(String prefix)
  {
    return prefix + toString();
  }

  /* Override this method if you want to customize how the node dumps
     out its children. */

  public void dump(String prefix)
  {
    System.out.println(toString(prefix));

    if (children != null)
    {

      for (int i = 0; i < children.length; ++i)
      {
        SimpleNode n = (SimpleNode) children[i];

        if (n != null)
        {
          n.dump(prefix + " ");
        }
      }
    }
  }
}
