package com.tom_e_white.set_game;

import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Card {
    public enum Number {
        THREE, ONE, TWO; // so that the ordinals make sense (mod 3)

        public static Number parseDescription(String description) {
            int num = Integer.parseInt(description.split(" ")[0]);
            return values()[num % 3];
        }
        public static Number parseFilename(File file) {
            return parseDescription(toDescription(file));
        }
    }
    public enum Shading {
        EMPTY, STRIPED, SOLID;

        public static Shading parseDescription(String description) {
            return valueOf(description.split(" ")[1].toUpperCase());
        }
        public static Shading parseFilename(File file) {
            return parseDescription(toDescription(file));
        }
    }
    public enum Color {
        GREEN, PURPLE, RED;

        public static Color parseDescription(String description) {
            return valueOf(description.split(" ")[2].toUpperCase());
        }
        public static Color parseFilename(File file) {
            return parseDescription(toDescription(file));
        }
    }
    public enum Shape {
        DIAMOND, OVAL, SQUIGGLE;

        public static Shape parseDescription(String description) {
            return valueOf(description.split(" ")[3].toUpperCase().replaceFirst("S$", ""));
        }
        public static Shape parseFilename(File file) {
            return parseDescription(toDescription(file));
        }
    }

    private static String toDescription(File file) {
        String reg = "([^-]+)-([^-]+).*(\\d)\\.jpg";
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(file.getName());
        if (matcher.matches()) {
            String colour = matcher.group(1);
            String number = matcher.group(2);
            String index = matcher.group(3);
            return toDescription(Integer.parseInt(number), colour, Integer.parseInt(index));
        }
        throw new IllegalArgumentException("Unrecognized file: " + file);
    }

    private static String toDescription(int number, String colour, int index) {
        // order on how training data cards were laid out
        // solid, striped, empty
        // oval, diamond, squiggle
        String s = number == 1 ? "" : "s";
        switch (index) {
            case 1: return number + " solid " + colour + " oval" + s;
            case 2: return number + " solid " + colour + " diamond" + s;
            case 3: return number + " solid " + colour + " squiggle" + s;
            case 4: return number + " striped " + colour + " oval" + s;
            case 5: return number + " striped " + colour + " diamond" + s;
            case 6: return number + " striped " + colour + " squiggle" + s;
            case 7: return number + " empty " + colour + " oval" + s;
            case 8: return number + " empty " + colour + " diamond" + s;
            case 9: return number + " empty " + colour + " squiggle" + s;
            default: throw new IllegalArgumentException("Unrecognized index " + index);
        }
    }
}

@@ -2227,18 +2227,25 @@
 / order 
-on
+signifies
  how tra
@@ -2347,51 +2347,8 @@
 gle%0A
-        String s = number == 1 ? %22%22 : %22s%22;%0A
     
@@ -2399,735 +2399,1133 @@
 urn 
-number + %22 solid %22 + colour + %22 oval%22 + s;%0A            case 2: return number + %22 solid %22 + colour + %22 diamond%22 + s;%0A            case 3: return number + %22 solid %22 + colour + %22 squiggle%22 + s;%0A            case 4: return number + %22 striped %22 + colour + %22 oval%22 + s;%0A            case 5: return number + %22 striped %22 + colour + %22 diamond%22 + s;%0A            case 6: return number + %22 striped %22 + colour + %22 squiggle%22 + s;%0A            case 7: return number + %22 empty %22 + colour + %22 oval%22 + s;%0A            case 8: return number + %22 empty %22 + colour + %22 diamond%22 + s;%0A            case 9: return number + %22 empty %22 + colour + %22 squiggle%22 + s;%0A            default: throw new IllegalArgumentException(%22Unrecognized index %22 + index);%0A        %7D
+toDescription(number, Shading.SOLID, colour, Shape.OVAL);%0A            case 2: return toDescription(number, Shading.SOLID, colour, Shape.DIAMOND);%0A            case 3: return toDescription(number, Shading.SOLID, colour, Shape.SQUIGGLE);%0A            case 4: return toDescription(number, Shading.STRIPED, colour, Shape.OVAL);%0A            case 5: return toDescription(number, Shading.STRIPED, colour, Shape.DIAMOND);%0A            case 6: return toDescription(number, Shading.STRIPED, colour, Shape.SQUIGGLE);%0A            case 7: return toDescription(number, Shading.EMPTY, colour, Shape.OVAL);%0A            case 8: return toDescription(number, Shading.EMPTY, colour, Shape.DIAMOND);%0A            case 9: return toDescription(number, Shading.EMPTY, colour, Shape.SQUIGGLE);%0A            default: throw new IllegalArgumentException(%22Unrecognized index %22 + index);%0A        %7D%0A    %7D%0A%0A    private static String toDescription(int number, Shading shading, String colour, Shape shape) %7B%0A        String s = number == 1 ? %22%22 : %22s%22;%0A        return number + %22 %22 + shading.name().toLowerCase() + %22 %22 + colour + %22 %22 + shape.name().toLowerCase() + s;
 %0A   

Improve type safety