import matplotlib.pyplot as plt
import matplotlib.cm as cm

import tensorflow as tf
import openbabel as ob

import tkinter as tk
from tkinter import filedialog

import os, glob
from PIL import Image, ImageTk

import numpy as np

from ofrcalc.routines.iomanager import loadInputFile, velocityValidator, genInputFile  
from ofrcalc.routines.iomanager import resultWriter, gradientPicSave, loadANNModel
from ofrcalc.routines.procsmiles import invokeFromSmiles



def main():


    def generate_COF_graph(resultsList):

        """
        Draws a simple lineplot of the COF vs velocity
        for each OFR-temperature combinations        
        """
        # draw a graph of velocity vs COF
        
        # organize the data
        plotting_results = {}
        for results in resultsList:
            velos =  [float(cn[3]) for  i,cn in enumerate(results["conditions"]) if cn[5] == "medium"]
            temps =  [float(cn[4]) for  i,cn in enumerate(results["conditions"]) if cn[5] == "medium"]
            COFs =  [results["predictions"][i][0] for i,cn in enumerate(results["conditions"]) if cn[5] == "medium"]
            for tt in set(temps):
                unique_name = results["conditions"][0][0] + '@' + str(int(tt)) + 'C'
                this_v = [velos[i] for i,t in enumerate(temps) if t == tt]
                this_cof = [COFs[i] for i,t in enumerate(temps) if t == tt]
                plotting_results.update({unique_name:{'velos':this_v,'COFs':this_cof}})
                
        # qualitative colors to max readability                    
        number_of_colors = len(plotting_results.keys())
        smap = plt.get_cmap("Set2",number_of_colors)

        # draw the plot
        for i, keys in enumerate(plotting_results.keys()):
            plt.plot(plotting_results[keys]['velos'],plotting_results[keys]['COFs'],
                     label=keys,color=smap(i))
        plt.legend()
        plt.savefig('testfig.png',res=300,width=3.33,height=2.9,unit='in')
        plt.close()

    def open_file():
        
        filename = filedialog.askopenfilename(initialdir="./",title = "Select file",
                                                     filetypes = (("text files","*.txt"),("cdxml files","*.cdxml"),("all files","*.*")))
        # ("cdxml files","*.cdxml")
        return filename

    def openfile_display():
        
        fname = open_file()
        
        # This creates the text field
        #greeting_display = tk.Text(master=window, height=10,width=30)
        entry1.delete(0, "end") 
        entry1.insert(tk.END,fname)
        
    def read_file():
        
        filename=str(entry1.get())
        #with open(filename,'r') as mydata:
        #   lines=mydata.read()
        #load_cdxml(filename)
        if filename.split('.')[1] == 'cdxml':
            genInputFile(filename)
            filename=filename.split('.')[0]+'.txt'
        with open(filename,'r') as output:
            lines=output.read()
        
        filecontent_display = tk.Text(master=window, height=10,width=30)
        filecontent_display.grid(column=0, row=3)
        
        filecontent_display.insert(tk.END,lines)
        filecontent_display.config(state='disable')
        
    def execute_ofrcalc():
        
        filename=str(entry1.get())
        if filename.split('.')[1] == 'cdxml':
            genInputFile(filename)
            filename=filename.split('.')[0]+'.txt'
        foldername=filename.split('.')[0]
        foldername=foldername.split('/')[len(foldername.split('/'))-1]
       
        ## start with loading the model
        NNdict = loadANNModel()
        print('loaded model successfully')
        
        
        ## load the input file
        inputList  = loadInputFile(filename)
        
        ## holder for results 
        resultsList = []
        
        ## loop over inputs
        thisPicdir = foldername+'-gui-pics/'
        for i, ins in enumerate(inputList):
            ins.update({'getGradients':True})
            ins.update({'absGradients':False})
            ins.update({'NNdict':NNdict})
            ins.update({'vrange':np.linspace(0.5,10,5)})
            results = invokeFromSmiles(**ins)
            resultsList.append(results)
            gradientPicSave(results, picDir = thisPicdir)
        
        generate_COF_graph(resultsList)
        
        thisResdir = foldername+'-gui-res/'
        resultWriter(resultsList,thisResdir)
        
        
        
        
        #myCmd = 'ofrcalc ' + filename
        #print(myCmd)
        #subprocess.run(myCmd,shell=True)
        
        
        res_name = foldername+'-gui-res/results.csv'
        with open(res_name,'r') as res_data:
            lines = res_data.read()
        
        filecontent_display = tk.Text(master=window, height=10,width=100)
        filecontent_display.grid(column=2, row=3)
        S = tk.Scrollbar(window, orient="vertical", command=filecontent_display.yview)
        S.grid(column=3,row=3,sticky='ns')
        filecontent_display.config(yscrollcommand=S.set)
        
        #horizontal sliding bar not working
        #S1 = tk.Scrollbar(window, orient="horizontal", command=filecontent_display.xview)
        #S1.grid(column=2,row=4,sticky='ew')
        #filecontent_display.config(xscrollcommand=S1.set)
        
        filecontent_display.insert(tk.END,lines)
        filecontent_display.config(state='disable')
        

        load2 = Image.open("testfig.png")
        width,height=load2.size
        print([width,height])
        #load2 = load2.resize((100,30))
        render2 = ImageTk.PhotoImage(load2)
        struct_pic_display2 = tk.Label(image=render2)
        struct_pic_display2.image = render2
        struct_pic_display2.grid(column=2,row=4)

        picglob = glob.glob(thisPicdir+'*.png')   
        load3 = Image.open(picglob[0])
        #load3 = load3.resize((100,30))
        width,height=load3.size
        print([width,height])
        render3 = ImageTk.PhotoImage(load3)
        struct_pic_display3 = tk.Label(image=render3)
        struct_pic_display3.image = render3
        struct_pic_display3.grid(column=0,row=4)
        
        
        #display a molecule picture
    #   load1 = Image.open("examplePic.png")
    #   width,height=load1.size
    #   #load = load.resize((40,20))
    #   render1 = ImageTk.PhotoImage(load1.resize((round(width/2),round(height/2))))
    #   struct_pic_display1 = tk.Label(image=render1)
    #   struct_pic_display1.image = render1
 
        
    def load_cdxml(cdxml):
        obconv = openbabel.OBConversion()  # ob Class
        obmol = openbabel.OBMol()  # ob Class
        obconv.SetInFormat('cdxml')  # ob Method to set cdxml
        obbconv.SetOutFormat('SMILES')
        obconv.ReadFile(obmol, cdxml)  # ob Method to reaad cdxml into a OBMol()
        
        mol = mol3D()
        mol.OBMol = obmol
        mol.convert2mol3D()
    

    # squelch some TF output
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
    os.environ['KMP_WARNINGS'] = '0'
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
    tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)
    try:
        from tensorflow.python.util import module_wrapper as deprecation
    except ImportError:
        from tensorflow.python.util import deprecation_wrapper as deprecation
    deprecation._PER_MODULE_WARNING_LIMIT = 0
   
    # squelch some OB output
    msghdlr = ob.OBMessageHandler()
    msghdlr.SetOutputLevel(0)
    
    
    window = tk.Tk()
    window.title("OFR Calculator")
    window.geometry("1000x600")    
    #------LABEL------
    label1 = tk.Label(text = "Welcome to OFR friction coefficients calculator v1.0!")
    label1.grid(column=0,row=0)

    label2 = tk.Label(text = "Import SMILES files or ChemDraw files ")
    label2.grid(column=0,row=1)

    #------ENTRIES------
    entry1 = tk.Entry()
    entry1.grid(column=1,row=1)

    #------BUTTON------
    botton1 = tk.Button(text = "Browse...", command=openfile_display)
    botton1.grid(column=2,row=1)

    botton2 = tk.Button(text = "Import", command=read_file)
    botton2.grid(column=1,row=2)

    botton3 = tk.Button(text = "Calculate", command=execute_ofrcalc)
    botton3.grid(column=1,row=3)

    #------

    window.mainloop()

if __name__ == '__main__':
    main()
#main()
