#  Copyright (C) 2020 The authors of Py-ChemShell
#
#  This file is part of Py-ChemShell.
#
#  Py-ChemShell is free software: you can redistribute it and/or modify
#  it under the terms of the GNU Lesser General Public License as
#  published by the Free Software Foundation, either version 3 of the
#  License, or (at your option) any later version.
#
#  Py-ChemShell is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public
#  License along with Py-ChemShell.  If not, see
#  <http://www.gnu.org/licenses/>.

__author__ = 'You Lu <you.lu@stfc.ukri.org>'

from numpy       import float64, int64, zeros
from .resultbase import ResultBase
from .xyz        import _XYZ
from ..dl_py2f   import utils

class ResultMD(ResultBase):
    '''Result object containing energy, gradient, etc.'''

    _kwargs = {
                # "energy" cannot be a scalar, because <float> is immutable and assignment will create a new instance (address changed)
                'energies'    : zeros(shape=(1)  , dtype=float64),
                'temperatures': zeros(shape=(1)  , dtype=float64),
                'frequencies' : zeros(shape=(1,3), dtype=float64),
                'gradients'   : zeros(shape=(1,3), dtype=float64),
                'natoms'      : 0,
                'kinetics'    : zeros(shape=(1)  , dtype=float64),
                'opt_energies': zeros(shape=(1)  , dtype=float64),
                'potentials'  : zeros(shape=(1)  , dtype=float64),
                'znums'       : zeros(shape=(1,) , dtype=int64),
              }

    _fields = 'znums', 'gradients'

    synons = { 'natoms':'npts' }
    _synons = {
                'natoms'     :'npts',
                'gradients'  :'xyz',
                'frequencies':'freq'
              }
                

    def resize(self, npts):
        ''''''

        self.kinetics.resize    (npts, refcheck=False)
        self.potentials.resize  (npts, refcheck=False)
        self.energies.resize    (npts, refcheck=False)
        self.temperatures.resize(npts, refcheck=False)


    @property
    def energies(self):
        '''Energy'''

        return self._energies


    @energies.setter
    def energies(self, val):
        '''Setter of energy'''

        from numpy import asarray

        self.resize(asarray(val).size)
        utils.nputils.setField(self._energies, val)

        
    @property
    def potentials(self):
        '''Potentials'''

        return self._potentials


    @potentials.setter
    def potentials(self, val):
        '''Setter of potentials'''

        from numpy import asarray

        self.resize(asarray(val).size)
        utils.nputils.setField(self._potentials, val)


    @property
    def kinetics(self):
        '''Kinetics'''

        return self._kinetics


    @kinetics.setter
    def kinetics(self, val):
        '''Setter of kinetics'''

        from numpy import asarray

        self.resize(asarray(val).size)
        utils.nputils.setField(self._kinetics, val)


    @property
    def temperatures(self):
        '''Temperatures'''

        return self._temperatures


    @temperatures.setter
    def temperatures(self, val):
        '''Setter of temperatures'''

        from numpy import asarray

        self.resize(asarray(val).size)
        utils.nputils.setField(self._temperatures, val)


    @property
    def gradients(self):
        '''Gradients'''

        return self._master.xyz


    @gradients.setter
    def gradients(self, val):
        '''Setter of gradients'''

        self._master.setField(val, field='xyz')


    @property
    def hessian(self):
        '''Hessian'''

        return self._master.hessian


    @hessian.setter
    def hessian(self, val):
        '''Setter of hessian'''

        self._master.setField(val, field='hessian')


    @property
    def potential(self):
        ''''''

        return self._master.potential


    @property
    def znums(self):
        '''Atomic numbers: (natoms,1)'''

        return self._master.znums


    @znums.setter
    @_XYZ._resize1D
    def znums(self, val):
        '''Setter of znums'''

        self._master.setField(val, field='znums')





















