package games.colonier.ld44.chemistry.reaction;

import games.colonier.ld44.chemistry.Atom;
import games.colonier.ld44.chemistry.Molecule;
import games.colonier.ld44.chemistry.rule.StructuralMolecularRule;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

public class ReactionPattern {

    public final String aExpression;
    public final String bExpression;

    public ReactionPattern (
            String aExpression,
            String bExpression
    ) {
        this.aExpression = aExpression;
        this.bExpression = bExpression;
    }

    private List <Atom> collect (List <StructuralMolecularRule.Edge> edges) {
        List <Atom> r = null;
        if (edges != null) {
            r = new ArrayList<> ();
            for (StructuralMolecularRule.Edge e : edges) {
                if (!r.contains (e.a)) r.add (e.a);
                if (!r.contains (e.b)) r.add (e.b);
            }
        }
        return r;
    }

    public void react (Molecule aMolecule, Molecule bMolecule) {

        StructuralMolecularRule aRule = new StructuralMolecularRule (aExpression);
        StructuralMolecularRule bRule = new StructuralMolecularRule (bExpression);

        List <StructuralMolecularRule.Edge> aEdges = aRule.firstMatch (aMolecule);
        List <StructuralMolecularRule.Edge> bEdges = bRule.firstMatch (bMolecule);

        List <Atom> aAtoms = collect (aEdges);
        List <Atom> bAtoms = collect (bEdges);

        while (aAtoms != null && bAtoms != null) {

            System.out.println (aExpression + " + " + bExpression + " ==> DESTROY");

            aAtoms.forEach (Atom::disconnectAll);
            bAtoms.forEach (Atom::disconnectAll);
            aMolecule.atoms.removeAll (aAtoms);
            bMolecule.atoms.removeAll (bAtoms);

            aEdges = aRule.firstMatch (aMolecule);
            bEdges = bRule.firstMatch (bMolecule);

            aAtoms = collect (aEdges);
            bAtoms = collect (bEdges);

        }

    }

}
