/*
 * @(#)$Id$
 *
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001 The Apache Software Foundation.  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 end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``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 APACHE SOFTWARE FOUNDATION 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 2001, Sun
 * Microsystems., http://www.sun.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * @author Jacek Ambroziak
 * @author Santiago Pericas-Geertsen
 * @author Erwin Bolwidt <ejb@klomp.org>
 * @author Morten Jorgensen <morten.jorgensen@sun.com>
 *
 */

package org.apache.xalan.xsltc.compiler;

import java.util.Vector;
import java.util.Hashtable;
import java.util.Dictionary;
import java.util.Enumeration;

import de.fub.bytecode.generic.*;
import org.apache.xalan.xsltc.compiler.util.*;

final class TestSeq {

    /*
     * A test sequence is a sequence of patterns that
     *
     *  (1) occured in templates in the same mode
     *  (2) share the same kernel node type (such as A/B and C/C/B).
     *
     * A test sequence may have a default template, which will be run if
     * none of the patterns do not match. This template is always a template
     * that matches solely on the shared kernel node type.
     */
    private Vector   _patterns = null; // all patterns
    private Mode     _mode     = null; // the shared mode
    private Template _default  = null; // the default template

    private InstructionList _instructionList;

    /**
     * Creates a new test sequence, given a set of patterns and a mode.
     */
    public TestSeq(Vector patterns, Mode mode) {
	_patterns = patterns;
	_mode = mode;
    }

    /**
     * The priority is only calculated if the test sequence has a default
     * template. This is bad, bad, bad. We should get the priority from the
     * other templates that make up the test sequence.
     */
    public double getPriority() {
	double prio = (0 - Double.MAX_VALUE);
	final int count = _patterns.size();
	for (int i = 0; i < count; i++) {
	    final Pattern pattern = (Pattern)_patterns.elementAt(i);
	    final Template template = pattern.getTemplate();
	    final double tp = template.getPriority();
	    if (tp > prio) prio = tp;
	}
	if (_default != null) {
	    final double tp = _default.getPriority();
	    if (tp > prio) prio = tp;
	}
	return prio;
    }

    /**
     * This method should return the last position of any template included
     * in this test sequence.
     */
    public int getPosition() {
	int pos = Integer.MIN_VALUE;
	final int count = _patterns.size();
	for (int i = 0; i < count; i++) {
	    final Pattern pattern = (Pattern)_patterns.elementAt(i);
	    final Template template = pattern.getTemplate();
	    final int tp = template.getPosition();
	    if (tp > pos) pos = tp;
	}
	if (_default != null) {
	    final int tp = _default.getPosition();
	    if (tp > pos) pos = tp;
	}
	return pos;
    }
	
    /**
     * Reduce the patterns in this test sequence to exclude the shared
     * kernel node type. After the switch() in the translet's applyTemplates()
     * we already know that we have a hit for the kernel node type, we only
     * have the check the rest of the pattens.
     */
    public void reduce() {
	final Vector newPatterns = new Vector();
	final int count = _patterns.size();

	// Traverse the existing set of patterns (they are in prioritised order)
	for (int i = 0; i < count; i++) {
	    final LocationPathPattern pattern =
		(LocationPathPattern)_patterns.elementAt(i);
	    // Reduce this pattern (get rid of kernel node type)
	    pattern.reduceKernelPattern();
			
	    // Add this pattern to the new vector of patterns.
	    if (!pattern.isWildcard()) {
		newPatterns.addElement(pattern);
	    }
	    // Set template as default if its pattern matches purely on kernel
	    else {
		_default = pattern.getTemplate();
		// Following patterns can be ignored since default has priority
		break;
	    }
	}
	_patterns = newPatterns;
    }

    /**
     * Returns, by reference, the templates that are included in this test
     * sequence. Remember that a single template can occur in several test
     * sequences if its pattern is a union (ex. match="A/B | A/C").
     */
    public void findTemplates(Dictionary templates) {
	if (_default != null)
	    templates.put(_default, this);
	for (int i = 0; i < _patterns.size(); i++) {
	    final LocationPathPattern pattern =
		(LocationPathPattern)_patterns.elementAt(i);
	    templates.put(pattern.getTemplate(), this);
	}
    }

    /**
     * Get the instruction handle to a template's code. This is used when
     * a single template occurs in several test sequences; that is, if its
     * pattern is a union of patterns (ex. match="A/B | A/C").
     */
    private InstructionHandle getTemplateHandle(Template template) {
	return (InstructionHandle)_mode.getTemplateInstructionHandle(template);
    }

    /**
     * Returns pattern n in this test sequence
     */
    private LocationPathPattern getPattern(int n) {
	return (LocationPathPattern)_patterns.elementAt(n);
    }

    /**
     * Copile the code for this test sequence. The code will first test for
     * the pattern with the highest priority, then go on to the next ones,
     * until it hits or finds the default template.
     */
    public InstructionHandle compile(ClassGenerator classGen,
				     MethodGenerator methodGen,
				     InstructionHandle continuation) {

	final int count = _patterns.size();

	// EZ DC if there is only one (default) pattern
	if (count == 0) getTemplateHandle(_default);

	// The 'fail' instruction handle represents a branch to go to when
	// test fails. It is updated in each iteration, so that the tests
	// are linked together in the  if-elseif-elseif-else fashion.
	InstructionHandle fail;

	// Initialize 'fail' to either the code for the default template
	if (_default != null)
	    fail = getTemplateHandle(_default);
	// ..or if that does not exist, to a location set by the caller.
	else
	    fail = continuation;

	for (int n = (count - 1); n >= 0; n--) {
	    final LocationPathPattern pattern = getPattern(n);
	    final Template template = pattern.getTemplate();
	    final InstructionList il = new InstructionList();

	    // Patterns expect current node on top of stack
	    il.append(methodGen.loadCurrentNode());
	    // Apply the test-code compiled for the pattern
	    il.append(pattern.compile(classGen, methodGen));

	    // On success branch to the template code
	    final InstructionHandle gtmpl = getTemplateHandle(template);
	    final InstructionHandle success = il.append(new GOTO_W(gtmpl));
	    pattern.backPatchTrueList(success);
	    pattern.backPatchFalseList(fail);

	    // We're working backwards here. The next pattern's 'fail' target
	    // is this pattern's first instruction
	    fail = il.getStart();

	    // Append existing instruction list to the end of this one
	    if (_instructionList != null) il.append(_instructionList);

	    // Set current instruction list to be this one.
	    _instructionList = il;
	}
	return fail;
    }

    /**
     * Returns the instruction list for this test sequence
     */
    public InstructionList getInstructionList() {
	return _instructionList;
    }

}
