#!/usr/bin/env python3
#
# Simple ttk treeview with scrollbar and select button

import os
import json

import tkinter
from tkinter import ttk
import natsort
#------------------------------------------------------
# Tree view used as a multi-column list box
#------------------------------------------------------

class TreeViewChoice(ttk.Frame):
    def __init__(self, parent, fontsize=11, markDir=False, deferLoad=False, selectVal=None, natSort=False, *args, **kwargs):
        ttk.Frame.__init__(self, parent, *args, **kwargs)
        s = ttk.Style()
        s.configure('normal.TLabel', font=('Helvetica', fontsize))
        s.configure('title.TLabel', font=('Helvetica', fontsize, 'bold'))
        s.configure('normal.TButton', font=('Helvetica', fontsize),
			border = 3, relief = 'raised')
        s.configure('Treeview.Heading', font=('Helvetica', fontsize, 'bold'))
        s.configure('Treeview.Column', font=('Helvetica', fontsize))
        self.markDir = markDir
        self.initSelected = selectVal
        self.natSort = natSort
        self.emptyMessage1 = '(no items)'
        self.emptyMessage  = '(loading...)' if deferLoad else self.emptyMessage1

    # Last item is a list of 2-item lists, each containing the name of a button
    # to place along the button bar at the bottom, and a callback function to
    # run when the button is pressed.

    def populate(self, title, itemlist=[], buttons=[], height=10, columns=[0],
		versioning=False):
        self.itemlist = itemlist[:]
        
        treeFrame = ttk.Frame(self)
        treeFrame.pack(side='top', padx=5, pady=5, fill='both', expand='true')
        
        scrollBar = ttk.Scrollbar(treeFrame)
        scrollBar.pack(side='right', fill='y')
        self.treeView = ttk.Treeview(treeFrame, selectmode='browse', columns=columns, height=height)
        self.treeView.pack(side='left', fill='both', expand='true')
        scrollBar.config(command=self.treeView.yview)
        self.treeView.config(yscrollcommand=scrollBar.set)
        self.treeView.heading('#0', text=title, anchor='w')
        buttonFrame = ttk.Frame(self)
        buttonFrame.pack(side='bottom', fill='x')

        self.treeView.tag_configure('odd',background='white',foreground='black')
        self.treeView.tag_configure('even',background='gray90',foreground='black')
        self.treeView.tag_configure('select',background='darkslategray',foreground='white')

        self.func_buttons = []
        for button in buttons:
            func = button[2]
            # Each func_buttons entry is a list of two items;  first is the
            # button widget, and the second is a boolean that is True if the
            # button is to be present always, False if the button is only
            # present when there are entries in the itemlist.
            if(button[0]=='Flow'):
                self.flowcallback = func
                
            self.func_buttons.append([ttk.Button(buttonFrame, text=button[0],
			style = 'normal.TButton',
			command = lambda func=func: self.func_callback(func)),
			button[1]])
			
        self.selectcallback = None
        self.lastselected = None
        self.lasttag = None
        self.treeView.bind('<<TreeviewSelect>>', self.retag)
        self.repopulate(itemlist, versioning)
        self.treeView.bind('<Double-1>', self.test_callback)

    def test_callback(self, event):
        self.flowcallback(self.treeView.item(self.treeView.selection()))
        
    def get_button(self, index):
        if index >= 0 and index < len(self.func_buttons):
            return self.func_buttons[index][0]
        else:
            return None

    def retag(self, value):
        treeview = value.widget
        try:
            selection = treeview.selection()[0]
            oldtag = self.treeView.item(selection, 'tag')[0]
        except IndexError:
            # No items in view;  can't select the "(no items)" line.
            return

        self.treeView.item(selection, tag='selected')
        if self.lastselected:
            try:
                self.treeView.item(self.lastselected, tag=self.lasttag)
            except:
                # Last selected item got deleted.  Ignore this.
                pass
        if self.selectcallback:
            self.selectcallback(value)
        if (selection!=self.lastselected):
            self.lastselected = selection
            self.lasttag = oldtag
    
    #Populate the project view
    def repopulate(self, itemlist=[], versioning=False):
        # Remove all children of treeview
        self.treeView.delete(*self.treeView.get_children())

        if self.natSort:
            self.itemlist = natsort.natsorted( itemlist,
                                               alg=natsort.ns.INT |
                                               natsort.ns.UNSIGNED |
                                               natsort.ns.IGNORECASE )
        else:
            self.itemlist = itemlist[:]
            self.itemlist.sort()

        mode = 'even'
        m=0
        for item in self.itemlist:
            # Special handling of JSON files.  The following reads a JSON file and
            # finds key 'ip-name' in dictionary 'data-sheet', if such exists.  If
            # not, it looks for key 'project' in the top level.  Failing that, it
            # lists the name of the JSON file (which is probably an ungainly hash
            # name).
            
            fileext = os.path.splitext(item)
            if fileext[1] == '.json':
                # Read contents of JSON file
                with open(item, 'r') as f:
                    try:
                        datatop = json.load(f)
                    except json.decoder.JSONDecodeError:
                        name = os.path.split(item)[1]
                    else:
                        name = []
                        if 'data-sheet' in datatop:
                            dsheet = datatop['data-sheet']
                            if 'ip-name' in dsheet:
                                name = dsheet['ip-name']
                        if not name and 'project' in datatop:
                            name = datatop['project']
                        if not name:
                            name = os.path.split(item)[1]
            elif versioning == True:
                # If versioning is true, then the last path component is the
                # version number, and the penultimate path component is the
                # name.
                version = os.path.split(item)[1]   
                name = os.path.split(os.path.split(item)[0])[1] + ' (v' + version + ')'
            else:
                name = os.path.split(item)[1]

            # Watch for duplicate items!
            n = 0
            origname = name
            while self.treeView.exists(name):
                n += 1
                name = origname + '(' + str(n) + ')'
            # Note: iid value with spaces in it is a bad idea.
            if ' ' in name:
                name = name.replace(' ', '_')
            
            # optionally: Mark directories with trailing slash
            if self.markDir and os.path.isdir(item):
                origname += "/"
            if os.path.islink(item):
                origname += " (link)"
            
            if ('subcells' not in item):
                mode = 'even' if mode == 'odd' else 'odd'
                self.treeView.insert('', 'end', text=origname, iid=item, value=item, tag=mode)
            else:
                self.treeView.insert('', 'end', text=origname, iid=item, value=item, tag='odd')
            
            if 'subcells' in os.path.split(item)[0]:
            # If a project is a subproject, move it under its parent
                parent_path = os.path.split(os.path.split(item)[0])[0]
                parent_name = os.path.split(parent_path)[1]
                self.treeView.move(item,parent_path,m)
                m+=1
            else:
            # If its not a subproject, create a "subproject" of itself
            # iid shouldn't be repeated since it starts with '.'
                self.treeView.insert('', 'end', text=origname, iid='.'+item, value=item, tag='odd')
                self.treeView.move('.'+item,item,0)
                m=1
        
                       
        if self.initSelected and self.treeView.exists(self.initSelected):
            if 'subcells' in self.initSelected:
                # ancestor projects must be expanded before setting current
                item_path = self.initSelected
                ancestors = []
                while 'subcells' in item_path:
                    item_path = os.path.split(os.path.split(item_path)[0])[0]
                    ancestors.insert(0,item_path)
                for a in ancestors:
                    self.treeView.item(a, open=True)       
                self.setselect(self.initSelected)
            elif self.initSelected[0]=='.':
                parent_path = self.initSelected[1:]
                self.treeView.item(parent_path, open=True) 
                self.setselect(self.initSelected)
            else:
                self.setselect(self.initSelected)
            self.initSelected = None
        

        for button in self.func_buttons:
            button[0].pack_forget()

        if len(self.itemlist) == 0:
            self.treeView.insert('', 'end', text=self.emptyMessage)
            self.emptyMessage = self.emptyMessage1  # discard optional special 1st loading... message
            for button in self.func_buttons:
                if button[1]:
                    button[0].pack(side='left', padx = 5)
        else:
            for button in self.func_buttons:
                button[0].pack(side='left', padx = 5)

    # Return values from the treeview
    def getvaluelist(self):
        valuelist = []
        itemlist = self.treeView.get_children()
        for item in itemlist:
            value = self.treeView.item(item, 'values')
            valuelist.append(value)
        return valuelist

    # Return items (id's) from the treeview
    def getlist(self):
        return self.treeView.get_children()

    # This is a bit of a hack way to populate a second column,
    # but it works.  It only works for one additional column,
    # though, or else tuples will have to be generated differently.

    def populate2(self, title, itemlist=[], valuelist=[]):
        # Populate the pdk column
        self.treeView.heading(1, text = title)
        self.treeView.column(1, anchor='center')
        children=list(self.getlist()) 
        
        # Add id's of subprojects
        i=1
        def add_ids(grandchildren):
            # Recursively add id's of all descendants to the list
            nonlocal i
            for g in grandchildren:
                children.insert(i,g)
                i+=1
                descendants=self.treeView.get_children(item=g)
                add_ids(descendants)
        
        for c in list(self.getlist()):
            grandchildren=self.treeView.get_children(item=c)
            add_ids(grandchildren)
            i+=1
        
        n = 0
        for item in valuelist:
            child = children[n]
            # Get the value at this index
            oldvalue = self.treeView.item(child, 'values')
            newvalue = (oldvalue, item)
            self.treeView.item(child, values = newvalue)
            # Add pdk for the "copy" of the project that is made in the treeview
            if (n+1<len(children) and children[n+1]=='.'+child):
                valuelist.insert(n,item)
            n += 1
        
    def double_click(self, event):
        item = self.treeView.selection()[0]
        print("you clicked on", self.treeView.item(item,"text"))
        
    def func_callback(self, callback, event=None):
        callback(self.treeView.item(self.treeView.selection()))

    def bindselect(self, callback):
        self.selectcallback = callback

    def setselect(self, value):
        self.treeView.selection_set(value)
        
    def selected(self):
        value = self.treeView.item(self.treeView.selection())
        if value['values']:
            return value
        else:
            return None
