#! /usr/bin/env python
#  -*- coding: utf-8 -*-
#
# GUI module generated by PAGE version 6.0.1
#  in conjunction with Tcl version 8.6
#    Mar 04, 2021 10:26:47 AM CET  platform: Windows NT


import sys
import os

try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk

try:
    import ttk
    py3 = False
except ImportError:
    import tkinter.ttk as ttk
    py3 = True
import tkinter.filedialog
import tkinter.messagebox


if __name__ == '__main__':
    import SCM
else:
    from . import SCM
import utils



global ImagingWinPath
ImagingWinPath = "C:/ImagingPamGigE/Data_RGB/"
global int_var, rep_var, temp_sep_var, pos_var
global val, root, top, PacManHndl


def set_tk_var():
    global int_var, rep_var, temp_sep_var, pos_var
    int_var = tk.IntVar()
    rep_var = tk.IntVar()
    pos_var = tk.StringVar()
    temp_sep_var = tk.IntVar()

def start(P_ptr = None):
    global ImagingWinPath
    if(P_ptr is None):
        path = os.getcwd()+"..\\"
        sys.path.append(path)
        import PacMan
        PCM = PacMan.PacMan()
    else:
        PCM = P_ptr 
    ImagingWinPath = PCM.settings['General']['imagingwininstalldir']
    vp_start_gui(PCM)
    PCM.IPam.load_acquisition_script()
    PCM.IPam.load_start_script()
    root.mainloop()  

def debug_start():
    vp_start_gui(1)
    root.mainloop()
    

def vp_start_gui(PCMHndl):
    '''Starting point when module is the main routine.'''
    global val, root, top
    root = tk.Tk()
    #Hide root window
    root.withdraw()
    set_tk_var()
    top = MainWnd (root,PMH = PCMHndl)
    #Ensure root window gets destroyed if top window gets closed
    top.protocol("WM_DELETE_WINDOW", root.destroy)

    
def load_AF():
    try:
        Threshold = float(window.dZMin_ent.get())
        Strength = float(window.AFStrength_ent.get())
        minCirc = float(window.minCirc_ent.get())
        minInert = float(window.minInert_ent.get())
        sizes = window.size_ent.get().split(',')
        utils.logmsg(f"Autofocus parameters changed to: {[Threshold,Strength,minCirc,minInert,int(sizes[0]),int(sizes[1])]}")
    except:
        print("One of the autofocus value was not correctly formmated")
    
def save_pos_list():
    print("Save pos list pressed")
    
    try:

        PacManHndl.StageCom.save_pos_list_file(ImagingWinPath+window.pos_list_ent.get())
    except Exception as e:
        exception_handler(e)
        
def load_pos_list():
    print("Load pos list pressed")
    try:
        PacManHndl.StageCom.load_pos_list_file(ImagingWinPath+window.pos_list_ent.get())
        update_pos_list()
    except Exception as e:
        exception_handler(e)

def rld_ipam():
    print("Reload IPAM button pressed")
    try:
        PacManHndl.IPam.initialize_connection()
    except Exception as e:
        exception_handler(e)

def rld_mm():
    print("Reload mm button pressed")
    try:
        PacManHndl.PMCom.reinit()
    except Exception as e:
        exception_handler(e)

def rld_pos():
    print('Reload pos script button pressed')
    try:
        PacManHndl.IPam.load_acquisition_script()
    except Exception as e:
        exception_handler(e)

def rld_start():
    print("Reload start script button pressed")
    try:
        PacManHndl.IPam.load_start_script()
    except Exception as e:
        exception_handler(e)

def send_serial_command():
   msg = window.ser_com_ent.get()
   window.ser_com_var.set("")
   #w.ser_com_ent.set("")
   if("log:" in msg[0:5]):
       utils.logmsg(msg)
   elif("Queue:" in msg[0:6]):
       timer_cmd = msg[6:]
       try:
           utils.logmsg(f"Queing following command:{timer_cmd}")
           PacManHndl.queue_command(timer_cmd)
       except Exception as e:
           exception_handler(e)
   elif("IPAM:" in msg[0:6]):
       print(f"Sending Manual IPAM Command:{msg[5:]}")
       IPAM_Cmd = msg[5:].split(",")

       PacManHndl.IPam.send_Command(IPAM_Cmd[0],IPAM_Cmd[1])
   elif("Prior:" in msg[0:7]):      
       prior_cmd = msg[6:]
       print(f"Sending Manual Serial Command:{prior_cmd}")
       try:
           utils.logmsg(PacManHndl.StageCom.msg_resp(prior_cmd))
       except Exception as e:
           exception_handler(e)

def update_pos_list():
    if(PacManHndl.StageCom.get_pos_list_length()>0):
        try:
            window.pos_list.delete(0,tk.END)
            for pos in PacManHndl.StageCom.Pos_List:
                formstring = f"{pos[0]} \t {pos[1]}"
                window.pos_list.insert(tk.END,formstring)
        except Exception as e:
            exception_handler(e)

def add_offset(index):
    try:
        print(index)
        PacManHndl.StageCom.add_offset(index[0], str(window.pos_name_var.get()))
        update_pos_list()
    except Exception as e:
        exception_handler(e)
            
def goto_sel_pos(index):
    print("Go to pos button pressed")
    try:
        index = int(index[0])
        PacManHndl.StageCom.go_to_position(index)
    except Exception as e:
        exception_handler(e)
        
def del_pos(index):
    try:
        window.pos_list.delete(index)
        PacManHndl.StageCom.remove_pos(index[0])
        update_pos_list()
    except Exception as e:
        exception_handler(f"Something went wrong when trying to delete a position. \n{e}")

def add_pos():
    try:
        PacManHndl.StageCom.add_pos(window.pos_name_var.get())
        showvar = PacManHndl.StageCom.get_pos(-1)
        formstring = f"{showvar[1]} \t {showvar[0]}"
        window.pos_list.insert(tk.END,formstring)
    except Exception as e:
        exception_handler(e)
    window.pos_name_var.set(f"Pos{PacManHndl.StageCom.get_pos_list_length()}")

def run_pos():
    print("Run position button pressed")
    try:
        PacManHndl.IPam.execute_queue([False, 'Pytest',0,0])
    except Exception as e:
        exception_handler(e)

def run_start():
    print("Run start script pressed")
    try:      
        name = window.pos_name_var.get()
        PacManHndl.IPam.execute_queue([True, f"{name}",0,0])
    except Exception as e:
        exception_handler(e)

def snap_img():
    print("Yield button pressed")
    try:
        PacManHndl.IPam.send_Command('Yield','')
    except Exception as e:
        exception_handler(e)

def run_exp():
    window.run_exp()
    
def exception_handler(exc):
    tb = exc.__traceback__
    msg = ""
    while(tb):
        msg = msg + "\n" + str.format("Exception in {}: {}. Exception {} ".format(tb.tb_frame.f_code.co_filename,tb.tb_lineno, exc))
        tb = tb.tb_next
    tk.messagebox.showerror("Exception", msg)
    


class MainWnd(tk.Toplevel):
    def __init__(self, root=None, master = None, PMH = None):
        global int_var, rep_var, pos_var
        global window, PacManHndl
        self.master = master
        tk.Toplevel.__init__(self)
        window = self
        top = self
        PacManHndl = PMH
        #self.icon = tk.PhotoImage(file = "PacMAN_LOGO_TRP.gif")
        #top.iconphoto(False, self.icon)
        icopath = os.path.abspath(__file__)[:-12]
        icopath += "PacMAN_LOGO_TRP.ico"
        self.iconbitmap(icopath)
        '''This class configures and populates the toplevel window.
           top is the toplevel containing window.'''
        _bgcolor = '#d9d9d9'  # X11 color: 'gray85'
        _fgcolor = '#000000'  # X11 color: 'black'
        _compcolor = '#d9d9d9' # X11 color: 'gray85'
        _ana1color = '#d9d9d9' # X11 color: 'gray85'
        _ana2color = '#ececec' # Closest X11 color: 'gray92'
        self.style = ttk.Style()
        if sys.platform == "win32":
            self.style.theme_use('winnative')
        self.style.configure('.',background=_bgcolor)
        self.style.configure('.',foreground=_fgcolor)
        self.style.map('.',background=
            [('selected', _compcolor), ('active',_ana2color)])
        
        
        top.geometry("600x280+550+200")
        top.minsize(120, 1)
        top.maxsize(3844, 1064)
        top.resizable(1,  1)
        top.title("PaCMAN")
        top.configure(background="#d9d9d9")
        top.configure(highlightbackground="#d9d9d9")
        top.configure(highlightcolor="black")

        self.tabControl = ttk.Notebook(top)
        self.main_tab = ttk.Frame(self.tabControl)
        self.tabControl.add(self.main_tab,text="Main")
        self.autofocus_tab = ttk.Frame(self.tabControl)
        #self.tabControl.add(self.autofocus_tab, text = "Autofocus",state="disabled")
        self.positions_tab = ttk.Frame(self.tabControl)
        self.tabControl.add(self.positions_tab, text = "Positions")
        
        #Style for all frames
        s = ttk.Style(top)
        s.configure('TFrame', background="#d9d9d9", highlightbackground="#d9d9d9",highlightcolor="black")
        
        self.action_frame = ttk.Frame(self.main_tab)
        self.action_frame.place(relx=0.02, rely=0.05, relheight=0.650
                , relwidth=0.549)
        self.action_frame.configure(relief='groove')
        self.action_frame.configure(borderwidth="2")
        self.action_frame.configure(relief="groove")
        #self.action_frame.configure(background="#d9d9d9")
        #self.action_frame.configure(highlightbackground="#d9d9d9")
        #self.action_frame.configure(highlightcolor="black")


        self.autofocus_frame = ttk.Frame(self.autofocus_tab)
        self.autofocus_frame.place(relx=0.02, rely=0.05, relheight=0.650
                , relwidth=0.9)
        self.autofocus_frame.configure(relief='groove')
        self.autofocus_frame.configure(borderwidth="2")
        self.autofocus_frame.configure(relief="groove")
        #Not operational
        self.tabControl.tab(1,state="normal")
        
########################################################################
##########################Positions TAB#################################
########################################################################

        baserely = 0.7
        baserelx = 0.45
        self.pos_list = tk.Listbox(self.positions_tab, selectmode='SINGLE')
        self.pos_list.place(relx = baserelx, rely = 0.08, relheight = 0.6, width = 300)
        
        self.pos_lbl = tk.Label(self.positions_tab, anchor = 'w')
        self.pos_lbl.place(relx=baserelx, rely=0, height=20, width=300)
        self.pos_lbl.configure(bg="#f9f9f9")
        self.pos_lbl.configure(fg="black")
        self.pos_lbl.configure(text ="X:      Y:      Z:      Name: ")
        
        self.go_to_btn = tk.Button(self.positions_tab)
        self.go_to_btn.place(relx=0.25, rely=0.6, height=24, width=80)
        self.go_to_btn.configure(activebackground="#ececec")
        self.go_to_btn.configure(activeforeground="#000000")
        self.go_to_btn.configure(background="#d9d9d9")
        self.go_to_btn.configure(command=lambda: goto_sel_pos(self.pos_list.curselection()))
        self.go_to_btn.configure(disabledforeground="#a3a3a3")
        self.go_to_btn.configure(foreground="#000000")
        self.go_to_btn.configure(highlightbackground="#d9d9d9")
        self.go_to_btn.configure(highlightcolor="black")
        self.go_to_btn.configure(pady="0")
        self.go_to_btn.configure(text='''Go To''')
        
        self.del_btn = tk.Button(self.positions_tab)
        self.del_btn.place(relx=0.05, rely=0.6, height=24, width=80)
        self.del_btn.configure(activebackground="#ececec")
        self.del_btn.configure(activeforeground="#000000")
        self.del_btn.configure(background="#d9d9d9")
        self.del_btn.configure(command=lambda: del_pos(self.pos_list.curselection()))
        self.del_btn.configure(disabledforeground="#a3a3a3")
        self.del_btn.configure(foreground="#000000")
        self.del_btn.configure(highlightbackground="#d9d9d9")
        self.del_btn.configure(highlightcolor="black")
        self.del_btn.configure(pady="0")
        self.del_btn.configure(text='''Delete Pos''')

        self.mark_btn = tk.Button(self.positions_tab)
        self.mark_btn.place(relx=0.05, rely=0.5, height=20, width=80)
        self.mark_btn.configure(activebackground="#ececec")
        self.mark_btn.configure(activeforeground="#000000")
        self.mark_btn.configure(background="#d9d9d9")
        self.mark_btn.configure(command=lambda: add_pos())
        self.mark_btn.configure(disabledforeground="#a3a3a3")
        self.mark_btn.configure(foreground="#000000")
        self.mark_btn.configure(highlightbackground="#d9d9d9")
        self.mark_btn.configure(highlightcolor="black")
        self.mark_btn.configure(pady="0")
        self.mark_btn.configure(text='''Add Pos''')
        
        self.offset_btn = tk.Button(self.positions_tab)
        self.offset_btn.place(relx=0.25, rely=0.5, height=20, width=80)
        self.offset_btn.configure(activebackground="#ececec")
        self.offset_btn.configure(activeforeground="#000000")
        self.offset_btn.configure(background="#d9d9d9")
        self.offset_btn.configure(command=lambda: add_offset(self.pos_list.curselection()))
        self.offset_btn.configure(disabledforeground="#a3a3a3")
        self.offset_btn.configure(foreground="#000000")
        self.offset_btn.configure(highlightbackground="#d9d9d9")
        self.offset_btn.configure(highlightcolor="black")
        self.offset_btn.configure(pady="0")
        self.offset_btn.configure(text='''Add Offset''')
        
        self.pos_name_var = tk.StringVar(value = "Pos0")

        self.pos_name_ent = tk.Entry(self.positions_tab)
        self.pos_name_ent.place(relx=0.1, rely=0.35, height=24, width=100)
        self.pos_name_ent.configure(background="white")
        self.pos_name_ent.configure(disabledforeground="#a3a3a3")
        self.pos_name_ent.configure(font="TkFixedFont")
        self.pos_name_ent.configure(foreground="#000000")
        self.pos_name_ent.configure(highlightbackground="#d9d9d9")
        self.pos_name_ent.configure(highlightcolor="black")
        self.pos_name_ent.configure(insertbackground="black")
        self.pos_name_ent.configure(selectbackground="blue")
        self.pos_name_ent.configure(selectforeground="white")
        self.pos_name_ent.configure(textvariable = self.pos_name_var)
        self.tooltip_font = "TkDefaultFont"
        self.Pos_index_tooltip = \
        ToolTip(self.pos_name_ent, self.tooltip_font, '''Write in the name of the position''')
        
        
        self.pos_list_var = tk.StringVar(value="Pos.txt")
        
        self.pos_list_ent = tk.Entry(self.positions_tab)
        self.pos_list_ent.place(relx=0.1, rely=0.05, height=24, width=80)
        self.pos_list_ent.configure(background="white")
        self.pos_list_ent.configure(disabledforeground="#a3a3a3")
        self.pos_list_ent.configure(font="TkFixedFont")
        self.pos_list_ent.configure(foreground="#000000")
        self.pos_list_ent.configure(highlightbackground="#d9d9d9")
        self.pos_list_ent.configure(highlightcolor="black")
        self.pos_list_ent.configure(insertbackground="black")
        self.pos_list_ent.configure(selectbackground="blue")
        self.pos_list_ent.configure(selectforeground="white")
        self.pos_list_ent.configure(textvariable = self.pos_list_var)
        
        self.save_pos_list_btn = tk.Button(self.positions_tab)
        self.save_pos_list_btn.place(relx=0.05, rely=0.18, height=20
                , width=80)
        self.save_pos_list_btn.configure(activebackground="#ececec")
        self.save_pos_list_btn.configure(activeforeground="#000000")
        self.save_pos_list_btn.configure(background="#d9d9d9")
        self.save_pos_list_btn.configure(command=lambda:save_pos_list())
        self.save_pos_list_btn.configure(disabledforeground="#a3a3a3")
        self.save_pos_list_btn.configure(foreground="#000000")
        self.save_pos_list_btn.configure(highlightbackground="#d9d9d9")
        self.save_pos_list_btn.configure(highlightcolor="black")
        self.save_pos_list_btn.configure(pady="0")
        self.save_pos_list_btn.configure(text='''Save List''')    
        
        self.load_pos_list_btn = tk.Button(self.positions_tab)
        self.load_pos_list_btn.place(relx=0.25, rely=0.18, height=20
                , width=80)
        self.load_pos_list_btn.configure(activebackground="#ececec")
        self.load_pos_list_btn.configure(activeforeground="#000000")
        self.load_pos_list_btn.configure(background="#d9d9d9")
        self.load_pos_list_btn.configure(command=lambda:load_pos_list())
        self.load_pos_list_btn.configure(disabledforeground="#a3a3a3")
        self.load_pos_list_btn.configure(foreground="#000000")
        self.load_pos_list_btn.configure(highlightbackground="#d9d9d9")
        self.load_pos_list_btn.configure(highlightcolor="black")
        self.load_pos_list_btn.configure(pady="0")
        self.load_pos_list_btn.configure(text='''Load List''')  
            
        

            
        # self.pos_lbl = tk.Message(self.positions_tab)
        # self.pos_lbl.place(relx=0.05, rely=0.3, height=100, width=60)
        # self.pos_lbl.configure(bg="#f9f9f9")
        # self.pos_lbl.configure(fg="black")
        # self.pos_lbl.configure(justify = tk.LEFT)
        # self.pos_lbl.configure(textvariable= pos_var)
        


        

########################################################################
##########################MAIN TAB######################################
########################################################################


        self.iterations_lbl = tk.Label(self.action_frame)
        self.iterations_lbl.place(relx=0.073, rely=0.22, height=18, width=64)
        self.iterations_lbl.configure(activebackground="#f9f9f9")
        self.iterations_lbl.configure(activeforeground="black")
        self.iterations_lbl.configure(background="#d9d9d9")
        self.iterations_lbl.configure(disabledforeground="#a3a3a3")
        self.iterations_lbl.configure(foreground="#000000")
        self.iterations_lbl.configure(highlightbackground="#d9d9d9")
        self.iterations_lbl.configure(highlightcolor="black")
        self.iterations_lbl.configure(text='''Iterations:''')

        self.iterations_ent = tk.Entry(self.action_frame)
        self.iterations_ent.place(relx=0.328, rely=0.22, height=20, relwidth=0.146)
        self.iterations_ent.configure(background="white")
        self.iterations_ent.configure(disabledforeground="#a3a3a3")
        self.iterations_ent.configure(font="TkFixedFont")
        self.iterations_ent.configure(foreground="#000000")
        self.iterations_ent.configure(highlightbackground="#d9d9d9")
        self.iterations_ent.configure(highlightcolor="black")
        self.iterations_ent.configure(insertbackground="black")
        self.iterations_ent.configure(selectbackground="blue")
        self.iterations_ent.configure(selectforeground="white")
        self.iterations_ent.configure(textvariable=rep_var)
        
        self.intervall_ent = tk.Entry(self.action_frame)
        self.intervall_ent.place(relx=0.328, rely=0.38, height=20
                , relwidth=0.146)
        self.intervall_ent.configure(background="white")
        self.intervall_ent.configure(disabledforeground="#a3a3a3")
        self.intervall_ent.configure(font="TkFixedFont")
        self.intervall_ent.configure(foreground="#000000")
        self.intervall_ent.configure(highlightbackground="#d9d9d9")
        self.intervall_ent.configure(highlightcolor="black")
        self.intervall_ent.configure(insertbackground="black")
        self.intervall_ent.configure(selectbackground="blue")
        self.intervall_ent.configure(selectforeground="white")
        self.intervall_ent.configure(textvariable=int_var)

        self.interval_lbl = tk.Label(self.action_frame)
        self.interval_lbl.place(relx=0.073, rely=0.38, height=18, width=70)
        self.interval_lbl.configure(activebackground="#f9f9f9")
        self.interval_lbl.configure(activeforeground="black")
        self.interval_lbl.configure(background="#d9d9d9")
        self.interval_lbl.configure(disabledforeground="#a3a3a3")
        self.interval_lbl.configure(foreground="#000000")
        self.interval_lbl.configure(highlightbackground="#d9d9d9")
        self.interval_lbl.configure(highlightcolor="black")
        self.interval_lbl.configure(text='''Interval(s):''')

        
        self.temp_sep_lbl = tk.Label(self.action_frame)
        self.temp_sep_lbl.place(relx=0.073, rely=0.54, height=18, width=80)
        self.temp_sep_lbl.configure(activebackground="#f9f9f9")
        self.temp_sep_lbl.configure(activeforeground="black")
        self.temp_sep_lbl.configure(background="#d9d9d9")
        self.temp_sep_lbl.configure(disabledforeground="#a3a3a3")
        self.temp_sep_lbl.configure(foreground="#000000")
        self.temp_sep_lbl.configure(highlightbackground="#d9d9d9")
        self.temp_sep_lbl.configure(highlightcolor="black")
        self.temp_sep_lbl.configure(text='''Pos time(s):''')

        self.temp_sep_ent = tk.Entry(self.action_frame)
        self.temp_sep_ent.place(relx=0.328, rely=0.54, height=20, relwidth=0.146)
        self.temp_sep_ent.configure(background="white")
        self.temp_sep_ent.configure(disabledforeground="#a3a3a3")
        self.temp_sep_ent.configure(font="TkFixedFont")
        self.temp_sep_ent.configure(foreground="#000000")
        self.temp_sep_ent.configure(highlightbackground="#d9d9d9")
        self.temp_sep_ent.configure(highlightcolor="black")
        self.temp_sep_ent.configure(insertbackground="black")
        self.temp_sep_ent.configure(selectbackground="blue")
        self.temp_sep_ent.configure(selectforeground="white")
        self.temp_sep_ent.configure(textvariable=temp_sep_var)
        
        self.exp_name_ent = tk.Entry(self.action_frame)
        self.exp_name_ent.place(relx=0.4, rely=0.054, height=18, width=104)
        self.exp_name_ent.configure(background="white")
        self.exp_name_ent.configure(disabledforeground="#a3a3a3")
        self.exp_name_ent.configure(font="TkFixedFont")
        self.exp_name_ent.configure(foreground="#000000")
        self.exp_name_ent.configure(highlightbackground="#d9d9d9")
        self.exp_name_ent.configure(highlightcolor="black")
        self.exp_name_ent.configure(insertbackground="black")
        self.exp_name_ent.configure(selectbackground="blue")
        self.exp_name_ent.configure(selectforeground="white")
        self.exp_name_ent.configure(textvariable=' ')
        
        self.exp_name_lbl = tk.Label(self.action_frame)
        self.exp_name_lbl.place(relx=0.073, rely=0.054, height=18, width=104)
        self.exp_name_lbl.configure(activebackground="#f9f9f9")
        self.exp_name_lbl.configure(activeforeground="black")
        self.exp_name_lbl.configure(background="#d9d9d9")
        self.exp_name_lbl.configure(disabledforeground="#a3a3a3")
        self.exp_name_lbl.configure(foreground="#000000")
        self.exp_name_lbl.configure(highlightbackground="#d9d9d9")
        self.exp_name_lbl.configure(highlightcolor="black")
        self.exp_name_lbl.configure(text='''Experiment Name:''')
        
        self.ser_com_var = tk.StringVar(value = "Serial Command")
        
        self.ser_com_ent = tk.Entry(self.action_frame)
        self.ser_com_ent.place(relx=0.05, rely=0.75, height=20, relwidth=0.55)
        self.ser_com_ent.configure(background="white")
        self.ser_com_ent.configure(disabledforeground="#a3a3a3")
        self.ser_com_ent.configure(font="TkFixedFont")
        self.ser_com_ent.configure(foreground="#000000")
        self.ser_com_ent.configure(highlightbackground="#d9d9d9")
        self.ser_com_ent.configure(highlightcolor="black")
        self.ser_com_ent.configure(insertbackground="black")
        self.ser_com_ent.configure(selectbackground="blue")
        self.ser_com_ent.configure(selectforeground="white")
        self.ser_com_ent.configure(textvariable=self.ser_com_var)
        ToolTip(self.ser_com_ent, self.tooltip_font, '''Enter commands to send. Formats: log:{msg} to send a message. 
                Else: IPAM:{Command},{Parameter} to send to ImagingWin, Prior:{Command} to send to prior. 
                Timer:{Repition}{Command}{Parameter} to queue commands for later iterations.''')
        
        
        self.send_ser_btn = tk.Button(self.action_frame)
        self.send_ser_btn.place(relx=0.65, rely=0.75, height=20, width=80)
        self.send_ser_btn.configure(activebackground="#ececec")
        self.send_ser_btn.configure(activeforeground="#000000")
        self.send_ser_btn.configure(background="#d9d9d9")
        self.send_ser_btn.configure(command=lambda: send_serial_command())
        self.send_ser_btn.configure(disabledforeground="#a3a3a3")
        self.send_ser_btn.configure(foreground="#000000")
        self.send_ser_btn.configure(highlightbackground="#d9d9d9")
        self.send_ser_btn.configure(highlightcolor="black")
        self.send_ser_btn.configure(pady="0")
        self.send_ser_btn.configure(text='''Send Com''')
        
                
        self.autofocus_flag = tk.BooleanVar()
        self.autofocus_flag.set(False)
        self.autofocus_box = ttk.Checkbutton(self.action_frame,text="Autofocus", variable = self.autofocus_flag)
        self.autofocus_box.place( relx=0.6, rely=0.25, height=30, width=80)
        
        self.dark_adapt_flag = tk.BooleanVar()
        self.dark_adapt_flag.set(False)
        self.autofocus_box = ttk.Checkbutton(self.action_frame,text="Dark-Adapt", variable = self.dark_adapt_flag)
        self.autofocus_box.place( relx=0.6, rely=0.4, height=30, width=85)

        self.run_exp_btn = tk.Button(top)
        self.run_exp_btn.place(relx=0.60, rely=0.8, height=40, width=160)
        self.run_exp_btn.configure(activebackground="#ececec")
        self.run_exp_btn.configure(activeforeground="#000000")
        self.run_exp_btn.configure(background="#d9d9d9")
        self.run_exp_btn.configure(command= lambda: self.run_exp())
        self.run_exp_btn.configure(disabledforeground="#a3a3a3")
        self.run_exp_btn.configure(foreground="#000000")
        self.run_exp_btn.configure(highlightbackground="#d9d9d9")
        self.run_exp_btn.configure(highlightcolor="black")
        self.run_exp_btn.configure(pady="0")
        self.run_exp_btn.configure(text='''Run Experiment''')

        self.settings_frm = ttk.Frame(self.main_tab)
        self.settings_frm.place(relx=0.60, rely=0.05, relheight=0.65
                , relwidth=0.30)
        self.settings_frm.configure(relief='groove')
        self.settings_frm.configure(borderwidth="2")
        self.settings_frm.configure(relief="groove")
        #self.settings_frm.configure(background="#d9d9d9")
        #self.settings_frm.configure(highlightbackground="#d9d9d9")
        #self.settings_frm.configure(highlightcolor="black")

        
        
        self.yield_btn = tk.Button(self.settings_frm)
        self.yield_btn.place(relx=0.1, rely=0.1, height=20, width=140)
        self.yield_btn.configure(activebackground="#ececec")
        self.yield_btn.configure(activeforeground="#000000")
        self.yield_btn.configure(background="#d9d9d9")
        self.yield_btn.configure(command= lambda: snap_img)
        self.yield_btn.configure(disabledforeground="#a3a3a3")
        self.yield_btn.configure(foreground="#000000")
        self.yield_btn.configure(highlightbackground="#d9d9d9")
        self.yield_btn.configure(highlightcolor="black")
        self.yield_btn.configure(pady="0")
        self.yield_btn.configure(text='''Yield''')  

        self.run_z_stack_btn = tk.Button(self.settings_frm)
        self.run_z_stack_btn.place(relx=0.1, rely=0.35, height=20, width=140)
        self.run_z_stack_btn.configure(activebackground="#ececec")
        self.run_z_stack_btn.configure(activeforeground="#000000")
        self.run_z_stack_btn.configure(background="#d9d9d9")
        self.run_z_stack_btn.configure(command=lambda:SCM.make_z_stack())
        self.run_z_stack_btn.configure(disabledforeground="#a3a3a3")
        self.run_z_stack_btn.configure(foreground="#000000")
        self.run_z_stack_btn.configure(highlightbackground="#d9d9d9")
        self.run_z_stack_btn.configure(highlightcolor="black")
        self.run_z_stack_btn.configure(pady="0")
        self.run_z_stack_btn.configure(text='''Make Z-Stack''') 
        self.run_z_stack_btn_tooltip = \
        ToolTip(self.run_z_stack_btn, self.tooltip_font, '''Give step and extent as "step,extent" ''')

        self.run_start_btn = tk.Button(self.settings_frm)
        self.run_start_btn.place(relx=0.1, rely=0.6, height=20, width=140)
        self.run_start_btn.configure(activebackground="#ececec")
        self.run_start_btn.configure(activeforeground="#000000")
        self.run_start_btn.configure(background="#d9d9d9")
        self.run_start_btn.configure(command=lambda:run_start())
        self.run_start_btn.configure(disabledforeground="#a3a3a3")
        self.run_start_btn.configure(foreground="#000000")
        self.run_start_btn.configure(highlightbackground="#d9d9d9")
        self.run_start_btn.configure(highlightcolor="black")
        self.run_start_btn.configure(pady="0")
        self.run_start_btn.configure(text='''Run Start Script''')   
        
        self.run_acq_btn = tk.Button(self.settings_frm)
        self.run_acq_btn.place(relx=0.1, rely=0.85, height=20, width=140)
        self.run_acq_btn.configure(activebackground="#ececec")
        self.run_acq_btn.configure(activeforeground="#000000")
        self.run_acq_btn.configure(background="#d9d9d9")
        self.run_acq_btn.configure(command=lambda:run_pos())
        self.run_acq_btn.configure(disabledforeground="#a3a3a3")
        self.run_acq_btn.configure(foreground="#000000")
        self.run_acq_btn.configure(highlightbackground="#d9d9d9")
        self.run_acq_btn.configure(highlightcolor="black")
        self.run_acq_btn.configure(pady="0")
        self.run_acq_btn.configure(text='''Run Acquisition Script''')   

        self.exp_progress = ttk.Progressbar(top, mode = 'determinate')
        self.exp_progress.place(relx=0.08, rely=0.85, relwidth=0.40 , height=22)
        self.exp_progress.configure(length="100")

        self.log_lbl = tk.Label(top, anchor = "w")
        self.log_lbl.place(relx=0.08, rely=0.75, height=20, width=340)
        self.log_lbl.configure(activebackground="#f9f9f9")
        self.log_lbl.configure(activeforeground="black")
        self.log_lbl.configure(background="#d9d9d9")
        self.log_lbl.configure(disabledforeground="#a3a3a3")
        self.log_lbl.configure(foreground="#000000")
        self.log_lbl.configure(highlightbackground="#d9d9d9")
        self.log_lbl.configure(highlightcolor="black")
        self.log_lbl.configure(text='''Log:''')
        
        #self.log_box = tk.Listbox(top, selectmode='SINGLE')
        #self.log_box.place(relx = 0.08 rely = 0.5, relheight = 0.6, width = 300)
#########################################################################
##########################AutoFocus######################################
#########################################################################

        row_pos = 0.15
        col_pos = 0.25
        lbl_w = 0.15
        ent_w=0.08
        self.use_PLLS = tk.IntVar()
        self.use_LPL = tk.IntVar()
        
        self.dZMin_lbl = tk.Label(self.autofocus_frame)
        self.dZMin_lbl.place(relx=0.05, rely=row_pos, height=25, relwidth=lbl_w)
        self.dZMin_lbl.configure(activebackground="#f9f9f9")
        self.dZMin_lbl.configure(activeforeground="black")
        self.dZMin_lbl.configure(background="#d9d9d9")
        self.dZMin_lbl.configure(disabledforeground="#a3a3a3")
        self.dZMin_lbl.configure(foreground="#000000")
        self.dZMin_lbl.configure(highlightbackground="#d9d9d9")
        self.dZMin_lbl.configure(highlightcolor="black")
        self.dZMin_lbl.configure(text='''AF Threshold:''')

        self.dZMin_ent = tk.Entry(self.autofocus_frame)
        self.dZMin_ent.place(relx=col_pos, rely=row_pos, height=20, relwidth=ent_w)
        self.dZMin_ent.configure(background="white")
        self.dZMin_ent.configure(disabledforeground="#a3a3a3")
        self.dZMin_ent.configure(font="TkFixedFont")
        self.dZMin_ent.configure(foreground="#000000")
        self.dZMin_ent.configure(highlightbackground="#d9d9d9")
        self.dZMin_ent.configure(highlightcolor="black")
        self.dZMin_ent.configure(insertbackground="black")
        self.dZMin_ent.configure(selectbackground="blue")
        self.dZMin_ent.configure(selectforeground="white")
        
        self.AFStrength_lbl = tk.Label(self.autofocus_frame)
        self.AFStrength_lbl.place(relx=col_pos+0.1, rely=row_pos, height=25, relwidth=lbl_w)
        self.AFStrength_lbl.configure(activebackground="#f9f9f9")
        self.AFStrength_lbl.configure(activeforeground="black")
        self.AFStrength_lbl.configure(background="#d9d9d9")
        self.AFStrength_lbl.configure(disabledforeground="#a3a3a3")
        self.AFStrength_lbl.configure(foreground="#000000")
        self.AFStrength_lbl.configure(highlightbackground="#d9d9d9")
        self.AFStrength_lbl.configure(highlightcolor="black")
        self.AFStrength_lbl.configure(text='''AF Strength:''')

        self.AFStrength_ent = tk.Entry(self.autofocus_frame)
        self.AFStrength_ent.place(relx=col_pos*2, rely=row_pos, height=20, relwidth=ent_w)
        self.AFStrength_ent.configure(background="white")
        self.AFStrength_ent.configure(disabledforeground="#a3a3a3")
        self.AFStrength_ent.configure(font="TkFixedFont")
        self.AFStrength_ent.configure(foreground="#000000")
        self.AFStrength_ent.configure(highlightbackground="#d9d9d9")
        self.AFStrength_ent.configure(highlightcolor="black")
        self.AFStrength_ent.configure(insertbackground="black")
        self.AFStrength_ent.configure(selectbackground="blue")
        self.AFStrength_ent.configure(selectforeground="white")     
        
        self.minCirc_lbl = tk.Label(self.autofocus_frame)
        self.minCirc_lbl.place(relx=0.05, rely=row_pos*2, height=25, relwidth=lbl_w)
        self.minCirc_lbl.configure(activebackground="#f9f9f9")
        self.minCirc_lbl.configure(activeforeground="black")
        self.minCirc_lbl.configure(background="#d9d9d9")
        self.minCirc_lbl.configure(disabledforeground="#a3a3a3")
        self.minCirc_lbl.configure(foreground="#000000")
        self.minCirc_lbl.configure(highlightbackground="#d9d9d9")
        self.minCirc_lbl.configure(highlightcolor="black")
        self.minCirc_lbl.configure(text='''Min circularity:''')

        self.minCirc_ent = tk.Entry(self.autofocus_frame)
        self.minCirc_ent.place(relx=col_pos, rely=row_pos*2, height=20, relwidth=ent_w)
        self.minCirc_ent.configure(background="white")
        self.minCirc_ent.configure(disabledforeground="#a3a3a3")
        self.minCirc_ent.configure(font="TkFixedFont")
        self.minCirc_ent.configure(foreground="#000000")
        self.minCirc_ent.configure(highlightbackground="#d9d9d9")
        self.minCirc_ent.configure(highlightcolor="black")
        self.minCirc_ent.configure(insertbackground="black")
        self.minCirc_ent.configure(selectbackground="blue")
        self.minCirc_ent.configure(selectforeground="white")
        
        self.minInert_lbl = tk.Label(self.autofocus_frame)
        self.minInert_lbl.place(relx=0.1 + col_pos, rely=row_pos*2, height=25, relwidth=lbl_w)
        self.minInert_lbl.configure(activebackground="#f9f9f9")
        self.minInert_lbl.configure(activeforeground="black")
        self.minInert_lbl.configure(background="#d9d9d9")
        self.minInert_lbl.configure(disabledforeground="#a3a3a3")
        self.minInert_lbl.configure(foreground="#000000")
        self.minInert_lbl.configure(highlightbackground="#d9d9d9")
        self.minInert_lbl.configure(highlightcolor="black")
        self.minInert_lbl.configure(text='''Min Inertia:''')

        self.minInert_ent = tk.Entry(self.autofocus_frame)
        self.minInert_ent.place(relx=col_pos*2, rely=row_pos*2, height=20, relwidth=ent_w)
        self.minInert_ent.configure(background="white")
        self.minInert_ent.configure(disabledforeground="#a3a3a3")
        self.minInert_ent.configure(font="TkFixedFont")
        self.minInert_ent.configure(foreground="#000000")
        self.minInert_ent.configure(highlightbackground="#d9d9d9")
        self.minInert_ent.configure(highlightcolor="black")
        self.minInert_ent.configure(insertbackground="black")
        self.minInert_ent.configure(selectbackground="blue")
        self.minInert_ent.configure(selectforeground="white")   
        
        self.size_lbl = tk.Label(self.autofocus_frame)
        self.size_lbl.place(relx=0.1 + col_pos, rely=row_pos*3, height=25, relwidth=lbl_w)
        self.size_lbl.configure(activebackground="#f9f9f9")
        self.size_lbl.configure(activeforeground="black")
        self.size_lbl.configure(background="#d9d9d9")
        self.size_lbl.configure(disabledforeground="#a3a3a3")
        self.size_lbl.configure(foreground="#000000")
        self.size_lbl.configure(highlightbackground="#d9d9d9")
        self.size_lbl.configure(highlightcolor="black")
        self.size_lbl.configure(text='''Size filter:''')

        self.size_ent = tk.Entry(self.autofocus_frame)
        self.size_ent.place(relx=col_pos*2, rely=row_pos*3, height=20, relwidth=ent_w)
        self.size_ent.configure(background="white")
        self.size_ent.configure(disabledforeground="#a3a3a3")
        self.size_ent.configure(font="TkFixedFont")
        self.size_ent.configure(foreground="#000000")
        self.size_ent.configure(highlightbackground="#d9d9d9")
        self.size_ent.configure(highlightcolor="black")
        self.size_ent.configure(insertbackground="black")
        self.size_ent.configure(selectbackground="blue")
        self.size_ent.configure(selectforeground="white")   
        
        
        self.load_AF_btn = tk.Button(self.autofocus_frame)
        self.load_AF_btn.place(relx=0.6, rely=row_pos*5, height=30, width=150)
        self.load_AF_btn.configure(activebackground="#ececec")
        self.load_AF_btn.configure(activeforeground="#000000")
        self.load_AF_btn.configure(background="#d9d9d9")
        self.load_AF_btn.configure(command=lambda:load_AF())
        self.load_AF_btn.configure(disabledforeground="#a3a3a3")
        self.load_AF_btn.configure(foreground="#000000")
        self.load_AF_btn.configure(highlightbackground="#d9d9d9")
        self.load_AF_btn.configure(highlightcolor="black")
        self.load_AF_btn.configure(pady="0")
        self.load_AF_btn.configure(text='''Set Autofocus parameters''')
        
        self.AF_calibration_btn = tk.Button(self.autofocus_frame)
        self.AF_calibration_btn.place(relx=0.2, rely=row_pos*5, height=30, width=150)
        self.AF_calibration_btn.configure(activebackground="#ececec")
        self.AF_calibration_btn.configure(activeforeground="#000000")
        self.AF_calibration_btn.configure(background="#d9d9d9")
        self.AF_calibration_btn.configure(command=lambda:self.calibration_Window())
        self.AF_calibration_btn.configure(disabledforeground="#a3a3a3")
        self.AF_calibration_btn.configure(foreground="#000000")
        self.AF_calibration_btn.configure(highlightbackground="#d9d9d9")
        self.AF_calibration_btn.configure(highlightcolor="black")
        self.AF_calibration_btn.configure(pady="0")
        self.AF_calibration_btn.configure(text='''Autofocus Calibration''')
        
        self.use_LPL_chk = ttk.Checkbutton(self.autofocus_frame,text="Use Laplacian scoring",variable = self.use_LPL)
        self.use_LPL_chk.place(relx=col_pos*2+0.15, rely=row_pos*1)
        
        self.use_PLLS_chk = ttk.Checkbutton(self.autofocus_frame, text="Use Power-log-log-scoring",variable = self.use_PLLS)
        self.use_PLLS_chk.place(relx=col_pos*2+0.15,rely=row_pos*2)
        

########################################################################
##########################Rest######################################
########################################################################

        self.log_positions = tk.BooleanVar()
        self.log_positions.set(False)
        self.menubar = tk.Menu(top,font="TkMenuFont",bg=_bgcolor,fg=_fgcolor)
        top.configure(menu = self.menubar)

        self.main_menubar  = tk.Menu(self.menubar, tearoff = 0)
        self.main_menubar.add_command(
                label="Initialize Encoder", command = lambda: PacManHndl.StageCom.init_encoder())
        self.main_menubar.add_command(
                label="Reload Stage Connection", command = lambda: PacManHndl.StageCom.reinit())
        self.main_menubar.add_command(
                label="Reload IPam Connection", command = lambda: PacManHndl.IPam.initialize_connection())
        self.main_menubar.add_command(
                label="Cancel Experiment", command = lambda: PacManHndl.cancel_exp())
        self.menubar.add_cascade(label = 'Main', menu = self.main_menubar)
                

        self.settings_menubar  = tk.Menu(self.menubar, tearoff = 0)
        self.settings_menubar.add_command(
                label="Select Experiment Directory", command = lambda: PacManHndl.select_exp_dir(tk.filedialog.askdirectory(mustexist = True)))
        self.settings_menubar.add_command(
                label="Set communications port (SCM)", command = lambda: self.changeComPort("SCM"))
        self.settings_menubar.add_command(
                label="Set communications port (IRHM)", command = lambda: self.changeComPort("IRHM"))
        self.settings_menubar.add_checkbutton(
                label="Log position movements (Movements.txt)", onvalue=1,offvalue=0,variable = self.log_positions)
        
        self.script_menubar  = tk.Menu(self.menubar, tearoff = 0)
        self.script_menubar.add_command(
                label="Run start Script", command = lambda: rld_start())
        self.script_menubar.add_command(
                label="Run acquistion Script", command = lambda: rld_pos())
        self.script_menubar.add_command(
                label="Select Start Script", command = lambda: PacManHndl.set_start_script(tk.filedialog.askopenfilename()))
        self.script_menubar.add_command(
                label="Select Position Script", command = lambda: PacManHndl.set_pos_script(tk.filedialog.askopenfilename()))
        self.help_menubar = tk.Menu(self.menubar,tearoff=0)
        self.help_menubar.add_command(
            label = "Open manual", command = "")
        self.help_menubar.add_command(
            label = "About", command = lambda: self.popupmsg())
        self.menubar.add_cascade(label = 'Settings', menu = self.settings_menubar)
        self.menubar.add_cascade(label = 'Scripts', menu = self.script_menubar)
        self.menubar.add_cascade(label = 'Help', menu = self.help_menubar)
        self.menubar.add_command(label="Exit", command=lambda:destroy_window())

        self.tabControl.pack(expand = 1, fill = 'both')
        
    def run_exp(self):
        print("Run experiment button pressed")
        try:
            if(int(self.intervall_ent.get()) < 1 or int(self.iterations_ent.get()) < 1):
                raise ValueError("Experiment repetitions or Experiment Intervalls are either below zero or not correctly formatted")
            if(PacManHndl.StageCom.get_pos_list_length() < 1):
                print("DEBUG POSITIONS LOADED")
                PacManHndl.StageCom.load_pos_list_file()
                update_pos_list()
            self.run_exp_btn.configure(text = "Cancel Experiment")
            self.run_exp_btn.configure(command = lambda: self.cancel_exp())
            PacManHndl.run_experiment(self, [self.exp_name_ent.get(), rep_var.get(), int_var.get(), temp_sep_var.get(), self.autofocus_flag.get(),self.dark_adapt_flag.get(),self.log_positions], True)
            self.reset_exp()
        except Exception as e:
            exception_handler(e)
    
    def cancel_exp(self):
        tk.messagebox.showwarning("Experiment cancelled")
        PacManHndl.cancel_flag = True
        self.reset_exp()     
    
    def reset_exp(self):
         self.run_exp_btn.configure(text = "Run Experiment")
         self.run_exp_btn.configure(command = lambda: self.run_exp())
         self.exp_progress['value'] = 0
         update_pos_list()
    
    def calibration_Window(self):
        cal_wnd = tk.Toplevel(root)
        cal_wnd.title("Calibration Settings")
        cal_wnd.geometry("300x125")
        
        dist_label = tk.Label(cal_wnd,text="Z-range to calibrate over")
        str_label = tk.Label(cal_wnd, text = "Starting Strength")
        
        dist_str = tk.StringVar(cal_wnd,value="5.0")
        strength_str = tk.StringVar(cal_wnd,value="100")
        
        calib_LPL = tk.BooleanVar(cal_wnd,value = True)
        calib_PLLS = tk.BooleanVar(cal_wnd, value = False)
        
        dist_entry = tk.Entry(cal_wnd, textvariable = dist_str)
        str_entry = tk.Entry(cal_wnd, textvariable = strength_str)
        
        use_LPL_chk = ttk.Checkbutton(cal_wnd,text="Use Laplacian scoring",variable = calib_LPL)        
        use_PLLS_chk = ttk.Checkbutton(cal_wnd, text="Use Power-log-log-scoring",variable = calib_PLLS)
        
        yes_btn = tk.Button(cal_wnd,text="Run Calibration",command = lambda: PacManHndl.AutoFocuser.calibrate(
            IPAM = PacManHndl.IPam , SCMH = PacManHndl.SCM, useLPL = calib_LPL.get(), usePLLS = calib_PLLS.get(), startStrength = int(strength_str.get()), calibrationDistance = float(dist_str.get())))
        no_btn = tk.Button(cal_wnd,text="Cancel",command= lambda:cal_wnd.destroy())
        
        dist_label.grid(column=0,row = 0)
        str_label.grid(column=0,row = 1)
        
        dist_entry.grid(column=1,row = 0)
        str_entry.grid(column=1,row = 1)
       
        use_LPL_chk.grid(column=0,row = 2)
        use_PLLS_chk.grid(column=1,row = 2)
        
        yes_btn.grid(column=0,row = 3)
        no_btn.grid(column=1,row = 3)
    
    #Wrappers
    def update(self):
        root.update()
    
    def msg_box(self,title,msg):
        tk.messagebox.showwarning(title, msg)
        
    def on_autofocus_frame_Switch(self,event):
        settings = PacManHndl.AutoFocuser.GUIGetParams()
        self.dZMin_ent.delete(0,tk.END)
        self.dZMin_ent.insert(0,settings[0])
        self.Strength_ent.delete(0,tk.END)
        self.Strength_ent.insert(0,settings[1])
        self.minCirc_ent.delete(0,tk.END)
        self.minCirc_ent.insert(0,settings[2])
        self.minInertia_ent.delete(0,tk.END)
        self.minInertia_ent.insert(0,settings[3])
                
    def popupmsg(self):
        popup = tk.Tk()
    
        def leavemini():
            popup.destroy()
    
        version = "0.9beta, 2021-12-04"
        popup.wm_title("About")
        popup.wm_attributes('-topmost', True)     # keeps popup above everything until closed.
        popup.geometry("450x150")
        popup.configure(background="#d9d9d9")
        popup.configure(highlightbackground="#d9d9d9")
        popup.config(bd=2, relief=tk.FLAT)           # tk style
    
        # this next label (tk.button) is the text field holding your message. i put it in a tk.button so the sizing matched the "close" button
        # also want to note that my button is very big due to it being used on a touch screen application.
    
        about_string = ("PACMan was developed in the research group of Lars Behrendt @ Uppsala University, Department of Eco-Toxicology. \n"
                        "The primary developer was Olle Pontén. Special thanks are extended to Lars Behrendt and Jeanne Kutter. \n"
                        f"The current version is the {version}. PACMan is released as-is under a GPL v3 license with no guarantees whatsoever. Use with care. \n")
        #icon.pack(side = tk.LEFT)
        about_lbl = tk.Text(popup, height=7,width=120, background="#d9d9d9", highlightbackground="#d9d9d9", font = ("Helvetica",8),)
        #icon_lbl = tk.Label(popup,image=self.icon)
        #icon_lbl.pack(side=tk.LEFT)
        
        close_button = tk.Button(popup, text="Close", command=leavemini, width=10, height=2,
                                 background="#d9d9d9", relief=tk.GROOVE, activebackground="#ececec", foreground="#000000",
                                 activeforeground="#000000", highlightbackground="#d9d9d9", highlightcolor="black")
        
        about_lbl.pack()
        close_button.pack()
        about_lbl.insert(tk.INSERT,about_string)
        
        def changeComPort(self, target):
            if(target=="SCM"):
                newPort = tkinter.simpledialog.askinteger("IRHM COM-reset","Input new COM-port number to map SCM to.")
                self.PacManHndl.StageCom.prior_init(f"COM{newPort}")
            return
# ======================================================
# Support code for Balloon Help (also called tooltips).
# Found the original code at:
# http://code.activestate.com/recipes/576688-tooltip-for-tkinter/
# Modified by Rozen to remove Tkinter import statements and to receive
# the font as an argument.
# ======================================================

from time import time, localtime, strftime

class ToolTip(tk.Toplevel):
    """
    Provides a ToolTip widget for Tkinter.
    To apply a ToolTip to any Tkinter widget, simply pass the widget to the
    ToolTip constructor
    """
    def __init__(self, wdgt, tooltip_font, msg=None, msgFunc=None,
                 delay=0.5, follow=True):
        """
        Initialize the ToolTip

        Arguments:
          wdgt: The widget this ToolTip is assigned to
          tooltip_font: Font to be used
          msg:  A static string message assigned to the ToolTip
          msgFunc: A function that retrieves a string to use as the ToolTip text
          delay:   The delay in seconds before the ToolTip appears(may be float)
          follow:  If True, the ToolTip follows motion, otherwise hides
        """
        self.wdgt = wdgt
        # The parent of the ToolTip is the parent of the ToolTips widget
        self.parent = self.wdgt.master
        # Initalise the Toplevel
        tk.Toplevel.__init__(self, self.parent, bg='black', padx=1, pady=1)
        # Hide initially
        self.withdraw()
        # The ToolTip Toplevel should have no frame or title bar
        self.overrideredirect(True)

        # The msgVar will contain the text displayed by the ToolTip
        self.msgVar = tk.StringVar()
        if msg is None:
            self.msgVar.set('No message provided')
        else:
            self.msgVar.set(msg)
        self.msgFunc = msgFunc
        self.delay = delay
        self.follow = follow
        self.visible = 0
        self.lastMotion = 0
        # The text of the ToolTip is displayed in a Message widget
        tk.Message(self, textvariable=self.msgVar, bg='#FFFFDD',
                font=tooltip_font,
                aspect=1000).grid()

        # Add bindings to the widget.  This will NOT override
        # bindings that the widget already has
        self.wdgt.bind('<Enter>', self.spawn, '+')
        self.wdgt.bind('<Leave>', self.hide, '+')
        self.wdgt.bind('<Motion>', self.move, '+')

    def spawn(self, event=None):
        """
        Spawn the ToolTip.  This simply makes the ToolTip eligible for display.
        Usually this is caused by entering the widget

        Arguments:
          event: The event that called this funciton
        """
        self.visible = 1
        # The after function takes a time argument in milliseconds
        self.after(int(self.delay * 1000), self.show)

    def show(self):
        """
        Displays the ToolTip if the time delay has been long enough
        """
        if self.visible == 1 and time() - self.lastMotion > self.delay:
            self.visible = 2
        if self.visible == 2:
            self.deiconify()

    def move(self, event):
        """
        Processes motion within the widget.
        Arguments:
          event: The event that called this function
        """
        self.lastMotion = time()
        # If the follow flag is not set, motion within the
        # widget will make the ToolTip disappear
        #
        if self.follow is False:
            self.withdraw()
            self.visible = 1

        # Offset the ToolTip 10x10 pixes southwest of the pointer
        self.geometry('+%i+%i' % (event.x_root+20, event.y_root-10))
        try:
            # Try to call the message function.  Will not change
            # the message if the message function is None or
            # the message function fails
            self.msgVar.set(self.msgFunc())
        except:
            pass
        self.after(int(self.delay * 1000), self.show)

    def hide(self, event=None):
        """
        Hides the ToolTip.  Usually this is caused by leaving the widget
        Arguments:
          event: The event that called this function
        """
        self.visible = 0
        self.withdraw()

    def update(self, msg):
        """
        Updates the Tooltip with a new message. Added by Rozen
        """
        self.msgVar.set(msg)

# ===========================================================
#                   End of Class ToolTip
# ===========================================================

if __name__ == '__main__':
    debug_start()
    

