/*---------------------------------------------------------------------------*\
**$Author: antanas $
**$Date: 2021-02-25 15:58:35 -0500 (Thu, 25 Feb 2021) $
**$Revision: 256 $
**$URL: svn://www.crystallography.net/smiles-scripts/branches/use-system-dependencies/src/cdksdf2smiles.java $
\*---------------------------------------------------------------------------*/

// This CLI Java program reads an SDF and converts it to a SMILES string.

import org.openscience.cdk.ChemFile;
import org.openscience.cdk.aromaticity.Aromaticity;
import org.openscience.cdk.aromaticity.ElectronDonation;
import org.openscience.cdk.AtomContainer;
import org.openscience.cdk.aromaticity.Kekulization;
import org.openscience.cdk.config.AtomTypeFactory;
import org.openscience.cdk.graph.CycleFinder;
import org.openscience.cdk.graph.Cycles;
import org.openscience.cdk.graph.rebond.RebondTool;
import org.openscience.cdk.interfaces.*;
import org.openscience.cdk.io.ISimpleChemObjectReader;
import org.openscience.cdk.io.MDLV2000Reader;
import org.openscience.cdk.io.MDLV3000Reader;
import org.openscience.cdk.silent.SilentChemObjectBuilder;
import org.openscience.cdk.smiles.SmiFlavor;
import org.openscience.cdk.smiles.SmilesGenerator;

import java.io.FileReader;
import java.util.Hashtable;

import static net.crystallography.helpers.cdk.OrthogonaliseAtomCoordinates.computeOrthogonalCoordinates;
import static org.openscience.cdk.tools.manipulator.AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms;
import static org.openscience.cdk.tools.manipulator.AtomContainerManipulator.removeHydrogens;
import static org.openscience.cdk.tools.manipulator.AtomContainerManipulator.suppressHydrogens;

@SuppressWarnings("ALL")
public class cdksdf2smiles {

    static OptionValue suppressHydrogensOption = new OptionValue();
    static OptionValue readMDLV3000Option = new OptionValue();
    static OptionValue aromaticOption = new OptionValue();
    static OptionValue electronDonationModelCDK = new OptionValue();

    static Option options[] = {
        new Option( "-2", "--mdl2000-input", OptionType.OT_BOOLEAN_FALSE,
                    readMDLV3000Option ),
        new Option( "-3", "--mdl3000-input", OptionType.OT_BOOLEAN_TRUE,
                    readMDLV3000Option ),

        new Option( null, "--cdk-electron-donation-model",
                    OptionType.OT_BOOLEAN_TRUE,
                    electronDonationModelCDK ),

        new Option( null, "--daylight-electron-donation-model",
                    OptionType.OT_BOOLEAN_FALSE,
                    electronDonationModelCDK ),

        new Option( "-a", "--aromatic", OptionType.OT_BOOLEAN_TRUE,
                    aromaticOption ),
        new Option( "-a-", "--not-aromatic", OptionType.OT_BOOLEAN_FALSE,
                    aromaticOption ),

        new Option( "-h", "--suppress-hydrogens", OptionType.OT_BOOLEAN_TRUE,
                    suppressHydrogensOption ),
        new Option( "-h-", "--dont-suppress-hydrogens", OptionType.OT_BOOLEAN_FALSE,
                    suppressHydrogensOption ),
        new VersionOption     ( null, "--version", OptionType.OT_FUNCTION ),
        new CDKSdf2SmilesHelp ( null, "--help",    OptionType.OT_FUNCTION ),
    };

    private static final String progName = CDKCif2SmilesHelp.progName;

    @SuppressWarnings("SingleStatementInBlock")
    public static void main(String[] argv ) {
        // Suppress explicit hydrogens by default:
        suppressHydrogensOption.bool = true;

        String filenames[] = null;
        try {
            filenames = SOptions.get_options( argv, options );
        }
        catch (SOptionsException e) {
            System.err.println( progName + ": " + e.getMessage() );
            System.exit(1);
        }

        if( filenames == null || filenames.length == 0 ) {
            filenames = new String[] { "-" };
        }
        for( String filename : filenames ) {
            try {
                ISimpleChemObjectReader reader;
                if (filename.equals("-")) {
                    if( readMDLV3000Option.bool == true ) {
                        reader = new MDLV3000Reader(System.in);
                    } else {
                        reader = new MDLV2000Reader(System.in);
                    }
                } else {
                    if( readMDLV3000Option.bool == true ) {
                        reader = new MDLV3000Reader(new FileReader(filename));
                    } else {
                        reader = new MDLV2000Reader(new FileReader(filename));
                    }
                }

                IAtomContainer container = reader.read(new AtomContainer());
                assert container != null;

                if( aromaticOption.bool == true ) {
                    //------------------------------------------------------------
                    // Taken from the example in:
                    // https://cdk.github.io/cdk/1.5/docs/api/index.html?overview-summary.html
                    ElectronDonation edmodel;
                    if( electronDonationModelCDK.bool == true ) {
                        percieveAtomTypesAndConfigureAtoms(container);
                        edmodel = ElectronDonation.cdk();
                    } else {
                        edmodel = ElectronDonation.daylight();
                    }
                    CycleFinder cycles       = Cycles.cdkAromaticSet();
                    Aromaticity aromaticity  = new Aromaticity(edmodel, cycles);
                    aromaticity.apply(container);
                }

                if( suppressHydrogensOption.bool == true ) {
                    suppressHydrogens(container);
                }

                SmilesGenerator sg =
                    new SmilesGenerator(SmiFlavor.Stereo |
                                        SmiFlavor.UseAromaticSymbols);
                String smiles = sg.create(container);
                System.out.print(smiles);

                String titleKey = "cdk:Title";
                if( container.getProperties().containsKey(titleKey) ) {
                    System.out.print("\t" + container.getProperties().get(titleKey));
                }
                System.out.println();
                
            } // try
            catch(Exception e) {
                System.err.println( progName + ": " + "WARNING, " + e );
            }
        } // for
    }

}
