/*
 * Copyright 2003-2007 the original author or authors.
 *
 * Licensed 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.
 */

package org.codehaus.groovy.syntax;

import org.codehaus.groovy.GroovyBugError;

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;
    }

}

