#!/usr/bin/env python

# pmx  Copyright Notice
# ============================
#
# The pmx source code is copyrighted, but you can freely use and
# copy it as long as you don't change or remove any of the copyright
# notices.
#
# ----------------------------------------------------------------------
# pmx is Copyright (C) 2006-2013 by Daniel Seeliger
#
#                        All Rights Reserved
#
# Permission to use, copy, modify, distribute, and distribute modified
# versions of this software and its documentation for any purpose and
# without fee is hereby granted, provided that the above copyright
# notice appear in all copies and that both the copyright notice and
# this permission notice appear in supporting documentation, and that
# the name of Daniel Seeliger not be used in advertising or publicity
# pertaining to distribution of the software without specific, written
# prior permission.
#
# DANIEL SEELIGER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS.  IN NO EVENT SHALL DANIEL SEELIGER BE LIABLE FOR ANY
# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# ----------------------------------------------------------------------

"""Functions to read the mutation database
"""

from .model import Model
from .atom import Atom
from .molecule import Molecule
from .parser import readSection, kickOutComments, parseList


def read_mutpdb(filename='mutations_oplsaa.pdb'):
    if not hasattr(filename, "read"):
        s = open(filename).read().split('ENDMDL')[:-1]
    else:
        s = filename.read().split('ENDMDL')[:-1]
    ml = []
    for entr in s:
        m = Model(pdbline=entr)
        ml.append(m)
    rdic = {}
    for m in ml:
        r = m.residues[0]
        rdic[r.resname] = r
    return rdic


def read_new_mtp_entry(entry, filename='mutres.mtp'):

    if not hasattr(filename, "read"):
        lst = open(filename).readlines()
    else:
        lst = filename.readlines()

    lst = kickOutComments(lst, ';')
    key = '[ '+entry+' ]'
    keyw = ('[ morphes ]', '[ atoms ]', '[ impropers ]', '[ dihedrals ]',
            '[ rotations ]', '[ coords ]')
    res = []
    for i, line in enumerate(lst):
        if line.startswith(key):
            for line2 in lst[i+1:]:
                if line2.startswith('[') and \
                   line2 not in keyw:
                    break
                else:
                    res.append(line2)

    morphes = {}
    ml = readSection(res, '[ morphes ]', '[')
    for i, line in enumerate(ml):
        entr = line.split()
        n0 = entr[0]
        t0 = entr[1]
        n1 = entr[3]
        t1 = entr[4]
        morphes[n0] = {
            't0': t0,
            'n1': n1,
            't1': t1,
            }
    atoms = []
    al = readSection(res, '[ atoms ]', '[')
    for i, line in enumerate(al):
        entr = line.split()
        name = entr[0]
        atomtype = entr[1]
        q = float(entr[2])
        cgnr = int(entr[3])
        m = float(entr[4])
        atomtypeB = entr[5]
        qB = float(entr[6])
        mB = float(entr[7])
        a = Atom(name=name, id=i+1, atomtype=atomtype, q=q, m=m, cgnr=cgnr,
                 atomtypeB=atomtypeB, qB=qB, mB=mB)
        atoms.append(a)
    mol = Molecule(atoms=atoms, unity='nm')
    mol.set_resname(entry)

    coords = readSection(res, '[ coords ]', '[')
    coords = parseList('fff', coords)
    for i, atom in enumerate(mol.atoms):
        atom.x = coords[i]
        atom.unity = 'A'
    il = readSection(res, '[ impropers ]', '[')
    imps = []
    for line in il:
        imps.append(line.split())
    diheds = []
    dl = readSection(res, '[ dihedrals ]', '[')
    for line in dl:
        diheds.append(line.split())
    rl = readSection(res, '[ rotations ]', '[')
    rots = []
    for line in rl:
        rots.append(line.split())
    rotdic = {}
    for rot in rots:
        key = rot[0]
        rotdic[key] = rot[1:]

    mol.morphes = morphes
    bonds = []
    return mol, bonds, imps, diheds, rotdic


def read_mtp_entry(entry, filename='ffamber99sb.mtp', version='old'):
    if version == 'new':
        return read_new_mtp_entry(entry, filename=filename)
    if not hasattr(filename, "read"):
        lst = open(filename).readlines()
    else:
        lst = filename.readlines()

    lst = kickOutComments(lst, ';')
    key = '[ '+entry+' ]'
    keyw = ('[ morphes ]', '[ atoms ]', '[ bonds ]', '[ impropers ]',
            '[ dihedrals ]', '[ rotations ]', '[ coords ]')
    res = []
    for i, line in enumerate(lst):
        if line.startswith(key):
            for line2 in lst[i+1:]:
                if line2.startswith('[') and \
                   line2 not in keyw:
                    break
                else:
                    res.append(line2)

    morphes = {}
    ml = readSection(res, '[ morphes ]', '[')
    for i, line in enumerate(ml):
        entr = line.split()
        n0 = entr[0]
        r0 = entr[1]
        t0 = entr[2]
        n1 = entr[4]
        r1 = entr[5]
        t1 = entr[6]
        morphes[n0] = {
            'r0': r0,
            't0': t0,
            'n1': n1,
            'r1': r1,
            't1': t1,
            }

    atoms = []
    al = readSection(res, '[ atoms ]', '[')
    for i, line in enumerate(al):
        entr = line.split()
        name = entr[0]
        atomtype = entr[1]
        q = float(entr[2])
        cgnr = int(entr[3])
        m = float(entr[4])
        atomtypeB = entr[5]
        qB = float(entr[6])
        mB = float(entr[7])
        a = Atom(name=name, id=i+1, atomtype=atomtype, q=q, m=m, cgnr=cgnr,
                 atomtypeB=atomtypeB, qB=qB, mB=mB)
        atoms.append(a)
    mol = Molecule(atoms=atoms, unity='nm')
    mol.set_resname(entry)

    coords = readSection(res, '[ coords ]', '[')
    coords = parseList('fff', coords)
    for i, atom in enumerate(mol.atoms):
        atom.x = coords[i]
        atom.unity = 'nm'
    bonds = []
    bl = readSection(res, '[ bonds ]', '[')
    for line in bl:
        bonds.append(line.split())
    imps = []
    il = readSection(res, '[ impropers ]', '[')
    for line in il:
        imps.append(line.split())
    diheds = []
    dl = readSection(res, '[ dihedrals ]', '[')
    for line in dl:
        diheds.append(line.split())
    rots = []
    rl = readSection(res, '[ rotations ]', '[')
    for line in rl:
        rots.append(line.split())
    rotdic = {}
    for rot in rots:
        key = rot[0]
        rotdic[key] = rot[1:]

    mol.morphes = morphes
    return mol, bonds, imps, diheds, rotdic


def read_mtp(filename='ffoplsaa.mtp'):

    if not hasattr(filename, "read"):
        lst = open(filename).readlines()
    else:
        lst = filename.readlines()
    lst = kickOutComments(lst, ';')

    keyw = ('[ atoms ]', '[ bonds ]', '[ impropers ]',
            '[ dihedrals ]', '[ rotations ]')

    entries = []
    for line in lst:
        if line.startswith('[') and line.strip() not in keyw:
            entries.append(line.strip()[1:-1].strip())
    rdic = {}
    for e in entries:
        rdic[e] = read_mtp_entry(e, filename)
    return rdic
