/**
 * Essentially a group of Atoms.
 */
class ContentMolecule {
    protected atoms : Array<ContentAtom> = [];

    public constructor (...atoms : Array<ContentAtom>) {
        this.addAtom(...atoms);
    }

    public addAtom (...atoms : Array<ContentAtom>) {
        this.atoms.push(...atoms);
        return this;
    }

    public getAtoms () {
        return this.atoms;
    }

    public findMatches (many : Array<ContentMolecule>, giveRelevant = false) {
        let missingAtoms = [...this.atoms];
        let chosenOnes = [];
        let relevantAtoms : Array<ContentAtom> = [];

        for (let k = 0; k < many.length; k++) {
            let vagueMolecule = many[k]
            let vagueAtoms = [...vagueMolecule.atoms];

            // Check if the ENTIRETY of vague side fits in here.
            let cachedAtoms = missingAtoms.slice();
            for (let i = vagueAtoms.length - 1; i >= 0; i--) {
                let vagueAtom = vagueAtoms[i];
                for (let k = cachedAtoms.length - 1; k >= 0; k--) {
                    let specificAtom = cachedAtoms[k];
                    if (specificAtom.compareAgainst(vagueAtom)) {
                        cachedAtoms.splice(k, 1);
                        relevantAtoms.push(...vagueAtoms.splice(i, 1));
                        break;
                    }
                }
            }

            if (vagueAtoms.length == 0) {
                missingAtoms = cachedAtoms;
                chosenOnes.push(k);
            }

            if (missingAtoms.length == 0) {
                break;
            }
        }

        if (giveRelevant) {
            return relevantAtoms;
        }

        if (missingAtoms.length == 0) {
            return chosenOnes; // Return best match
        } else {
            return []; // No match
        }
    }
}