package simulator;

import java.util.Arrays;

/*
    Rules for Chi wheel settings.
    Cannot have more than 5 consecutive similar symbols (e.g. 1100000111 is valid, 00111111000 is not).
    The number of crosses per each wheel is limited to one or two possible values (so is the number of dots, accordingly).
    Similarly, the number of crosses in the delta of the wheel pattern is also limited to one or or values.

    W L  x        dx        // W = wheel number from 1 to 5; L = number of pins ; x = possible numbers of crosses; dx = possible numbers of crosses in delta
    1 41 20 or 21 20
    2 31 15 or 16 16
    3 29 14 or 15 14
    4 26 13       12 or 14
    5 23 11 or 12 12

     */
public class ChiRule {

    static ChiRule[] chiRules = {
            /* Wheel 1 */ new ChiRule(new int[] {20, 21}, new int[] {20}),
            /* Wheel 2 */ new ChiRule(new int[] {15, 16}, new int[] {16}),
            /* Wheel 3 */ new ChiRule(new int[] {14, 15}, new int[] {14}),
            /* Wheel 4 */ new ChiRule(new int[] {13}, new int[] {12, 14}),
            /* Wheel 5 */ new ChiRule(new int[] {11, 12}, new int[] {12}),
    };
    public static final int MAX_CONSECUTIVE_CROSSES = 5;
    public static final int MAX_CONSECUTIVE_DOTS = 5;

    // Specific wheel rule
    private int[] possibleNumberOfCrosses;
    private int[] possibleNumberOfCrossesInDelta;

    private ChiRule(int[] possibleNumberOfCrosses, int[] possibleNumberOfCrossesInDelta){
        this.possibleNumberOfCrosses = Arrays.copyOf(possibleNumberOfCrosses, possibleNumberOfCrosses.length);
        this.possibleNumberOfCrossesInDelta = Arrays.copyOf(possibleNumberOfCrossesInDelta, possibleNumberOfCrossesInDelta.length);
    }

    public static int randomDeltaCrosses(int w) {
        ChiRule chiRule = chiRules[w];
        return chiRule.possibleNumberOfCrossesInDelta[Utils.random.nextInt(chiRule.possibleNumberOfCrossesInDelta.length)];
    }
    public static int minDeltaCrosses(int w) {
        ChiRule chiRule = chiRules[w];
        return chiRule.possibleNumberOfCrossesInDelta[0];
    }
    public static int maxDeltaCrosses(int w) {
        ChiRule chiRule = chiRules[w];
        return chiRule.possibleNumberOfCrossesInDelta[chiRule.possibleNumberOfCrossesInDelta.length - 1];
    }

    public static int randomCrosses(int w) {
        ChiRule chiRule = chiRules[w];
        return chiRule.possibleNumberOfCrosses[Utils.random.nextInt(chiRule.possibleNumberOfCrosses.length)];
    }
    public static int minCrosses(int w) {
        ChiRule chiRule = chiRules[w];
        return chiRule.possibleNumberOfCrosses[0];
    }
    public static int maxCrosses(int w) {
        ChiRule chiRule = chiRules[w];
        return chiRule.possibleNumberOfCrosses[chiRule.possibleNumberOfCrosses.length - 1];
    }

    public static void printRules() {
        System.out.print("W L  x         dx\n");
        for (int w = Tunny.CHI1; w <= Tunny.CHI5 ; w++) {
            System.out.printf("%d %2d ", w + 1, Tunny.CHI_PERIOD[w]);
            int[] possibleNumberOfCrosses = chiRules[w].possibleNumberOfCrosses;
            if (possibleNumberOfCrosses.length == 2) {
                System.out.printf("%2d or %2d, ", possibleNumberOfCrosses[0], possibleNumberOfCrosses[1]);
            } else {
                System.out.printf("%2d,       ", possibleNumberOfCrosses[0]);
            }
            int[] possibleNumberOfCrossesInDelta = chiRules[w].possibleNumberOfCrossesInDelta;
            if (possibleNumberOfCrossesInDelta.length == 2) {
                System.out.printf("%2d or %2d, ", possibleNumberOfCrossesInDelta[0], possibleNumberOfCrossesInDelta[1]);
            } else {
                System.out.printf("%2d,       ", possibleNumberOfCrossesInDelta[0]);
            }

            System.out.println();
        }
    }
}
