/*
 $Id$

 Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.

 Redistribution and use of this software and associated documentation
 ("Software"), with or without modification, are permitted provided
 that the following conditions are met:

 1. Redistributions of source code must retain copyright
    statements and notices.  Redistributions must also contain a
    copy of this document.

 2. Redistributions in binary form must reproduce the
    above copyright notice, this list of conditions and the
    following disclaimer in the documentation and/or other
    materials provided with the distribution.

 3. The name "groovy" must not be used to endorse or promote
    products derived from this Software without prior written
    permission of The Codehaus.  For written permission,
    please contact info@codehaus.org.

 4. Products derived from this Software may not be called "groovy"
    nor may "groovy" appear in their names without prior written
    permission of The Codehaus. "groovy" is a registered
    trademark of The Codehaus.

 5. Due credit should be given to The Codehaus -
    http://groovy.codehaus.org/

 THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
 ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 OF THE POSSIBILITY OF SUCH DAMAGE.

 */

package org.codehaus.groovy.syntax;

import org.codehaus.groovy.GroovyBugError;
import org.codehaus.groovy.syntax.Token;
import org.codehaus.groovy.syntax.Types;
import org.codehaus.groovy.syntax.Reduction;

import java.io.StringWriter;
import java.io.PrintWriter;


/**
 *  An abstract base class for nodes in the concrete syntax tree that is
 *  the result of parsing.  Note that the CSTNode is inextricably linked
 *  with the Token in that every CSTNode has a Token as it's root.
 *
 *  @see antlr.Parser
 *  @see Token
 *  @see org.codehaus.groovy.syntax.Reduction
 *  @see org.codehaus.groovy.syntax.Types
 *
 *  @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
 *  @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a>
 *
 *  @version $Id$
 */

public abstract class CSTNode
{

  //---------------------------------------------------------------------------
  // NODE IDENTIFICATION AND MEANING


   /**
    *  Returns the meaning of this node.  If the node isEmpty(), returns
    *  the type of Token.NULL.
    */

    public int getMeaning()
    {
        return getRoot( true ).getMeaning();
    }



   /**
    *  Sets the meaning for this node (and it's root Token).  Not
    *  valid if the node isEmpty().  Returns the node, for convenience.
    */

    public CSTNode setMeaning( int meaning )
    {
        getRoot().setMeaning( meaning );
        return this;
    }



   /**
    *  Returns the actual type of the node.  If the node isEmpty(), returns
    *  the type of Token.NULL.
    */

    public int getType()
    {
        return getRoot( true ).getType();
    }



   /**
    *  Returns true if the node can be coerced to the specified type.
    */

    public boolean canMean( int type )
    {
        return Types.canMean( getMeaning(), type );
    }



   /**
    *  Returns true if the node's meaning matches the specified type.
    */

    public boolean isA( int type )
    {
        return Types.ofType( getMeaning(), type );
    }



   /**
    *  Returns true if the node's meaning matches any of the specified types.
    */

    public boolean isOneOf( int[] types )
    {
        int meaning = getMeaning();
        for( int i = 0; i < types.length; i++ )
        {
            if( Types.ofType(meaning, types[i]) )
            {
                return true;
            }
        }

        return false;
    }



   /**
    *  Returns true if the node's meaning matches all of the specified types.
    */

    public boolean isAllOf( int[] types )
    {
        int meaning = getMeaning();
        for( int i = 0; i < types.length; i++ )
        {
            if( !Types.ofType(meaning, types[i]) )
            {
                return false;
            }
        }

        return true;
    }



   /**
    *  Returns the first matching meaning of the specified types.
    *  Returns Types.UNKNOWN if there are no matches.
    */

    public int getMeaningAs( int[] types )
    {

        for( int i = 0; i < types.length; i++ )
        {
            if( isA(types[i]) )
            {
                return types[i];
            }
        }

        return Types.UNKNOWN;
    }




  //---------------------------------------------------------------------------
  // TYPE SUGAR


   /**
    *  Returns true if the node matches the specified type.  Effectively
    *  a synonym for <code>isA()</code>.  Missing nodes are Token.NULL.
    */

    boolean matches( int type )
    {
        return isA(type);
    }



   /**
    *  Returns true if the node and it's first child match the specified
    *  types.  Missing nodes are Token.NULL.
    */

    boolean matches( int type, int child1 )
    {
        return isA(type) && get(1, true).isA(child1);
    }



   /**
    *  Returns true if the node and it's first and second child match the
    *  specified types.  Missing nodes are Token.NULL.
    */

    boolean matches( int type, int child1, int child2 )
    {
        return matches( type, child1 ) && get(2, true).isA(child2);
    }



   /**
    *  Returns true if the node and it's first three children match the
    *  specified types.  Missing nodes are Token.NULL.
    */

    boolean matches( int type, int child1, int child2, int child3 )
    {
        return matches( type, child1, child2 ) && get(3, true).isA(child3);
    }



   /**
    *  Returns true if the node an it's first four children match the
    *  specified types.  Missing nodes have type Types.NULL.
    */

    boolean matches( int type, int child1, int child2, int child3, int child4 )
    {
        return matches( type, child1, child2, child3 ) && get(4, true).isA(child4);
    }





  //---------------------------------------------------------------------------
  // MEMBER ACCESS


   /**
    *  Returns true if the node is completely empty (no root, even).
    */

    public boolean isEmpty()
    {
        return false;
    }



   /**
    *  Returns the number of elements in the node (including root).
    */

    public abstract int size();



   /**
    *  Returns true if the node has any non-root elements.
    */

    public boolean hasChildren()
    {
        return children() > 0;
    }



   /**
    *  Returns the number of non-root elements in the node.
    */

    public int children()
    {
        int size = size();
        if( size > 1 )
        {
            return size - 1;
        }
        return 0;
    }



   /**
    *  Returns the specified element, or null.
    */

    public abstract CSTNode get( int index );



   /**
    *  Returns the specified element, or Token.NULL if
    *  safe is set and the specified element is null (or doesn't
    *  exist).
    */

    public CSTNode get( int index, boolean safe )
    {
        CSTNode element = get( index );

        if( element == null && safe )
        {
            element = Token.NULL;
        }

        return element;
    }



   /**
    *  Returns the root of the node.  By convention, all nodes have
    *  a Token as the first element (or root), which indicates the type
    *  of the node.  May return null if the node <code>isEmpty()</code>.
    */

    public abstract Token getRoot();



   /**
    *  Returns the root of the node, the Token that indicates it's
    *  type.  Returns a Token.NULL if safe and the actual root is null.
    */

    public Token getRoot( boolean safe )
    {
        Token root = getRoot();

        if( root == null && safe )
        {
            root = Token.NULL;
        }

        return root;
    }



   /**
    *  Returns the text of the root.  Uses <code>getRoot(true)</code>
    *  to get the root, so you will only receive null in return if the
    *  root token returns it.
    */

    public String getRootText()
    {
        Token root = getRoot( true );
        return root.getText();
    }



   /**
    *  Returns a description of the node.
    */

    public String getDescription()
    {
        return Types.getDescription( getMeaning() );
    }



   /**
    *  Returns the starting line of the node.  Returns -1
    *  if not known.
    */

    public int getStartLine()
    {
        return getRoot(true).getStartLine();
    }



   /**
    *  Returns the starting column of the node.  Returns -1
    *  if not known.
    */

    public int getStartColumn()
    {
        return getRoot(true).getStartColumn();
    }



   /**
    *  Marks the node a complete expression.  Not all nodes support
    *  this operation!
    */

    public void markAsExpression()
    {
        throw new GroovyBugError( "markAsExpression() not supported for this CSTNode type" );
    }



   /**
    *  Returns true if the node is a complete expression.
    */

    public boolean isAnExpression()
    {
        return isA(Types.SIMPLE_EXPRESSION);
    }





  //---------------------------------------------------------------------------
  // OPERATIONS


   /**
    *  Adds an element to the node.  Returns the element for convenience.
    *  Not all nodes support this operation!
    */

    public CSTNode add( CSTNode element )
    {
        throw new GroovyBugError( "add() not supported for this CSTNode type" );
    }



   /**
    *  Adds all children of the specified node to this one.  Not all
    *  nodes support this operation!
    */

    public void addChildrenOf( CSTNode of )
    {
        for( int i = 1; i < of.size(); i++ )
        {
            add( of.get(i) );
        }
    }



   /**
    *  Sets an element node in at the specified index.  Returns the element
    *  for convenience.  Not all nodes support this operation!
    */

    public CSTNode set( int index, CSTNode element )
    {
        throw new GroovyBugError( "set() not supported for this CSTNode type" );
    }



   /**
    *  Creates a <code>Reduction</code> from this node.  Returns self if the
    *  node is already a <code>Reduction</code>.
    */

    public abstract Reduction asReduction();




  //---------------------------------------------------------------------------
  // STRING CONVERSION


   /**
    *  Formats the node as a <code>String</code> and returns it.
    */

    public String toString()
    {
        StringWriter string = new StringWriter();
        write( new PrintWriter(string) );

        string.flush();
        return string.toString();
    }


   /**
    *  Formats the node and writes it to the specified <code>Writer</code>.
    */

    public void write( PrintWriter writer )
    {
        write( writer, "" );
    }


   /**
    *  Formats the node and writes it to the specified <code>Writer</code>.
    *  The indent is prepended to each output line, and is increased for each
    *  recursion.
    */

    protected void write( PrintWriter writer, String indent )
    {
        writer.print( "(" );

        if( !isEmpty() )
        {
            Token  root = getRoot( true );
            int    type = root.getType();
            int meaning = root.getMeaning();


            //
            // Display our type, text, and (optional) meaning

            writer.print( Types.getDescription(type) );

            if( meaning != type )
            {
                writer.print( " as " );
                writer.print( Types.getDescription(meaning) );
            }

            if( getStartLine() > -1 )
            {
                writer.print( " at " + getStartLine() + ":" + getStartColumn() );
            }

            String text = root.getText();
            int  length = text.length();
            if( length > 0 )
            {
                writer.print( ": " );
                if( length > 40 )
                {
                   text = text.substring( 0, 17 ) + "..." + text.substring( length - 17, length );
                }

                writer.print( " \"" );
                writer.print( text );
                writer.print( "\" " );
            }
            else if( children() > 0 )
            {
                writer.print( ": " );
            }



            //
            // Recurse to display the children.

            int count = size();
            if( count > 1 )
            {
                writer.println( "" );

                String indent1 = indent + "  ";
                String indent2 = indent + "   ";
                for( int i = 1; i < count; i++ )
                {
                    writer.print( indent1 );
                    writer.print( i );
                    writer.print( ": " );

                    get( i, true ).write( writer, indent2 );
                }

                writer.print( indent );
            }
        }

        if( indent.length() > 0 )
        {
            writer.println( ")" );
        }
        else
        {
            writer.print( ")" );
        }
    }
}
