/* JJT: 0.2.2 */

package w3c.pics.parser;

import java.util.*;

class PICSS_Expr extends SimpleNode implements EvalNode {
  PICSS_Expr(int id) {
    super(id);
  }

  String text = null;
  
  public String getText() {
    return text;
  }

  public String getServiceName() {
    return ((PICSServiceNode)children[0]).getText();
  }

  public String getCategoryName() {
    if (children.length>1)
      return ((PICSCategoryNode)children[1]).getText();
    else
      return null;
  }

  public String getOperator() {
    if (children.length>2)
      return ((PICSOperatorNode)children[2]).getText();
    else
      return null;
  }

  public String getConstant() {
    if (children.length>2)
      return ((PICSConstantNode)children[3]).getText();
    else
      return null;
  }

  public boolean isValid(Vector labellist, Hashtable silist) {
    // check shortnames from Profile to get URLs to check against Label 
    // source URL
    Enumeration sitables = silist.keys();
    boolean foundservice = false;
    Label label = null;
    boolean labelmatch = false;
    while (sitables.hasMoreElements()) {
      Hashtable shash = (Hashtable)silist.get(sitables.nextElement());
      // System.out.println("shash.get(shortname): "+shash.get("shortname"));
      // System.out.println("servicename: "+this.getServiceName());
      if (shash.get("shortname").equals(this.getServiceName())) {
	foundservice = true;
	// System.out.println("shash.get(name): "+shash.get("name"));
	// System.out.println("label service: "+label.getService());
	Enumeration thelabels = labellist.elements();
	while (thelabels.hasMoreElements()) {
	  label = (Label)thelabels.nextElement();
	  if (!(shash.get("name").equals(label.getService())))
	    continue;
	  else {
	    labelmatch = true;
	    break;
	  }
	}
      }
      if (foundservice) 
	break;
    }
    if ((!foundservice) || (!labelmatch))
      return false;
    // first check to see if serviceonly
    if (children.length==1) {
      return true;
    }
    // full value check
    String catname = getCategoryName();
    Vector rvalues = label.getCategory(catname);
    // System.out.println("catname: "+catname);
    // System.out.println("rvalues: "+rvalues);
    if (rvalues==null) {
      return false;
    }
    // System.out.println("children size = "+children.size());
    // check to see if categoryonly
    if (children.length==2)
      return true;
    Enumeration rlist = rvalues.elements();
    int theop = opToInt(getOperator());
    double pval = Double.valueOf(getConstant()).doubleValue();
    // System.out.println("pval: "+pval);
    while (rlist.hasMoreElements()) {
      Rating rval = (Rating)rlist.nextElement();
      if (rval.isRange()) {
	String range = rval.toString();
	int thecolon = range.indexOf(":");
	String num1 = range.substring(0, thecolon);
	String num2 = range.substring(thecolon+1);
	double dval1 = Double.valueOf(num1).doubleValue();
	double dval2 = Double.valueOf(num2).doubleValue();
	switch (theop) {
	case EQUAL:
	  if ((dval1>pval) || (dval2<pval))
	    return false;
	  break;
	case GREATER:
	  if ((dval1<=pval) && (dval2<=pval))
	    return false;
	  break;
	case LESS:
	  if ((dval1>=pval) && (dval2>=pval))
	    return false;
	  break;
	case GREATEREQ:
	  if ((dval1<pval) && (dval2<pval))
	    return false;
	  break;
	case LESSEQ:
	  if ((dval1>pval) && (dval2>pval))
	    return false;
	  break;
	}
      }
      else {
	String num = rval.toString();
	double dval = Double.valueOf(num).doubleValue();
	switch (theop) {
	case EQUAL:
	  if (dval!=pval)
	    return false;
	  break;
	case GREATER:
	  if (dval<=pval)
	    return false;
	  break;
	case LESS:
	  if (dval>=pval)
	    return false;
	  break;
	case GREATEREQ:
	  if (dval<pval)
	    return false;
	  break;
	case LESSEQ:
	  if (dval>pval)
	    return false;
	  break;
	}
      }
    }
    return true;
  }

  private int opToInt(String op) {
    if (op.equals("=")) 
      return EQUAL;
    else if (op.equals(">"))
      return GREATER;
    else if (op.equals("<"))
      return LESS;
    else if (op.equals(">="))
      return GREATEREQ;
    else if (op.equals("<="))
      return LESSEQ;
    else
      return -1;
  }

  private static final int EQUAL = 0;
  private static final int GREATER = 1;
  private static final int LESS = 2;
  private static final int GREATEREQ = 3;
  private static final int LESSEQ = 4;

}
