package com.simolecule.centres;

import com.simolecule.centres.config.Configuration;
import com.simolecule.centres.config.Sp2Bond;
import com.simolecule.centres.config.Tetrahedral;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IStereoElement;
import org.openscience.cdk.stereo.Atropisomeric;
import org.openscience.cdk.stereo.DoubleBondStereochemistry;
import org.openscience.cdk.stereo.ExtendedTetrahedral;
import org.openscience.cdk.stereo.TetrahedralChirality;

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

public final class CdkLabeller extends Labeller<IAtom, IBond> {

  CdkLabeller()
  {
  }

  static List<Configuration<IAtom, IBond>> createConfigs(IAtomContainer mol)
  {
    List<Configuration<IAtom, IBond>> configs = new ArrayList<>();

    for (IStereoElement se : mol.stereoElements()) {
      switch (se.getConfigClass()) {
        case IStereoElement.TH: {
          TetrahedralChirality thSe = (TetrahedralChirality) se;
          configs.add(new Tetrahedral<IAtom, IBond>(thSe.getFocus(),
                                                    thSe.getCarriers().toArray(new IAtom[4]),
                                                    thSe.getConfigOrder()));
        }
        break;
        case IStereoElement.CT: {
          DoubleBondStereochemistry dbSe  = (DoubleBondStereochemistry) se;
          IBond                     bond  = dbSe.getFocus();
          IBond[]                   bonds = dbSe.getBonds();
          configs.add(new Sp2Bond<>(bond,
                                    new IAtom[]{bond.getBegin(), bond.getEnd()},
                                    new IAtom[]{bonds[0].getOther(bond.getBegin()),
                                            bonds[1].getOther(bond.getEnd())},
                                    dbSe.getConfigOrder()));
        }
        break;
        case IStereoElement.AT: {
          Atropisomeric atSe  = (Atropisomeric) se;
          IBond         bond  = atSe.getFocus();
          configs.add(new com.simolecule.centres.config.Atropisomeric<IAtom, IBond>(
                  bond,
                  new IAtom[]{bond.getBegin(), bond.getEnd()},
                  atSe.getCarriers().toArray(new IAtom[4]),
                  atSe.getConfigOrder()));
        }
        break;
        case IStereoElement.AL: {
          ExtendedTetrahedral etSe     = (ExtendedTetrahedral) se;
          IAtom               middle   = etSe.getFocus();
          IAtom[]             endAtoms = ExtendedTetrahedral.findTerminalAtoms(mol, middle);
          IAtom[]             focus    = new IAtom[]{middle, endAtoms[0], endAtoms[1]};
          IAtom[]             carriers = etSe.getCarriers().toArray(new IAtom[4]);
          configs.add(new com.simolecule.centres.config.ExtendedTetrahedral<IAtom, IBond>(focus,
                                                                                          carriers,
                                                                                          etSe.getConfigOrder()));
        }
        break;
      }
    }
    return configs;
  }

  public static void label(IAtomContainer mol)
  {
    new CdkLabeller().label(new CdkMol(mol), createConfigs(mol));
  }
}

@@ -119,63 +119,221 @@
 fig.
-Sp2Bond;%0Aimport com.simolecule.centres.config.Tetrahedr
+Octahedral;%0Aimport com.simolecule.centres.config.Sp2Bond;%0Aimport com.simolecule.centres.config.SquarePlanar;%0Aimport com.simolecule.centres.config.Tetrahedral;%0Aimport com.simolecule.centres.config.TrigonalBipyramid
 al;%0A
@@ -3292,24 +3292,1135 @@
      break;%0A
+        case IStereoElement.OC: %7B%0A          org.openscience.cdk.stereo.Octahedral ocSe%0A                  = ((org.openscience.cdk.stereo.Octahedral) se).normalize();%0A          configs.add(new Octahedral%3CIAtom, IBond%3E(ocSe.getFocus(),%0A                                                   ocSe.getCarriers().toArray(new IAtom%5B6%5D)));%0A        %7D%0A        break;%0A        case IStereoElement.SP: %7B%0A          org.openscience.cdk.stereo.SquarePlanar spSe%0A                  = ((org.openscience.cdk.stereo.SquarePlanar) se).normalize();%0A          configs.add(new SquarePlanar%3CIAtom, IBond%3E(spSe.getFocus(),%0A                                                     spSe.getCarriers().toArray(new IAtom%5B4%5D)));%0A        %7D%0A        break;%0A        case IStereoElement.TBPY: %7B%0A          org.openscience.cdk.stereo.TrigonalBipyramidal tbpySe%0A                  = ((org.openscience.cdk.stereo.TrigonalBipyramidal) se).normalize();%0A          configs.add(new TrigonalBipyramidal%3CIAtom, IBond%3E(tbpySe.getFocus(),%0A                                                            tbpySe.getCarriers().toArray(new IAtom%5B4%5D)));%0A        %7D%0A        break;%0A
       %7D%0A    

Create additional geometries from CDK