package games.colonier.ld44.chemistry.rule;

import games.colonier.ld44.chemistry.MoleculeRule;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public final class RuleGenerator {

    private RuleGenerator () {
        throw new UnsupportedOperationException ();
    }

    private static MoleculeRule tryGenerate (int complexity) throws IllegalStateException {


        List<MoleculeRule> rules = new ArrayList<> ();
        Random random = new Random ();

        for (int i = 0; i < complexity; i++) {

            MoleculeRule mr = null;

            /* if (random.nextBoolean () && rules.stream ().noneMatch (r -> r instanceof StatisticalMoleculeRule)) {

                int nR = random.nextInt (10) + 3;
                int nG = random.nextInt (10) + 3;
                int nB = random.nextInt (10) + 3;

                if (rules.stream ().filter (r -> r instanceof SimpleAtomicMolecularRule).map (SimpleAtomicMolecularRule.class::cast).anyMatch (samr -> samr.atomType == Atom.Type.Red)) {
                    nR = 0;
                }

                if (rules.stream ().filter (r -> r instanceof SimpleAtomicMolecularRule).map (SimpleAtomicMolecularRule.class::cast).anyMatch (samr -> samr.atomType == Atom.Type.Green)) {
                    nG = 0;
                }

                if (rules.stream ().filter (r -> r instanceof SimpleAtomicMolecularRule).map (SimpleAtomicMolecularRule.class::cast).anyMatch (samr -> samr.atomType == Atom.Type.Blue)) {
                    nB = 0;
                }

                mr = new StatisticalMoleculeRule (
                        nR, nG, nB,
                        nR > 0 ? random.nextInt (nR) : 0,
                        Math.min (nR, nG) > 0 ? random.nextInt (Math.min (nR, nG)) : 0,
                        Math.min (nR, nB) > 0 ? random.nextInt (Math.min (nR, nB)) : 0,
                        nG > 0 ? random.nextInt (nG) : 0,
                        Math.min (nG, nB) > 0 ? random.nextInt (Math.min (nG, nB)) : 0,
                        nB > 0 ? random.nextInt (nB) : 0
                );

            } else { */

            mr = new SimpleAtomicMolecularRule (
                    SimpleAtomicMolecularRule.randomCounter (random),
                    SimpleAtomicMolecularRule.randomDecider (random),
                    random.nextInt (5) + 3
            );

            // }

            rules.add (mr);

        }

        CompoundMolecularRule rule = new CompoundMolecularRule (rules, CompoundMolecularRule.Operator.And);

        return rule;


    }

    public static MoleculeRule generate (int complexity) {

        while (true) {

            try {

                return tryGenerate (complexity);

            } catch (IllegalStateException ise) {

            }

        }

    }

}
