package net.domesdaybook.compiler.regex;

import net.domesdaybook.automata.State;
import net.domesdaybook.automata.Transition;
import net.domesdaybook.automata.TransitionFactory;
import net.domesdaybook.automata.base.ByteMatcherTransition;
import net.domesdaybook.compiler.matcher.CompilerUtils;
import net.domesdaybook.matcher.bytes.ByteMatcherFactory;
import net.domesdaybook.matcher.bytes.SetAnalysisByteMatcherFactory;
import net.domesdaybook.parser.ParseException;
import net.domesdaybook.parser.tree.ParseTree;


public final class ParseTreeTransitionFactory<T>
  implements TransitionFactory<T, ParseTree> {

  private final ByteMatcherFactory matcherFactory;
  
  public ParseTreeTransitionFactory() {
    this(new SetAnalysisByteMatcherFactory());
  }
  
  public ParseTreeTransitionFactory(final ByteMatcherFactory matcherFactory) {
    this.matcherFactory = matcherFactory;
  }
  
  public Transition<T> create(final ParseTree source,
                              final boolean invert,
                              final State<T> toState) {
    try {
      switch (source.getParseTreeType()) {
        case BYTE:          return createByteTransition(source, toState);
        case ALL_BITMASK:   return createAllBitmaskTransition(source, toState);
        case ANY_BITMASK:   return createAnyBitmaskTransition(source, toState);
        case ANY:           return createAnyTransition(source, toState);
        case SET:           return createSetTransition(source, toState);
      }
    } catch (final ParseException justReturnNull) {
      //TODO: Should a factory throw an exception?  If so, it involves some
      //      extensive refactoring in the classes that use the factories, as
      //      they currently don't expect to fail at creating transitions.
      //      Maybe they should - there are inputs from which a transition can't be
      //      created, for example, the empty set of bytes.  However, this will also
      //      cascade into exceptions for building other kinds of things.  But I guess,
      //      if it's possible to fail due to the arguments passed in, we can only choose 
      //      a checked exception, or throw a runtime IllegalArgumentException...
    }
    return null;
  }

  
  private Transition<T> createByteTransition(final ParseTree ast, final State<T> toState) throws ParseException {
    return new ByteMatcherTransition(CompilerUtils.createByteMatcher(ast), toState);
  }
  
  private Transition<T> createAllBitmaskTransition(final ParseTree ast, final State<T> toState) throws ParseException {
    return new ByteMatcherTransition(CompilerUtils.createAllBitmaskMatcher(ast), toState);
  }

  private Transition<T> createAnyBitmaskTransition(final ParseTree ast, final State<T> toState) throws ParseException {
   return new ByteMatcherTransition(CompilerUtils.createAnyBitmaskMatcher(ast), toState);
  }
  
  private Transition<T> createAnyTransition(final ParseTree ast, final State<T> toState) throws ParseException {
    return new ByteMatcherTransition(CompilerUtils.createAnyMatcher(ast), toState);
  }

  private Transition<T> createSetTransition(final ParseTree ast, final State<T> toState) throws ParseException {
     return new ByteMatcherTransition(CompilerUtils.createMatcherFromSet(ast, matcherFactory), toState);
  }

}

@@ -2424,32 +2424,35 @@
 atcherTransition
+%3CT%3E
 (CompilerUtils.c
@@ -2477,32 +2477,32 @@
 st), toState);%0D%0A
-
   %7D%0D%0A  %0D%0A  priva
@@ -2643,32 +2643,35 @@
 atcherTransition
+%3CT%3E
 (CompilerUtils.c
@@ -2865,32 +2865,35 @@
 atcherTransition
+%3CT%3E
 (CompilerUtils.c
@@ -3083,32 +3083,35 @@
 atcherTransition
+%3CT%3E
 (CompilerUtils.c
@@ -3260,24 +3260,24 @@
 xception %7B%0D%0A
-
      return 
@@ -3301,16 +3301,19 @@
 ansition
+%3CT%3E
 (Compile

make bytematchertransition constructors generic