/*
 $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 java.util.List;
import java.util.ArrayList;
import java.util.Collections;


/** 
 *  A syntax reduction, produced by the <code>Parser</code>.
 *
 *  @see antlr.Parser
 *  @see Token
 *  @see CSTNode
 *  @see Types
 *
 *  @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
 *  @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a>
 *
 *  @version $Id$
 */

public class Reduction extends CSTNode
{
    public static final Reduction EMPTY = new Reduction();


  //---------------------------------------------------------------------------
  // INITIALIZATION AND SUCH

    private List    elements  = null;    // The set of child nodes   
    private boolean marked    = false;   // Used for completion marking by some parts of the parser


   /**
    *  Initializes the <code>Reduction</code> with the specified root.
    */

    public Reduction( Token root ) 
    {
        elements = new ArrayList();
        set( 0, root );
    }


   /**
    *  Initializes the <code>Reduction</code> to empty.
    */

    private Reduction() 
    {
        elements = Collections.EMPTY_LIST;
    }


   /**
    *  Creates a new <code>Reduction</code> with <code>Token.NULL</code>
    *  as it's root.
    */

    public static Reduction newContainer() 
    {
        return new Reduction( Token.NULL );
    }




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


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

    public boolean isEmpty() 
    {
        return size() == 0;
    }



   /**
    *  Returns the number of elements in the node.
    */

    public int size() 
    {
        return elements.size();
    }



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

    public CSTNode get( int index ) 
    {
        CSTNode element = null;

        if( index < size() ) 
        {
            element = (CSTNode)elements.get( index );
        }

        return element;
    }



   /**
    *  Returns the root of the node, the Token that indicates it's
    *  type.  Returns null if there is no root (usually only if the
    *  node is a placeholder of some kind -- see isEmpty()).
    */

    public Token getRoot() 
    {
        if( size() > 0 )
        {
            return (Token)elements.get(0);
        }
        else
        {
            return null;
        }
    }



   /**
    *  Marks the node a complete expression.
    */

    public void markAsExpression() 
    {
        marked = true;
    }



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

    public boolean isAnExpression() 
    {
        if( isA(Types.COMPLEX_EXPRESSION) ) 
        {
            return true;
        }

        return marked;
    }




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


   /**
    *  Adds an element to the node.
    */

    public CSTNode add( CSTNode element ) 
    {
        return set( size(), element );
    }



   /**
    *  Sets an element in at the specified index.
    */

    public CSTNode set( int index, CSTNode element ) 
    {
        
        if( elements == null ) 
        {
            throw new GroovyBugError( "attempt to set() on a EMPTY Reduction" );
        }

        if( index == 0 && !(element instanceof Token) ) 
        {

            //
            // It's not the greatest of design that the interface allows this, but it
            // is a tradeoff with convenience, and the convenience is more important.

            throw new GroovyBugError( "attempt to set() a non-Token as root of a Reduction" );
        }


        //
        // Fill slots with nulls, if necessary.

        int count = elements.size();
        if( index >= count ) 
        {
            for( int i = count; i <= index; i++ ) 
            {
                elements.add( null );
            }
        }

        //
        // Then set in the element.

        elements.set( index, element );

        return element;
    }



   /**
    *  Removes a node from the <code>Reduction</code>.  You cannot remove 
    *  the root node (index 0).
    */

    public CSTNode remove( int index )
    {
        if( index < 1 ) 
        {
            throw new GroovyBugError( "attempt to remove() root node of Reduction" );
        }

        return (CSTNode)elements.remove( index );
    }



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

    public Reduction asReduction() 
    {
        return this;
    }

}

