package search;

import java.awt.Color;
import java.io.IOException;
import java.sql.SQLException;

import chemaxon.enumeration.supergraph.SupergraphException;
import chemaxon.jchem.db.DatabaseSearchException;
import chemaxon.jchem.db.JChemSearch;
import chemaxon.jchem.db.TransferException;
import chemaxon.sss.search.JChemSearchOptions;
import chemaxon.sss.search.MolSearchOptions;
import chemaxon.sss.search.SearchException;
import chemaxon.struc.Molecule;
import chemaxon.util.HitColoringAndAlignmentOptions;
import chemaxon.util.HitDisplayTool;

/**
 * Example codes for hit coloring and alignment
 * 
 * alignmentRotating() - searches two query molecules in the same target, 
 * the second query is the rotated pair of the first one.
 * Hits in the target can be shown in color and/or
 * aligned to query independently.
 * 
 * alignmentPartialClean() - shows the difference between 
 * no alignment, rotating and partial cleaning
 * 
 * rotateDatabaseHits() - retrieves aligned hits of a database search
 * in Molecule format
 * 
 * @author Tamas Csizmazia
 * @version 5.2.2, 05/20/2009
 *
 */
public class VisualizationExample {

    private Molecule query;
    private Molecule target;
    private Molecule result;
    private HitDisplayTool hdt;
    private HitColoringAndAlignmentOptions coloringOptions;
    
    public static void main(String[] args)
	throws TransferException, SQLException, IOException, 
	DatabaseSearchException, SearchException, SupergraphException{

	    VisualizationExample ve = new VisualizationExample();

	    // Example for demonstrating diferences 
	    // when target is aligned (rotated) according to a query
//	    ve.alignmentRotating();

	    // Examples for demonstarting diferences 
	    // between no alignment, alignment (rotation) and partial cleaning
//	    ve.alignmentPartialClean();
	    
	    ve.rotateDatabaseHits();
	}

    public void setup(){
	coloringOptions = new HitColoringAndAlignmentOptions();
    }
    
    public void alignmentRotating(){
//	throws TransferException, SQLException, IOException, 
//		DatabaseSearchException, SearchException, SupergraphException{
	
	// We will look for hits in this molecule
	target = MoleculeImport.importMol("target.mrv", true);

	setup();
        // hit should be coloured in target 
	coloringOptions.coloring = true;
	coloringOptions.hitColor = Color.red;
	coloringOptions.nonHitColor = Color.green;

	//**********************************************
	//* First search: only colouring, no alignment *
	//**********************************************

	// target will not be aligned to query
        coloringOptions.alignmentMode 
	= HitColoringAndAlignmentOptions.ALIGNMENT_OFF;

	// importing first query molecule
        query = MoleculeImport.importMol("query1.mrv", true);

        alignStructures();
        
        
        // Showing query with hit colouring in target (no alignment)
        Util.showMolecule(query, 0, 200);
        Util.showMolecule(result, 1, 200);

        //***********************************************************
	//* Second search: repeating previous search with alignment *
        //***********************************************************
        
	// target will be aligned to query
        coloringOptions.alignmentMode 
	= HitColoringAndAlignmentOptions.ALIGNMENT_ROTATE;
        
        alignStructures();

        Util.showMolecule(result, 2, 200);

        //*******************************************************
	//* Third search: searching second query with alignment *
        //*******************************************************
        
        query = MoleculeImport.importMol("query2.mrv", true);

        alignStructures();

        Util.showMolecule(query, 4, 200);
        Util.showMolecule(result, 5, 200);
    }

    public void alignmentPartialClean(){

	// Importing and displaying query 
	query = MoleculeImport.importMol("molToAlign.mrv", true);
	Util.showMolecule(query, 8, 300);

	// Importing target
	target = MoleculeImport.importMolFromString(
    		"CC(C)(C)C1=C2OC(=O)C(=C2N2N=NN=C12)C(C)(C)C");
        
        // hit should be coloured in target 
	coloringOptions.coloring = true;
	coloringOptions.hitColor = Color.red;
	coloringOptions.nonHitColor = Color.green;

	//**********************************************
	//* First search: only colouring, no alignment *
	//**********************************************

	// target will not be aligned to query
        coloringOptions.alignmentMode 
	= HitColoringAndAlignmentOptions.ALIGNMENT_OFF;
        alignStructures();

        // Displaying hit in target
        Util.showMolecule(result, 9, 300);

        //**************************************
        //* Second search: alignment (rotating)*
        //**************************************
        
        // target will be aligned to query
	target = MoleculeImport.importMolFromString(
    		"CC(C)(C)C1=C2OC(=O)C(=C2N2N=NN=C12)C(C)(C)C");
        coloringOptions.alignmentMode 
        	= HitColoringAndAlignmentOptions.ALIGNMENT_ROTATE;
        alignStructures();
        
        // Displaying hit in target
        Util.showMolecule(result, 10, 300);
        
        //**********************************
        //* Third search: partial cleaning *
        //**********************************
        
        target = MoleculeImport.importMolFromString(
        "CC(C)(C)C1=C2OC(=O)C(=C2N2N=NN=C12)C(C)(C)C");
        coloringOptions.alignmentMode 
        	= HitColoringAndAlignmentOptions.ALIGNMENT_PARTIAL_CLEAN;
        alignStructures();
        
        // Displaying hit in target
        Util.showMolecule(result, 11, 300);
    }

    public void rotateDatabaseHits(){

	Molecule[] hits = null;
	try {
	    SearchExampleBase.tableSetup();

	    JChemSearch jChemSearch = InitializingSearch.createJChemSearch(
		    Connection.getConnectionHandler(1), "OC(CCC)=O",
		    Util.structureTableName, new JChemSearchOptions());

	    jChemSearch.run();

	    setup();
	    coloringOptions.alignmentMode = 
		HitColoringAndAlignmentOptions.ALIGNMENT_ROTATE;
	    coloringOptions.coloring = true;
	    coloringOptions.hitColor = Color.red;
	    coloringOptions.nonHitColor = Color.green;

	    hits = jChemSearch.getHitsAsMolecules(
		    jChemSearch.getResults(), coloringOptions, null, null);
	} catch (Exception e) {
	    e.printStackTrace();
	}

	// showing query
	Util.showMolecule(MoleculeImport.importMolFromString("OC(CCC)=O"), 0);
	// showing first 8 hits
	for (int i = 0; i < 8; i++) { // max. 8 hits to show
	    Util.showMolecule(hits[i], i+4);
	}
    }

    public void alignStructures() {
        
        hdt = new HitDisplayTool(
        	coloringOptions,
        	new MolSearchOptions(),
        	null,  //only aromatization
        	query);
        
        try {
            result = hdt.getHit(target);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


