/*
 [The "BSD license"]
 Copyright (c) 2005-2009 Terence Parr
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
 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 of the author may not be used to endorse or promote products
     derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 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 AUTHOR 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.antlr.runtime.tree;

import org.antlr.runtime.RecognizerSharedState;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.TokenStream;

public class TreeRewriter extends TreeParser {
    public interface fptr {
        public Object rule() throws RecognitionException;
    }

    protected boolean showTransformations = false;

    protected TokenStream originalTokenStream;
    protected TreeAdaptor originalAdaptor;
    
    public TreeRewriter(TreeNodeStream input) {
        this(input, new RecognizerSharedState());
    }
    public TreeRewriter(TreeNodeStream input, RecognizerSharedState state) {
        super(input, state);
        originalAdaptor = input.getTreeAdaptor();
        originalTokenStream = input.getTokenStream();        
    }

    public Object applyOnce(Object t, fptr whichRule) {
        if ( t==null ) return null;
        try {
            // share TreeParser object but not parsing-related state
            state = new RecognizerSharedState();
            input = new CommonTreeNodeStream(originalAdaptor, t);
            ((CommonTreeNodeStream)input).setTokenStream(originalTokenStream);
            setBacktrackingLevel(1);
            TreeRuleReturnScope r = (TreeRuleReturnScope)whichRule.rule();
            setBacktrackingLevel(0);
            if ( failed() ) return t;
            if ( showTransformations &&
                 r!=null && !t.equals(r.getTree()) && r.getTree()!=null )
            {
                reportTransformation(t, r.getTree());
            }
            if ( r!=null && r.getTree()!=null ) return r.getTree();
            else return t;
        }
        catch (RecognitionException e) { ; }
        return t;
    }

    public Object applyRepeatedly(Object t, fptr whichRule) {
        boolean treeChanged = true;
        while ( treeChanged ) {
            Object u = applyOnce(t, whichRule);
            treeChanged = !t.equals(u);
            t = u;
        }
        return t;
    }

    public Object downup(Object t) { return downup(t, false); }

    public Object downup(Object t, boolean showTransformations) {
        this.showTransformations = showTransformations;
        TreeVisitor v = new TreeVisitor(new CommonTreeAdaptor());
        TreeVisitorAction actions = new TreeVisitorAction() {
            public Object pre(Object t)  { return applyOnce(t, topdown_fptr); }
            public Object post(Object t) { return applyRepeatedly(t, bottomup_ftpr); }
        };
        t = v.visit(t, actions);
        return t;
    }

    /** Override this if you need transformation tracing to go somewhere
     *  other than stdout or if you're not using Tree-derived trees.
     */
    public void reportTransformation(Object oldTree, Object newTree) {
        System.out.println(((Tree)oldTree).toStringTree()+" -> "+
                           ((Tree)newTree).toStringTree());
    }

    fptr topdown_fptr = new fptr() {
        public Object rule() throws RecognitionException { return topdown(); }
    };
    
    fptr bottomup_ftpr = new fptr() {
        public Object rule() throws RecognitionException { return bottomup(); }
    };

    // methods the downup strategy uses to do the up and down rules.
    // to override, just define tree grammar rule topdown and turn on
    // filter=true.
    public Object topdown() throws RecognitionException { return null; }
    public Object bottomup() throws RecognitionException { return null; }
}
