package com.jclark.xsl.expr;

import com.jclark.xsl.om.*;

abstract class ConvertibleNodeSetExpr extends ConvertibleExpr implements NodeSetExpr {

  ConvertibleStringExpr makeStringExpr() {
    return new ConvertibleStringExpr() {
      public String eval(Node node, ExprContext context) throws XSLException {
	return Converter.toString(ConvertibleNodeSetExpr.this.eval(node, context));
      }
    };
  }

  ConvertibleBooleanExpr makeBooleanExpr() {
    return new ConvertibleBooleanExpr() {
      public boolean eval(Node node, ExprContext context) throws XSLException {
	return Converter.toBoolean(ConvertibleNodeSetExpr.this.eval(node, context));
      }
    };
  }

  ConvertibleNodeSetExpr makeNodeSetExpr() {
    return this;
  }

  ConvertibleVariantExpr makeVariantExpr() {
    return new ConvertibleVariantExpr() {
      public Variant eval(Node node, ExprContext context) throws XSLException {
	return new NodeSetVariant(ConvertibleNodeSetExpr.this.eval(node, context));
      }
    };
  }

  /**
   * If is set, then all nodes in the result of eval(x, c)
   * are guaranteed to be in the subtree rooted at x.
   */

  static final int STAYS_IN_SUBTREE = 01;

  /**
   * If this is set, then all nodes in the result of eval(x, c) are
   * guaranteed to be at the same level of the tree (ie siblings of each
   * other or attributes of the same node).  For example, this is true
   * for the children axis but not for the descendants axis.
   */
  static final int SINGLE_LEVEL = 02;

  int getOptimizeFlags() {
    return 0;
  }
  
  /* Return an expression for this/expr */
  ConvertibleNodeSetExpr compose(ConvertibleNodeSetExpr expr) {
    int opt1 = this.getOptimizeFlags();
    int opt2 = expr.getOptimizeFlags();
    if ((opt1 & SINGLE_LEVEL) != 0
	&& (opt2 & STAYS_IN_SUBTREE) != 0)
      return new SequenceComposeExpr(this, expr);
    return new ComposeExpr(this, expr);
  }

  Pattern getChildrenNodePattern() {
    return null;
  }
}
