#!/usr/bin/env python
# (C) 2017 OpenEye Scientific Software Inc. All rights reserved.
#
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of OpenEye products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. OpenEye claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable OpenEye offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall OpenEye be
# liable for any damages or liability in connection with the Sample Code
# or its use.

import sys
from openeye import oechem
from openeye import oedepict
from openeye import oegrapheme

###############################################################
# USED TO GENERATE CODE SNIPPETS FOR THE OEGRAPHEME DOCUMENTATION
###############################################################


# @ <SNIPPET-ACTIVESITE-OEADDHIGHLIGHTING-PREDICATE>
class Pred6MemAromAtom(oechem.OEUnaryAtomPred):
    def __call__(self, atom):
        return atom.IsAromatic() and oechem.OEAtomIsInAromaticRingSize(atom, 6)


class Pred6MemAromBond(oechem.OEUnaryBondPred):
    def __call__(self, bond):
        return bond.IsAromatic() and oechem.OEBondIsInAromaticRingSize(bond, 6)


def OEAddHighlighting_Predicate(adisp):
    highlight = oedepict.OEHighlightByBallAndStick(oechem.OEBlueTint)
    oegrapheme.OEAddLigandHighlighting(adisp, highlight, Pred6MemAromAtom())
    oegrapheme.OEAddLigandHighlighting(adisp, highlight, Pred6MemAromBond())


def OEAddHighlighting_AtomAndBondPredicate(adisp):
    highlight = oedepict.OEHighlightByColor(oechem.OEDarkGreen)
    oegrapheme.OEAddLigandHighlighting(adisp, highlight, Pred6MemAromAtom(), Pred6MemAromBond())
# @ </SNIPPET-ACTIVESITE-OEADDHIGHLIGHTING-PREDICATE>


# @ <SNIPPET-ACTIVESITE-OEADDHIGHLIGHTING-OEMATCH>
def OEAddHighlighting_OEMatch(adisp):
    ligand = adisp.GetDisplayedLigand()
    subs = oechem.OESubSearch("a1aaaaa1")
    colors = oechem.OEGetVividColors()
    unique = True
    for match, color in zip(subs.Match(ligand, unique), colors):
        highlight = oedepict.OEHighlightByLasso(color)
        highlight.SetConsiderAtomLabelBoundingBox(True)
        oegrapheme.OEAddLigandHighlighting(adisp, highlight, match)
# @ </SNIPPET-ACTIVESITE-OEADDHIGHLIGHTING-OEMATCH>


# @ <SNIPPET-ACTIVESITE-OEADDHIGHLIGHTING-OEATOMBONDSET>
def OEAddHighlighting_OEAtomBondSet(adisp):
    ligand = adisp.GetDisplayedLigand()
    highlight = oedepict.OEHighlightByCogwheel(oechem.OEPinkTint)
    highlight.SetInnerContour(False)
    abset = oechem.OEAtomBondSet(ligand.GetAtoms(Pred6MemAromAtom()),
                                 ligand.GetBonds(Pred6MemAromBond()))

    oegrapheme.OEAddLigandHighlighting(adisp, highlight, abset)
# @ </SNIPPET-ACTIVESITE-OEADDHIGHLIGHTING-OEATOMBONDSET>


# @ <SNIPPET-ACTIVESITE-OEADDHIGHLIGHTING-OERESIDUE>
def OEAddHighlighting_OEResidue(adisp):
    for res, color in zip(adisp.GetDisplayedResidues(), oechem.OEGetLightColors()):
        pen = oedepict.OEPen(color, color, oedepict.OEFill_On, 1.0)
        oegrapheme.OEAddResidueHighlighting(adisp, pen, res)
# @ </SNIPPET-ACTIVESITE-OEADDHIGHLIGHTING-OERESIDUE>


def ImportMolecule(filename):
    ifs = oechem.oemolistream()
    if not ifs.open(filename):
        oechem.OEThrow.Fatal("Unable to open %s for reading" % filename)

    mol = oechem.OEGraphMol()
    if not oechem.OEReadMolecule(ifs, mol):
        oechem.OEThrow.Fatal("Unable to read molecule in %s" % filename)

    return mol


########################################################################
#
########################################################################

if len(sys.argv) != 3:
    oechem.OEThrow.Usage("%s <receptor> <ligand>" % sys.argv[0])

receptor = ImportMolecule(sys.argv[1])
ligand = ImportMolecule(sys.argv[2])

asite = oechem.OEInteractionHintContainer(receptor, ligand)
asite.SetTitle(ligand.GetTitle())
oechem.OEPerceiveInteractionHints(asite)
oegrapheme.OEPrepareActiveSiteDepiction(asite)

opts = oegrapheme.OE2DActiveSiteDisplayOptions(600, 400)
adisp = oegrapheme.OE2DActiveSiteDisplay(asite, opts)
OEAddHighlighting_Predicate(adisp)

oegrapheme.OERenderActiveSite("OEAddHighlighting-ActiveSite-Predicate.png", adisp)
oegrapheme.OERenderActiveSite("OEAddHighlighting-ActiveSite-Predicate.pdf", adisp)

adisp = oegrapheme.OE2DActiveSiteDisplay(asite, opts)
OEAddHighlighting_AtomAndBondPredicate(adisp)
oegrapheme.OERenderActiveSite("OEAddHighlighting-ActiveSite-AtomAndBondPredicate.png", adisp)
oegrapheme.OERenderActiveSite("OEAddHighlighting-ActiveSite-AtomAndBondPredicate.pdf", adisp)

adisp = oegrapheme.OE2DActiveSiteDisplay(asite, opts)
OEAddHighlighting_OEMatch(adisp)
oegrapheme.OERenderActiveSite("OEAddHighlighting-ActiveSite-OEMatch.png", adisp)
oegrapheme.OERenderActiveSite("OEAddHighlighting-ActiveSite-OEMatch.pdf", adisp)

adisp = oegrapheme.OE2DActiveSiteDisplay(asite, opts)
OEAddHighlighting_OEAtomBondSet(adisp)
oegrapheme.OERenderActiveSite("OEAddHighlighting-ActiveSite-OEAtomBondSet.png", adisp)
oegrapheme.OERenderActiveSite("OEAddHighlighting-ActiveSite-OEAtomBondSet.pdf", adisp)

adisp = oegrapheme.OE2DActiveSiteDisplay(asite, opts)
OEAddHighlighting_OEResidue(adisp)
oegrapheme.OERenderActiveSite("OEAddHighlighting-ActiveSite-OEResidue.png", adisp)
oegrapheme.OERenderActiveSite("OEAddHighlighting-ActiveSite-OEResidue.pdf", adisp)
