package org.drools.guvnor.client.factconstraints.predefined;

import org.drools.guvnor.client.factcontraints.ArgumentNotSetException;
import org.drools.guvnor.client.factcontraints.DefaultConstraintImpl;
import org.drools.guvnor.client.factcontraints.ValidationResult;

/**
 *
 * @author esteban.aliverti@gmail.com
 */
public class RangeConstraint extends DefaultConstraintImpl {

    public static final String RANGE_CONSTRAINT_MIN = "Min.value";
    public static final String RANGE_CONSTRAINT_MAX = "Max.value";

    public RangeConstraint() {
        //set default values
        this.setArgumentValue(RANGE_CONSTRAINT_MIN, "0");
        this.setArgumentValue(RANGE_CONSTRAINT_MAX, "0");
    }

    @Override
    public String getVerifierRule() {
    	return this.createVerifierRuleTemplate("Range_Field_Constraint", null, "The value must be between " + getMin() + " and " + getMax()); //I18N
    }

    @Override
    public ValidationResult validate(Object value) {
        ValidationResult result = new ValidationResult();

        try {
            if (value == null || !(value instanceof Number || value instanceof String)) {
                result.setSuccess(false);
                if (value == null) {
                    result.setMessage("The value is null"); //TODO: I18N
                } else {
                    result.setMessage("Invalid value type " + value.getClass().getName()); //TODO: I18N
                }
            } else {
            	double min = Double.parseDouble(getMin()) ;
                double max = Double.parseDouble(getMax());
                double d = Double.parseDouble(value.toString());
                result.setSuccess(d > min && d < max);
                if (!result.isSuccess()) {
                    result.setMessage("The value should be between " + min + " and " + max); //TODO: I18N
                }
            }
        } catch (Throwable t) {
            result.setSuccess(false);
            result.setMessage(t.getMessage()); //TODO: I18N
        }

        return result;
    }

    public String getMin() {
    	try {
			return (String) this.getMandatoryArgument(RANGE_CONSTRAINT_MIN);
		} catch (ArgumentNotSetException e) {
			throw new IllegalStateException(e);
		}
    }
    
    public String getMax() {
    	try {
			return (String) this.getMandatoryArgument(RANGE_CONSTRAINT_MAX);
		} catch (ArgumentNotSetException e) {
			throw new IllegalStateException(e);
		}
    }
    
    @Override
    protected String getVerifierRestrictionPatternTemplate() {
        StringBuilder restrictionPattern = new StringBuilder();

        restrictionPattern.append("      ($restriction :LiteralRestriction(\n");
        restrictionPattern.append("            fieldPath == $field.path,\n");
        restrictionPattern.append("            valueType == Field.INT,\n");
        restrictionPattern.append("            intValue < " + getMin() + " || > " + getMax() + "\n");
        restrictionPattern.append("      ) OR\n");
        restrictionPattern.append("      $restriction :LiteralRestriction(\n");
        restrictionPattern.append("            fieldPath == $field.path,\n");
        restrictionPattern.append("            valueType == Field.DOUBLE,\n");
        restrictionPattern.append("            doubleValue < " + getMin() + " || > " + getMax() + "\n");
        restrictionPattern.append("      ))\n");

        return restrictionPattern.toString();
    }
}

@@ -509,16 +509,161 @@
 alue%22;%0A%0A
+    private enum Operator%7B%0A        EQ,%0A        NEQ,%0A        GT,%0A        LT,%0A        GE,%0A        LE%0A    %7D%0A%0A    private Operator currentOperator;%0A%0A
     publ
@@ -681,24 +681,24 @@
 straint() %7B%0A
-
         //se
@@ -893,23 +893,173 @@
 ) %7B%0A    
-%09return
+    StringBuilder rules = new StringBuilder();%0A        for (Operator operator : Operator.values()) %7B%0A            this.currentOperator = operator;%0A           
  this.cr
@@ -1106,17 +1106,39 @@
 nstraint
-%22
+_%22+this.currentOperator
 , null, 
@@ -1203,24 +1203,64 @@
 ()); //I18N%0A
+        %7D%0A    %09return rules.toString();%0A
     %7D%0A%0A    @
@@ -3148,30 +3148,64 @@
     
-valueType == Field.INT
+operator.operatorString == Operator.EQUAL.operatorString
 ,%5Cn%22
@@ -3254,16 +3254,45 @@
         
+((valueType == Field.INT && (
 intValue
@@ -3324,34 +3324,35 @@
 %22 + getMax() + %22
-%5Cn
+)) 
 %22);%0A        rest
@@ -3384,14 +3384,18 @@
     
-) OR%5Cn
+       %7C%7C 
 %22);%0A
@@ -3439,43 +3439,100 @@
     
-$restriction :LiteralRestriction(%5Cn
+      (valueType == Field.DOUBLE && (doubleValue %3C %22 + getMin() + %22 %7C%7C %3E %22 + getMax() + %22)) 
 %22);%0A
@@ -3576,53 +3576,26 @@
     
-      fieldPath == $field.path,
+)))
 %5Cn%22);%0A
+%0A
         
 rest
@@ -3582,32 +3582,39 @@
 )%5Cn%22);%0A%0A        
+return 
 restrictionPatte
@@ -3620,259 +3620,410 @@
 ern.
-append(%22            valueType == Field.DOUBLE,%5Cn%22);%0A        restrictionPattern.append(%22            doubleValue %3C %22 + getMin() + %22 %7C%7C %3E %22 + getMax() + %22%5Cn%22);%0A        restrictionPattern.append(%22      ))%5Cn%22);%0A%0A        return restrictionPattern.
+toString();%0A    %7D%0A%0A%0A//    @Override%0A//    protected String getVerifierImportsSufixTemplate() %7B%0A//        return %22import org.drools.base.evaluators.Operator;%5Cn%22;%0A//    %7D%0A//%0A//    @Override%0A//    protected String getVerifierActionSufixTemplate() %7B%0A//        return %22System.out.println(%5C%22OPERATOR= %5C%22+$restriction.getOperator().getOperatorString()+%5C%22. Operator.EQUAL= %5C%22+Operator.EQUAL.getOpera
 to
+r
 String()
 ;%0A  
@@ -4018,18 +4018,26 @@
 String()
-;%0A
+);%5Cn%22;%0A//
     %7D%0A
+%0A
 %7D%0A

Initial support for multiple operators.