# Source code for pymatgen.analysis.chemenv.utils.defs_utils

    # coding: utf-8
    # Copyright (c) Pymatgen Development Team.
    # Distributed under the terms of the MIT License.

    """
    This module contains the definition of some objects used in the chemenv package.
    """

    __author__ = "David Waroquiers"
    __copyright__ = "Copyright 2012, The Materials Project"
    __credits__ = "Geoffroy Hautier"
    __version__ = "2.0"
    __maintainer__ = "David Waroquiers"
    __email__ = "david.waroquiers@gmail.com"
    __date__ = "Feb 20, 2016"

    from pymatgen.analysis.chemenv.utils.coordination_geometry_utils import is_anion_cation_bond

    STATS_ENV_PAPER = 'David Waroquiers, Xavier Gonze, Gian-Marco Rignanese, Cathrin Welker-Nieuwoudt, Frank Rosowski,\n' \
                      'Michael Goebel, Stephan Schenk, Peter Degelmann, Rute Andre, Robert Glaum, and Geoffroy Hautier,\n' \
                      '"Statistical analysis of coordination environments in oxides",\n' \
                      'Chem. Mater., 2017, 29 (19), pp 8346-8360,\n' \
                      'DOI: 10.1021/acs.chemmater.7b02766\n'

    def chemenv_citations():
        out = ''
        out += '\nIf you use the ChemEnv tool for your research, please consider citing the following reference(s) :\n'
        out += '==================================================================================================\n'
        out += STATS_ENV_PAPER
        return out

    class AdditionalConditions():
        NO_ADDITIONAL_CONDITION = 0
        ONLY_ANION_CATION_BONDS = 1
        NO_ELEMENT_TO_SAME_ELEMENT_BONDS = 2
        ONLY_ANION_CATION_BONDS_AND_NO_ELEMENT_TO_SAME_ELEMENT_BONDS = 3
        ONLY_ELEMENT_TO_OXYGEN_BONDS = 4
        # Short versions
        NONE = NO_ADDITIONAL_CONDITION
        NO_AC = NO_ADDITIONAL_CONDITION
        ONLY_ACB = ONLY_ANION_CATION_BONDS
        NO_E2SEB = NO_ELEMENT_TO_SAME_ELEMENT_BONDS
        ONLY_ACB_AND_NO_E2SEB = ONLY_ANION_CATION_BONDS_AND_NO_ELEMENT_TO_SAME_ELEMENT_BONDS
        ONLY_E2OB = ONLY_ELEMENT_TO_OXYGEN_BONDS
        # Dictionary mapping of integer for the condition and its "description"
        CONDITION_DESCRIPTION = {NO_ADDITIONAL_CONDITION: 'No additional condition',
                                 ONLY_ANION_CATION_BONDS: 'Only anion-cation bonds',
                                 NO_ELEMENT_TO_SAME_ELEMENT_BONDS: 'No element-element bonds (same elements)',
                                 ONLY_ANION_CATION_BONDS_AND_NO_ELEMENT_TO_SAME_ELEMENT_BONDS: 'Only anion-cation bonds and'
                                                                                               ' no element-element bonds'
                                                                                               ' (same elements)',
                                 ONLY_ELEMENT_TO_OXYGEN_BONDS: 'Only element-oxygen bonds'}

        ALL = [NONE, ONLY_ACB, NO_E2SEB, ONLY_ACB_AND_NO_E2SEB, ONLY_E2OB]

        def check_condition(self, condition, structure, parameters):
            if condition == self.NONE:
                return True
            elif condition == self.ONLY_ACB:
                valences = parameters['valences']
                ii = parameters['site_index']
                jj = parameters['neighbor_index']
                return is_anion_cation_bond(valences, ii, jj)
            elif condition == self.NO_E2SEB:
                ii = parameters['site_index']
                jj = parameters['neighbor_index']
                elmts_ii = [sp.symbol for sp in structure[ii].species]
                elmts_jj = [sp.symbol for sp in structure[jj].species]
                return len(set(elmts_ii) & set(elmts_jj)) == 0
            elif condition == self.ONLY_ACB_AND_NO_E2SEB:
                valences = parameters['valences']
                ii = parameters['site_index']
                jj = parameters['neighbor_index']
                elmts_ii = [sp.symbol for sp in structure[ii].species]
                elmts_jj = [sp.symbol for sp in structure[jj].species]
                return len(set(elmts_ii) & set(elmts_jj)) == 0 and is_anion_cation_bond(valences, ii, jj)
            elif condition == self.ONLY_E2OB:
                ii = parameters['site_index']
                jj = parameters['neighbor_index']
                elmts_ii = [sp.symbol for sp in structure[ii].species]
                elmts_jj = [sp.symbol for sp in structure[jj].species]
                return ('O' in elmts_jj and 'O' not in elmts_ii) or ('O' in elmts_ii and 'O' not in elmts_jj)