#!/usr/bin/python
from __future__ import print_function, absolute_import

import subprocess, sys, os, math, shutil
from os import listdir
from os.path import isfile, join

from pymol import cmd

#######################################
###########  P R E P A R E ############
#######################################

# Prepare structures via Pymol for Mopac or Gaussian
# Use in Pymol command prompt:
# run wSterimol.py
# run sterimoltools.py
# run setup.py
# run prepare_file.py
# prepare (directory, setup_path, verbose)
# example: prepare conformers

def prepare_file(directory = "temp", setup_path = "default", verbose = "False"):
    # If the directory exists
    if os.path.exists(directory):
        # Log generation
        log = Log()
        log.write("\n\n########################################\n###########  P R E P A R E  ############\n########################################\n\n")
        #verbose
        if verbose.lower() in ['true', '1', 't', 'y', 'yes']: verbose = True
        else: verbose = False
        # Retrieve all the files in the directory
        files = [f for f in listdir(directory) if isfile(join(directory, f))]
        if len(files) > 0:
            # get setup.ini
            setup = Setup(log, setup_path)
            if setup.isLoaded() == True:
                # modify the files
                for filename in files:
                    filesplit = filename.split(".")
                    if len(filesplit) > 1: # there is an extension
                        if filesplit[len(filesplit)-1] == "pdb": # is a pdb
                            if setup.software == "GAUSSIAN": # GAUSSIAN software
                                out = getinData(join(directory, "%s.pdb" % filesplit[0]))
                                # create file
                                lines = []
                                lines.append("%%mem=%sGB\n" % setup.memories )
                                lines.append("%%nprocshared=%s\n" % setup.procsshared)
                                lines.append("%%chk=%s.chk\n" % filesplit[0])
                                lines.append("# %s \n" % setup.leveloftheory) #maxcycles as a walltime
                                lines.append("\n")
                                lines.append("Generated by prepare_file.py\n")
                                lines.append("\n")
                                lines.append("%s %s\n" % (setup.charge,setup.spin) )
                                for i in range(len(out.ATOMTYPES)):
                                    lines.append(" %-2s              %13.8f %13.8f %13.8f\n" % ( out.ATOMTYPES[i], out.CARTESIANS[i][0], out.CARTESIANS[i][1], out.CARTESIANS[i][2] ))
                                lines.append("\n")
                                if setup.singlepointcalculation != "": # create a link to calculate the energy in a higher level of theory
                                    lines.append("--Link1--\n")
                                    lines.append("%%mem=%sGB\n" % setup.memories )
                                    lines.append("%%nprocshared=%s\n" % setup.procsshared)
                                    lines.append("%%chk=%s.chk\n" % filesplit[0])
                                    lines.append("# %s geom=check guess=read\n" % setup.singlepointcalculation)
                                    lines.append("\n")
                                    lines.append("Generated by prepare_file.py\n")
                                    lines.append("\n")
                                    lines.append("%s %s\n" % (setup.charge,setup.spin) )
                                    lines.append("\n")
                                #write
                                file = open(join(directory, "%s.com" % filesplit[0]),"w")
                                for line in lines:
                                    file.write(line)
                                file.close()
                                #remove pdb, useless
                                try: os.remove(join(directory, "%s.pdb" % filesplit[0]))
                                except: log.write("Error: The file [%s] couldn't be deleted" % join(directory, "%s.pdb" % filesplit[0]))
                            elif setup.software == "MOPAC": # MOPAC software
                                # horribly modify the pdb to be accepted by mopac, but works
                                lines = []
                                lines.append("%s charge=%s %s\n" % (setup.SE, setup.charge, setup.scf) )
                                lines.append("Generated by weighted sterimol script\n")
                                lines.append("\n")
                                #write
                                file = open(join(directory, filename),"r")
                                lines.extend(file.readlines())
                                file.close()
                                file = open(join(directory, filename),"w")
                                for line in lines:
                                    file.write(line)
                                file.close()
                                shutil.move(join(directory, filename), join(directory, filename.split(".")[0] + ".mop"))
                            elif setup.software == "ORCA": # ORCA software
                                out = getinData(join(directory, "%s.pdb" % filesplit[0]))
                                # create file
                                lines = []
                                lines.append("%s \n" % setup.leveloftheory) # "!PBEh-3c opt" for example
                                lines.append("Generated by prepare_file.py\n")
                                lines.append("%% pal nprocs %s end\n" % setup.procsshared) # "16" for instance
                                lines.append("%% maxcore %s\n" % setup.memories) # "4000" for instance  in MB
                                lines.append("%%scf maxiter 500\n")
                                lines.append("     end\n")
                                lines.append("% output\n")
                                lines.append("    printlevel mini\n")
                                lines.append("    print[ P_SCFInfo ] 1\n")
                                lines.append("    print[ P_SCFIterInfo ] 1\n")
                                lines.append("    print[ P_OrbEn ] 0\n")
                                lines.append("    print[ P_Cartesian ] 0\n")
                                lines.append("end\n")
                                lines.append("% elprop\n")
                                lines.append("    Dipole False\n")
                                lines.append("end\n")
                                lines.append("* xyz %s %s \n" % (setup.charge,setup.spin))
                                for i in range(len(out.ATOMTYPES)):
                                    lines.append(" %-2s%13.8f %13.8f %13.8f \n" % ( out.ATOMTYPES[i], out.CARTESIANS[i][0], out.CARTESIANS[i][1], out.CARTESIANS[i][2]))
                                lines.append("*\n")
                                #write
                                file = open(join(directory, "%s.inp" % filesplit[0]),"w")
                                for line in lines:
                                    file.write(line)
                                file.close()
                                #remove pdb
                                try: os.remove(join(directory, "%s.pdb" % filesplit[0]))
                                except: log.write("Error: The file [%s] couldn't be deleted" % join(directory, "%s.pdb" % filesplit[0]))
                            else:
                                log.write("Error: Software in setup.ini is not recognised. [%s]" % setup.software)
                                return False
                log.write("----------------------------\n---- Normal Termination ----\n----------------------------\n")
                log.finalize()
                return True
            else:
                log.write("Error: Failed to load setup.ini in [%s]. Fix it to continue." % setup_path)
                return False
        else: 
            log.write("Error: No file to modify in the directory [%s]" % directory)
            return False
    else: 
        print("FATAL ERROR: Specified directory doesn't exist [%s]" % directory)
        return False

cmd.extend("prepare",prepare_file)
