package search;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;

import chemaxon.formats.MolFormatException;
import chemaxon.formats.MolImporter;
import chemaxon.jchem.db.Importer;
import chemaxon.jchem.db.PropertyNotSetException;
import chemaxon.jchem.db.TransferException;
import chemaxon.jchem.db.UpdateHandler;
import chemaxon.struc.Molecule;
import chemaxon.util.ConnectionHandler;
import chemaxon.util.MolHandler;

/**
 * Example codes for importing molecules
 * from molecule files or strings 
 * into arrays, Molecule objects or database tables.
 * 
 * When structures are stored in a file,
 * we can import them into database using Importer (databaseImport())
 * or into (array of) Molecule objects using MolImporter and subsequent
 * MolImporter.read() calls (importMol(), moleculeArrayImport()).
 * 
 * If we know only string representation of structure 
 * (SMILES, MDL Molfile, ...), we can import it into a Molecule object
 * using importMolFromString() method.
 * 
 * importMolFromStringAsQuer() is useful to import SMILES strings
 * as SMARTS molecules.
 * 
 * @author Tamas Csizmazia
 * @version 5.2.2, 05/14/2009
 * 
 */
public class MoleculeImport {

    /***
     * Imports a molecule from a file given by full path
     * @param fullPath full path name of file
     * @return first molecule described by file
     */
    public static Molecule importMol(String fullPath){
	return importMol(fullPath, false);
    }

    /**
     * Imports a molecule from a file given by path  
     * @param path path of the file
     * @param localPath false, if <code>path</code> is full path name,
     * otherwise tries to read from default input directory
     * @return first molecule described by file
     */
    public static Molecule importMol(String path, boolean localPath){
	try {
	    MolImporter mi = new MolImporter(
		    localPath ? Util.addPath(path) : path );
	    return mi.read();
	} catch (MolFormatException e) {
	    e.printStackTrace();  // invalid molecule format 
	} catch (IOException e) {
	    e.printStackTrace();  // cannot read from file
	}
	
	return null; //
    }

    /**
     * Imports a molecule given by its string representation
     * e.g. 
     * @param moleculeString e.g. "BrC1=CC=CC=C1"
     * @return molecule
     */
    public static Molecule importMolFromString(String moleculeString) {
	try {
	    return MolImporter.importMol(moleculeString);
	} catch (MolFormatException e) {
	    e.printStackTrace();
	}
	return null;
    }

    /**
     * Importing a molecule as SMARTS 
     * @param moleculeString e.g. "c1ccccc1Cl"
     * @return molecule
     * @throws MolFormatException 
     */
    public static Molecule importMolFromStringAsQuery(String moleculeString) 
    		throws MolFormatException {
	// If queryMode is set true string will be imported as SMARTS
	// If SMILES import needed, set queryMode to false (default)
	MolHandler mh = new MolHandler(moleculeString, true);
	// molecule can be aromatized
//	mh.aromatize();
	return mh.getMolecule();
	
	// The above method is equivalent to the following
//	MolHandler mh = new MolHandler();
//	mh.setQueryMode(true);
//	mh.setMolecule(moleculeString);
//	return mh.getMolecule();
    }
    
    /**
     * Imports the content of an input molecule file
     * to a specified database table.  
     * @param inputFile full path of input file
     * @param connectionHandler open connection handler
     * @param structTableName database table name
     * @throws TransferException
     */
    public static void databaseImport(
	    String inputFile, 
	    ConnectionHandler connectionHandler, 
	    String structTableName) 
    	throws TransferException {
	
        Importer importer = new Importer();
        
        importer.setInput(inputFile);
        importer.setConnectionHandler(connectionHandler);
        importer.setTableName(structTableName);
        importer.setLinesToCheck(100);
        importer.setHaltOnError(false);
        // checking duplicates may slow down import! 
        importer.setDuplicateImportAllowed(true);
        
        // gathering information about file
        importer.init();
        
        // importing molecules into database table
         importer.importMols();
    }
    
    /**
     * Imports the content of an input molecule object
     * to a specified database table.  
     * @param mol the molecule to import
     * @param connectionHandler open connection handler
     * @param structTableName database table name
     * @throws PropertyNotSetException 
     * @throws TransferException
     */
    public static void databaseImportFromMolObject(
	    Molecule mol, 
	    ConnectionHandler connectionHandler, 
	    String structTableName) 
    	throws SQLException, PropertyNotSetException {
	
	UpdateHandler uh = new UpdateHandler(connectionHandler,
		UpdateHandler.INSERT,structTableName, null);
	try {
	    uh.setStructure(mol.toFormat("mrv")); //the molecule has to be converted to one of the available formats
	    uh.execute();
	} finally {
	    uh.close();
	}
	
    }
    

    public static Molecule[] moleculeArrayImport(String inputFilePath) 
    	throws MolFormatException, FileNotFoundException, IOException {
	
	MolImporter imp = new MolImporter (
		new FileInputStream(inputFilePath));
	ArrayList  molList = new ArrayList();
	Molecule m; 
	while ((m= imp.read())!= null) {
	    // If used for searches, molecules can be aromatized here
	    // m.aromatize();
	    molList.add(m);
	}
	imp.close();

	Molecule[] mols = new Molecule[molList.size()];
	for (int i=0;i<molList.size();i++)
	    mols[i] = (Molecule) molList.get(i);
	System.out.println("Imported "+molList.size()+" structures.");
	
	return mols;
    }
}

