package org.monospark.spongematchers.parser.primitive;

import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.monospark.spongematchers.matcher.SpongeMatcher;
import org.monospark.spongematchers.matcher.primitive.FloatingPointMatchers;
import org.monospark.spongematchers.parser.SpongeMatcherParser;
import org.monospark.spongematchers.util.PatternBuilder;

public final class FloatingPointMatcherParser extends SpongeMatcherParser<Double> {

    private static final String FLOATING_POINT_REGEX = "(?:\\d+)?.\\d+f";
    
    @Override
    protected Pattern createAcceptanceRegex() {
        return new PatternBuilder()
                .openNamedParantheses("range")
                    .appendCapturingPart(FLOATING_POINT_REGEX, "rangestart")
                    .appendNonCapturingPart("-")
                    .appendCapturingPart(FLOATING_POINT_REGEX, "rangeend")
                .closeParantheses()
                .or()
                .openNamedParantheses("amount")
                    .appendNonCapturingPart("\\(")
                        .openNamedParantheses("amountvalues")
                            .appendNonCapturingPart(FLOATING_POINT_REGEX)
                            .openAnonymousParantheses()
                                .appendNonCapturingPart(FLOATING_POINT_REGEX)
                            .closeParantheses()
                        .closeParantheses()
                    .oneOrMore()
                    .appendNonCapturingPart("\\)")
                .closeParantheses()
                .or()
                .openNamedParantheses("value")
                    .appendNonCapturingPart(FLOATING_POINT_REGEX)
                .closeParantheses()
                .openNamedParantheses("greater")
                    .appendNonCapturingPart(">")
                    .appendCapturingPart(FLOATING_POINT_REGEX, "greatervalue")
                .closeParantheses()
                .or()
                .openNamedParantheses("greaterorequal")
                    .appendNonCapturingPart(">=")
                    .appendCapturingPart(FLOATING_POINT_REGEX, "greaterorequalvalue")
                .closeParantheses()
                .openNamedParantheses("less")
                    .appendNonCapturingPart("<")
                    .appendCapturingPart(FLOATING_POINT_REGEX, "lessvalue")
                .closeParantheses()
                .or()
                .openNamedParantheses("lessorequal")
                    .appendNonCapturingPart("<=")
                    .appendCapturingPart(FLOATING_POINT_REGEX, "lessorequalvalue")
                .closeParantheses()
                .build();
    }
    
    public Optional<SpongeMatcher<Double>> parse(Matcher matcher) {
        if (matcher.group("range") != null) {
            double start = Double.valueOf(matcher.group("rangestart"));
            double end = Double.valueOf(matcher.group("rangeend"));
            return Optional.of(FloatingPointMatchers.range(start, end));
        } else if (matcher.group("amount") != null) {
            String[] split = matcher.group("amount").split(",");
            double[] values = new double[split.length];
            for (int i = 0; i < split.length; i++) {
                values[i] = Double.valueOf(split[i]);
            }
            return Optional.of(FloatingPointMatchers.amount(values));
        } else if (matcher.group("value") != null) {
            double value = Double.valueOf(matcher.group("value"));
            return Optional.of(FloatingPointMatchers.value(value));
        } else if (matcher.group("greater") != null) {
            return Optional.of(FloatingPointMatchers.greaterThan(Double.valueOf(matcher.group("greatervalue"))));
        } else if (matcher.group("greaterorequal") != null) {
            return Optional.of(FloatingPointMatchers.greaterThanOrEqual(Double.valueOf(
                    matcher.group("greaterorequalvalue"))));
        } else if (matcher.group("less") != null) {
            return Optional.of(FloatingPointMatchers.lessThan(Double.valueOf(matcher.group("lessvalue"))));
        } else {
            return Optional.of(FloatingPointMatchers.lessThanOrEqual(Double.valueOf(
                    matcher.group("lessorequalvalue"))));
        }
    }
}

@@ -488,87 +488,8 @@
  %7B%0A%0A
-    private static final String FLOATING_POINT_REGEX = %22(?:%5C%5Cd+)?.%5C%5Cd+f%22;%0A    %0A
     
@@ -542,24 +542,87 @@
 ceRegex() %7B%0A
+        String floatingPointPattern = %22(?:-)?(?:%5C%5Cd+)?.%5C%5Cd+f%22;%0A
         retu
@@ -733,36 +733,36 @@
 ingPart(
-FLOATING_POINT_REGEX
+floatingPointPattern
 , %22range
@@ -859,36 +859,36 @@
 ingPart(
-FLOATING_POINT_REGEX
+floatingPointPattern
 , %22range
@@ -1164,36 +1164,36 @@
 ingPart(
-FLOATING_POINT_REGEX
+floatingPointPattern
 )%0A      
@@ -1298,36 +1298,42 @@
 ingPart(
-FLOATING_POINT_REGEX
+%22,%22 + floatingPointPattern
 )%0A      
@@ -1366,32 +1366,73 @@
 seParantheses()%0A
+                            .oneOrMore()%0A
                 
@@ -1463,41 +1463,8 @@
 s()%0A
-                    .oneOrMore()%0A
     
@@ -1572,59 +1572,8 @@
 r()%0A
-                .openNamedParantheses(%22value%22)%0A    
     
@@ -1583,35 +1583,32 @@
          .append
-Non
 CapturingPart(FL
@@ -1605,36 +1605,45 @@
 ingPart(
-FLOATING_POINT_REGEX
+floatingPointPattern, %22value%22
 )%0A      
@@ -1653,32 +1653,18 @@
        .
-closeParantheses
+or
 ()%0A     
@@ -1797,36 +1797,36 @@
 ingPart(
-FLOATING_POINT_REGEX
+floatingPointPattern
 , %22great
@@ -2040,36 +2040,36 @@
 ingPart(
-FLOATING_POINT_REGEX
+floatingPointPattern
 , %22great
@@ -2113,32 +2113,54 @@
 seParantheses()%0A
+                .or()%0A
                 
@@ -2279,36 +2279,36 @@
 ingPart(
-FLOATING_POINT_REGEX
+floatingPointPattern
 , %22lessv
@@ -2520,28 +2520,28 @@
 art(
-FLOATING_POINT_REGEX
+floatingPointPattern
 , %22l

Add support for negative floating point matchers