import genanki
import tkinter
from tkinter import ttk
from tkinter import filedialog
import loaders  

class MainFrame(ttk.Frame):
    def __init__(self, parent, *args, **kwargs):
        ttk.Frame.__init__(self, parent, *args, **kwargs)
        self.root = parent
        self.init_gui()
        self.words = {}
 
    def init_gui(self):
        """Builds GUI."""
        self.root.title('AnkiMaker')     
        self.grid(column=0, row=0, sticky='nsew')
        
        lists_width = 10
        
        
        # Loaders frame              
              
        loader_list = [loaders.KindleLoader,
                       loaders.FileLoader,
                       loaders.OEDLoader,
                       loaders.WikLoader]
        
        self.loaders = []
        for l in loader_list:
            # initialize every loader's frame with the mainframe as parent
            self.loaders.append(l(self))
        
        # Loaders list
        
        self.list = tkinter.Listbox(self, width = lists_width, 
                                    height = 8,
                                    selectmode = tkinter.SINGLE)
        self.list.grid(column=0, row=0, sticky = 'N')
        for op in self.loaders:
            self.list.insert(tkinter.END, op.name)   
        self.list.bind('<<ListboxSelect>>', self.select)
        

        self.list.selection_set(0)      

        # Deck creation frame
        
        self.dframe = DeckFrame(self)
        self.dframe.grid(column=0, row=1, columnspan = 4)
        self.dframe.disable()
        
        # Add padding to everything
        for child in self.winfo_children():
            child.grid_configure(padx=5, pady=5)
                                            
        self.select()
            
            
            
    def add_words(self, words):
        # Adds entries to the table if they are not there already
        self.dframe.add_words(words)    
        for w in words:
            if not w in self.words:
                self.words[w] = {}
                
#        self.activate_infoloaders()
        self.dframe.activate()
        
    def get_words(self):
        return self.words.keys()
        
    def add_info(self, col_name, words):
        # Adds entries to the table if they are not there already
        self.dframe.add_info(col_name, words)
        for w in words:
            if w in self.words:
                self.words[w][col_name] = words[w]
        
            
    def select(self, event = None):
        current_selection = self.list.curselection() # a tuple of selected
        if len(current_selection): # if there is a selected one
            index = current_selection[0]
            for l in self.loaders:
                l.grid_forget()
            self.loaders[index].grid(column=1, row=0, sticky = 'N')
            self.loaders[index].grid_configure(padx=5, pady=5)    


    
        
class DeckFrame(ttk.Frame):
        
    def __init__(self, parent, *args, **kwargs):
        ttk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        # this dictionary will store the index of every field
#        self.columns = {}
        self.columns = {'Question':'#0', 'Answer':'#1'}
        self.init_frame()
  
        
    def init_frame(self):
        columns = ['#' + str(c) for c in range(1, 10)]
        self.words_table = ttk.Treeview(self, columns = columns, 
                                        displaycolumns = ['#1'])
        self.words_table.grid(column= 0, row= 0, columnspan= 5)
        
        # this dictionary will store the index of every field
        
        self.words_table.heading('#0', text = 'Question',
                                 command = lambda: self.sort_table_by('#0'))
        self.words_table.heading('#1', text = 'Answer',
                                 command = lambda: self.sort_table_by('#1'))
        
        ttk.Label(self, text='Anki deck name:').grid(column=0, row=1)
        self.name_entry = ttk.Entry(self, width=20)
        self.name_entry.grid(column=1, row=1, columnspan = 1)
        
        ttk.Label(self, text='File').grid(column=2, row=1)
        self.file_entry = ttk.Entry(self, width=25)
        self.file_entry.grid(column=3, row=1, columnspan = 1)
      
        self.browse_button = ttk.Button(self, text='Browse',
                                      command=self.select_file)
        self.browse_button.grid(column=4, row=1, columnspan = 1)
        
      
        self.create_button = ttk.Button(self, text='Create',
                                      command=self.create_deck)
        self.create_button.grid(column=5, row=1, columnspan = 1)
        

     
        # Add padding to everything
        for child in self.winfo_children():
            child.grid_configure(padx=5, pady=5)
            
    def activate(self):
        self.browse_button.state(['!disabled'])
        self.create_button.state(['!disabled'])
            
    def disable(self):
        self.browse_button.state(['disabled'])
        self.create_button.state(['disabled'])
            
    def add_column(self, name):
        if not name in self.columns:
            cid = '#' + str(len(self.columns))
            self.columns[name] = cid
            new_columns = self.words_table.cget('displaycolumns') + (cid,)
            self.words_table.configure(displaycolumns = new_columns)
            
            sort_command = lambda: self.sort_table_by(cid)
            self.words_table.heading(cid, text = name,
                                     command = sort_command)

    def add_words(self, words):
        # Adds entries to the table if they are not there already
        # words: a list of words to be added
        for w in words:
            if not self.words_table.exists(w):
                self.words_table.insert('', 'end', w, text=w)
                
    
    def add_info(self, col_name, info):
        # Adds entries to the table if they are not there already.
        # Columns will be created if they don't exist yet
        # col_name: a string with the name of the relevant field
        # words_info: a dictionary of dictionaries with the words
        # as keys and the information as values
    
        # Maybe join this methoed with add_words, so that if the
        # words passed to this one don't exists new entries are added
        self.add_column(col_name)
        for w in info:
            if self.words_table.exists(w):
                self.words_table.set(w, self.columns[col_name], info[w])
    
    def select_file(self):
        options = {'defaultextension':'apkg',
                   'parent':self,
                   'title':'Select the Anki deck location'}
        self.filename = filedialog.asksaveasfilename(**options)
        if self.filename != '': 
            self.file_entry.delete(0, tkinter.END)
            self.file_entry.insert(0, self.filename)
            

        
    def create_deck(self):

        deck = genanki.Deck(2059400110, self.name_entry.get())
        
        fields = []
        for f in self.columns.keys(): # for each field
            fields.append({'name':f})
        model = genanki.Model(
            1607392319,
            'Word',
            fields=fields,
            templates=[
                {
                    'name': 'Card 1',
                    'qfmt': '{{Question}}',
                    'afmt': '<b>{{FrontSide}}</b>: {{Answer}}<hr id="usage">{{Usage}}'
                }]
        )
        
        for w in self.parent.words:
            fields = []
            for f in self.columns.keys(): # for each field
                if f == 'Question':
                    fields.append(w)
                else:
                    fields.append(self.parent.words[w][f])
            note = genanki.Note(
                model=model,
                fields=fields
                )
            deck.add_note(note)
    
        genanki.Package(deck).write_to_file(self.file_entry.get())
        

        
    def sort_table_by(self, column):
        print('Sorting by' + column)
    
    
if __name__ == '__main__':
    root = tkinter.Tk()
    MainFrame(root)
    root.mainloop()