/*
 * @(#)$Id$
 *
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001-2003 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
 *
 */

package org.apache.xalan.xsltc.compiler;

import org.apache.bcel.generic.BranchInstruction;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.INVOKESTATIC;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.PUSH;
import org.apache.xalan.xsltc.compiler.util.BooleanType;
import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
import org.apache.xalan.xsltc.compiler.util.IntType;
import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
import org.apache.xalan.xsltc.compiler.util.MethodType;
import org.apache.xalan.xsltc.compiler.util.NodeSetType;
import org.apache.xalan.xsltc.compiler.util.NodeType;
import org.apache.xalan.xsltc.compiler.util.RealType;
import org.apache.xalan.xsltc.compiler.util.ReferenceType;
import org.apache.xalan.xsltc.compiler.util.ResultTreeType;
import org.apache.xalan.xsltc.compiler.util.Type;
import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
import org.apache.xalan.xsltc.runtime.Operators;

final class RelationalExpr extends Expression implements Operators {
    private int _op;
    private Expression _left, _right;
		
    public RelationalExpr(int op, Expression left, Expression right) {
	_op = op;
	(_left = left).setParent(this);
	(_right = right).setParent(this);
    }

    public void setParser(Parser parser) {
	super.setParser(parser);
	_left.setParser(parser);
	_right.setParser(parser);
    }

    /**
     * Returns true if this expressions contains a call to position(). This is
     * needed for context changes in node steps containing multiple predicates.
     */
    public boolean hasPositionCall() {
	if (_left.hasPositionCall()) return true;
	if (_right.hasPositionCall()) return true;
	return false;
    }

    public boolean hasReferenceArgs() {
	return _left.getType() instanceof ReferenceType ||
	    _right.getType() instanceof ReferenceType;
    }

    public boolean hasNodeArgs() {
	return _left.getType() instanceof NodeType ||
	    _right.getType() instanceof NodeType;
    }

    public boolean hasNodeSetArgs() {
	return _left.getType() instanceof NodeSetType ||
	    _right.getType() instanceof NodeSetType;
    }

    public Type typeCheck(SymbolTable stable) throws TypeCheckError {
	Type tleft = _left.typeCheck(stable); 
	Type tright = _right.typeCheck(stable);

	//bug fix # 2838, cast to reals if both are result tree fragments
	if (tleft instanceof ResultTreeType &&
	    tright instanceof ResultTreeType ) 
  	{
	    _right = new CastExpr(_right, Type.Real);
	    _left = new CastExpr(_left, Type.Real);
	    return _type = Type.Boolean; 
	}

	// If one is of reference type, then convert the other too
	if (hasReferenceArgs()) {
	    Type type = null;
	    Type typeL = null;
	    Type typeR = null;
	    if (tleft instanceof ReferenceType) {
		if (_left instanceof VariableRefBase) {
		    VariableRefBase ref = (VariableRefBase)_left;
		    VariableBase var = ref.getVariable();
		    typeL = var.getType();
		}
	    }
	    if (tright instanceof ReferenceType) {
		if (_right instanceof VariableRefBase) {
		    VariableRefBase ref = (VariableRefBase)_right;
		    VariableBase var = ref.getVariable();
		    typeR = var.getType();
		}
	    }
	    // bug fix # 2838 
	    if (typeL == null)
		type = typeR;
	    else if (typeR == null)
		type = typeL;
	    else {
		type = Type.Real;
	    }
	    if (type == null) type = Type.Real;

	    _right = new CastExpr(_right, type);
            _left = new CastExpr(_left, type);
	    return _type = Type.Boolean;
	}

	if (hasNodeSetArgs()) {
	    // Ensure that the node-set is the left argument
	    if (tright instanceof NodeSetType) {
		final Expression temp = _right; _right = _left; _left = temp;
		_op = (_op == Operators.GT) ? Operators.LT :
		    (_op == Operators.LT) ? Operators.GT :
		    (_op == Operators.GE) ? Operators.LE : Operators.GE;
		tright = _right.getType();
	    }

	    // Promote nodes to node sets
	    if (tright instanceof NodeType) {
		_right = new CastExpr(_right, Type.NodeSet);
	    }
	    // Promote integer to doubles to have fewer compares
	    if (tright instanceof IntType) {
		_right = new CastExpr(_right, Type.Real);
	    }
	    // Promote result-trees to strings
	    if (tright instanceof ResultTreeType) {
		_right = new CastExpr(_right, Type.String);
	    }
	    return _type = Type.Boolean;
	}

	// In the node-boolean case, convert node to boolean first
	if (hasNodeArgs()) {
	    if (tleft instanceof BooleanType) {
		_right = new CastExpr(_right, Type.Boolean);
		tright = Type.Boolean;
	    }
	    if (tright instanceof BooleanType) {
		_left = new CastExpr(_left, Type.Boolean);
		tleft = Type.Boolean;
	    }
	}

	// Lookup the table of primops to find the best match
	MethodType ptype = lookupPrimop(stable, Operators.names[_op],
					new MethodType(Type.Void, 
						       tleft, tright)); 

	if (ptype != null) {
	    Type arg1 = (Type) ptype.argsType().elementAt(0);
	    if (!arg1.identicalTo(tleft)) {
		_left = new CastExpr(_left, arg1);
	    }
	    Type arg2 = (Type) ptype.argsType().elementAt(1);
	    if (!arg2.identicalTo(tright)) {
		_right = new CastExpr(_right, arg1);				
	    }
	    return _type = ptype.resultType();
	}
	throw new TypeCheckError(this);
    }

    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
	if (hasNodeSetArgs() || hasReferenceArgs()) {
	    final ConstantPoolGen cpg = classGen.getConstantPool();
	    final InstructionList il = methodGen.getInstructionList();

	    // Call compare() from the BasisLibrary
	    _left.translate(classGen, methodGen);
	    _left.startResetIterator(classGen, methodGen);
	    _right.translate(classGen, methodGen);
	    _right.startResetIterator(classGen, methodGen);

	    il.append(new PUSH(cpg, _op));
	    il.append(methodGen.loadDOM());

	    int index = cpg.addMethodref(BASIS_LIBRARY_CLASS, "compare",
					 "("
					 + _left.getType().toSignature() 
					 + _right.getType().toSignature()
					 + "I"
					 + DOM_INTF_SIG
					 + ")Z");
	    il.append(new INVOKESTATIC(index));
	}
	else {
	    translateDesynthesized(classGen, methodGen);
	    synthesize(classGen, methodGen);
	}
    }

    public void translateDesynthesized(ClassGenerator classGen,
				       MethodGenerator methodGen) {
	if (hasNodeSetArgs() || hasReferenceArgs()) {
	    translate(classGen, methodGen);
	    desynthesize(classGen, methodGen);
	}
	else {
	    BranchInstruction bi = null;
	    final InstructionList il = methodGen.getInstructionList();

	    _left.translate(classGen, methodGen);
	    _right.translate(classGen, methodGen);

	    // TODO: optimize if one of the args is 0

	    boolean tozero = false;
	    Type tleft = _left.getType(); 

	    if (tleft instanceof RealType) {
		il.append(tleft.CMP(_op == LT || _op == LE));
		tleft = Type.Int;
		tozero = true;
	    }

	    switch (_op) {
	    case LT:
		bi = tleft.GE(tozero);	
		break;
		
	    case GT:
		bi = tleft.LE(tozero);
		break;
		
	    case LE:
		bi = tleft.GT(tozero);
		break;
		
	    case GE:
		bi = tleft.LT(tozero);
		break;
		
	    default:
		ErrorMsg msg = new ErrorMsg(ErrorMsg.ILLEGAL_RELAT_OP_ERR,this);
		getParser().reportError(Constants.FATAL, msg);
	    }

	    _falseList.add(il.append(bi));		// must be backpatched
	}
    }

    public String toString() {
	return Operators.names[_op] + '(' + _left + ", " + _right + ')';
    }
}
