package simulator;

import java.util.HashMap;

/*

   Rules limiting the Psi-wheel settings.

 */
public class PsiRule {

    // The number of crosses (and dots) is constant per each wheel.
    private static int[] numberOfCrosses = new int[] {22, 24, 26, 27, 30};  // Independent of d.

    // The number of crosses in the psi-wheel pattern delta depends on d (the number of dots in MU2 (MU37)).
    private static String numberOfDeltaCrossesString = "" +
            //d   1  2        3        4  5
            "14   26 28       32       32 36 14\n" +
            "15   26 30       32       34 38 15\n" +
            "16   28 30       32       34 38 16\n" +
            "17   28 30       32 or 34 34 38 17\n" +
            "18   28 32       34       36 38 18\n" +
            "19   28 32       34       36 40 19\n" +
            "20   30 32       34 or 36 36 40 20\n" +
            "21   30 32       36       38 42 21\n" +
            "22   30 34       36       38 42 22\n" +
            "23   32 34       38       38 42 23\n" +
            "24   32 34       38       40 44 24\n" +
            "25   32 36       38       40 44 25\n" +
            "26   34 36       40       40 46 26\n" +
            "27   34 36 or 38 40       42 46 27\n" +
            "28   34 38       42       42 48 28";

    // Specific Psi rule
    private int d;
    private int[][] numberOfDeltaCrosses = new int[5][];  // depend on d.

    public static int randomDeltaCrosses(int w, int d) {
        PsiRule psiRule = ruleForD.get(d);
        return psiRule.numberOfDeltaCrosses[w][Utils.random.nextInt(psiRule.numberOfDeltaCrosses[w].length)];
    }
    public static int minDeltaCrosses(int w, int d) {
        PsiRule psiRule = ruleForD.get(d);
        return psiRule.numberOfDeltaCrosses[w][0];
    }
    public static int maxDeltaCrosses(int w, int d) {
        PsiRule psiRule = ruleForD.get(d);
        return psiRule.numberOfDeltaCrosses[w][psiRule.numberOfDeltaCrosses[w].length - 1];
    }
    public static int crosses(int w) {
        return numberOfCrosses[w];
    }

    public static void printRule(int d) {
        PsiRule psiRule = ruleForD.get(d);
        System.out.printf("d: %d: ", d);
        for (int w = Tunny.PSI1; w <= Tunny.PSI5; w++) {
            int[] deltaCrosses = psiRule.numberOfDeltaCrosses[w];
            if (deltaCrosses.length == 2) {
                System.out.printf("%2d or %2d, ", deltaCrosses[0], deltaCrosses[1]);
            } else  {
                System.out.printf("%2d,       ", deltaCrosses[0]);
            }
        }
        System.out.println();
    }

    // Private
    private PsiRule(String line) {
        line = line.replaceAll("[ ]+", " ");
        String[] items = line.split(" ");
        d = Integer.parseInt(items[0]);

        int index = 1;
        for (int w = Tunny.PSI1; w <= Tunny.PSI5; w++) {
            if (items[index + 1].equals("or")) {
                numberOfDeltaCrosses[w] = new int[2];
                numberOfDeltaCrosses[w][0] = Integer.parseInt(items[index]);
                numberOfDeltaCrosses[w][1] = Integer.parseInt(items[index + 2]);
                index += 3;
            } else {
                numberOfDeltaCrosses[w] = new int[1];
                numberOfDeltaCrosses[w][0] = Integer.parseInt(items[index]);
                index += 1;
            }
        }
    }
    private static HashMap<Integer, PsiRule> ruleForD = initPsiRules();
    private static HashMap<Integer, PsiRule> initPsiRules() {
        HashMap<Integer, PsiRule> map = new HashMap<>();

        String[] lines = numberOfDeltaCrossesString.split("[\r\n]+");
        for (String line : lines) {
            PsiRule psiRule = new PsiRule(line);
            map.put(psiRule.d, psiRule);
        }
        return map;
    }

}
