# import tkinter
try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk
try:
    from tkinter import *
except ImportError:
    print("import error")
try:
    from tkinter import filedialog
except ImportError:
    print("import error2")

import os
from winsound import Beep
from datetime import datetime, timedelta

#stopwatch description
# it's a tuple where the second item is a list of pair tuples

#delta,start end
#      start end
#      start end










#import datetime
#from datetime import datetime
#from datetime import timedelta
#import time
tic_time=5000
time_delta_zero=timedelta()

stopwatches=[]
gui_stopwatch_elements=[]
fn='blank'
appfont=("Consolas","15")
ledfont=("Consolas","30")
def buzz():
    for j in range(3):
        for i in range(3):
            Beep(480,300)
        #time.sleep(.400)
def time_format(n):
    s=int(n%60)
    m=int(n//60)
    h=int(m//60)
    m=m%60
    return '{:02d}:{:02d}:{:02d}'.format(h,m,s)
def time_format_time_delta(n):
    return datetime.utcfromtimestamp(n.seconds).strftime("%H:%M:%S")
def sum_stopwatch(n):
    sum=time_delta_zero
    for e in n['stamps']:
        sum+=e[1]-e[0]
    return sum
def write_file(data,fn,flags):
    fh=open(fn,flags)
    fh.write(data)
    fh.close()
def read_file(fn,flags):
    fh=open(fn,flags)
    rv=fh.read()
    fh.close()
    return rv
def str_stopwatches():
    rv=''
    for sw in stopwatches:
        rv+='name:'+sw['name']+'\n'
        rv+='elapsed:'+str(sw['elapsed'])+'\n'
        for stamp in sw['stamps']:
            rv+='\t'+str(stamp[0])+'\t'+str(stamp[1])+'\n'
    return rv
def save_timestamps():
    for i,gui_stopwatch in enumerate(gui_stopwatch_elements):
        stopwatches[i]['name']=gui_stopwatch[0].get()
    fn=str(datetime.now())
    fn=fn.replace(":",".")
    fn=fn[0:19]
    write_file(str_stopwatches(),fn+".ts.txt","wt")
def load_file(fn):
    s=read_file(fn,"rt")
    load_stopwatches(s)
def load_stopwatches(s):
    stopwatches.clear()
    for line in s.splitlines():
        if line[0:5]=="name:":
            stopwatches.append({"name":line[5:]})
            stopwatches[-1]["stamps"]=[]
        elif line[0:8]=="elapsed:":
            #stopwatches[-1]["elapsed"]=line[8:]
            stopwatches[-1]["elapsed"]=time_delta_zero
        else:
            v=line.split('\t')
            t1=datetime.strptime(v[1],'%Y-%m-%d %H:%M:%S.%f')
            t2=datetime.strptime(v[2],'%Y-%m-%d %H:%M:%S.%f')            
            stopwatches[-1]["stamps"].append([t1,t2])
    for stopwatch in stopwatches:
        for stamp in stopwatch['stamps']:
            stopwatch["elapsed"]+=stamp[1]-stamp[0]
def on_closing():
    for i,gui_stopwatch in enumerate(gui_stopwatch_elements):
        stopwatches[i]['name']=gui_stopwatch[0].get()
    root.destroy()
def donothing():
    pass

class Timer:
    def __init__(self, parent):
        self.sroot=parent
        self.active=False
        self.button_create = tk.Button(parent,
                                       font=appfont,
                                       text="CREATE NEW STOPWATCH",
                                       command=self.create_new_stopwatch_gui)
        self.button_create.grid(column=0,row=0,columnspan=2)
        menubar = tk.Menu(parent)
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(label="Load", command=self.ui_load_file)
        filemenu.add_command(label="Save", command=save_timestamps)
        filemenu.add_command(label="Debug", command=self.debug)
        filemenu.add_command(label="Destroy",command=self.destroy)
        filemenu.add_command(label="Exit",command=self.sroot.destroy)
        menubar.add_cascade(label="File",menu=filemenu)
        parent.config(menu=menubar)

    def create_new_stopwatch_gui(self):
        stopwatches.append({'name':'','elapsed':time_delta_zero,'stamps':[]})
        self.create_new_stopwatch()
    def create_new_stopwatch(self):
        gui_stopwatch_elements.append([])
        i=len(gui_stopwatch_elements)-1
        gui_stopwatch_elements[-1].append(tk.Entry(root,font=appfont))
        gui_stopwatch_elements[-1][-1].grid(column=0,row=i+1)

        gui_stopwatch_elements[-1].append(tk.Button(root,font=appfont,text="START",command=lambda: self.start_stopwatch(i)))
        gui_stopwatch_elements[-1][-1].grid(column=1,row=i+1)

        gui_stopwatch_elements[-1].append(tk.Button(root,font=appfont,text="STOP",command=lambda: self.stop_stopwatch(i)))
        gui_stopwatch_elements[-1][-1].grid(column=2,row=i+1)

        gui_stopwatch_elements[-1].append(tk.Label(root,font=ledfont,text="0:00:00"))
        gui_stopwatch_elements[-1][-1].grid(column=3,row=i+1)

    def destroy(self):
        #for i in range (len(gui_stopwatch_elements)):
        #    del(gui_stopwatch_elements[i])
        if gui_stopwatch_elements==[]: return
        for each in gui_stopwatch_elements[0]:
            each.destroy()
        gui_stopwatch_elements.pop(0)
        
    def ui_load_file(self):
        self.sroot.filename=tk.filedialog.askopenfilename(initialdir = os.getcwd(),title = "Select file",filetypes = (("txt files","*.txt"),("all files","*.*")))
        fn=self.sroot.filename
        if fn!='': load_file(fn)
        while gui_stopwatch_elements!=[]:
            self.destroy()
        for stopwatch in stopwatches:
            self.create_new_stopwatch()
            print("sw")
            gui_stopwatch_elements[-1][0].insert(0,stopwatch["name"])
        self.render_all()
        
    def start_stopwatch(self,i):
        was_active=self.active
        self.active=True
        print('start',i,end='')
#        self.debug()
        print(gui_stopwatch_elements[i][0].get())
        # if stopwatch is brand new with zero
        if stopwatches[i]['stamps']==[]:
            stopwatches[i]['stamps'].append([datetime.now(),None])
            if not was_active: self.tick()
        else:
            # if end stamp exists, ie if not already open
            if stopwatches[i]['stamps'][-1][1] is not None:
                stopwatches[i]['stamps'].append([datetime.now(),None])
                if not was_active: self.tick()
        #self.debug()

    def stop_stopwatch(self,i):
        #print('stop',i,end='')
        if stopwatches[i]['stamps']!=[] and stopwatches[i]['stamps'][-1][1] is None:
            stopwatches[i]['stamps'][-1][1]=datetime.now()
            stopwatches[i]['elapsed']+=stopwatches[i]['stamps'][-1][1]-stopwatches[i]['stamps'][-1][0]
        self.active=self.is_active()
        #self.debug()

    def debug(self):
        for i,gui_stopwatch in enumerate(gui_stopwatch_elements):
            stopwatches[i]['name']=gui_stopwatch[0].get()
        print(stopwatches,str_stopwatches(),sep='\n')
        print('len(gui_stopwatch_elements)=',len(gui_stopwatch_elements))
    def render(self,now):
        for i,stopwatch in enumerate(stopwatches):
            if stopwatch['stamps']==[]: continue
            if stopwatch['stamps'][-1][1] is None:
                q=stopwatch['elapsed']+now-stopwatch['stamps'][-1][0]
                #s=time_format(q.total_seconds())
                s=str(q)[0:-7]
                gui_stopwatch_elements[i][3].configure(text=s)
    def render_all(self):
        for i,stopwatch in enumerate(stopwatches):
            #s=str(stopwatch["elapsed"])
            #s=s[0:7]
            gui_stopwatch_elements[i][3].configure(text=str(stopwatch["elapsed"])[0:7])
    def is_active(self):
        for stopwatch in stopwatches:
            if stopwatch['stamps']==[]: continue
            if stopwatch['stamps'][-1][1] is None: return True
        return False

    def tick(self):
        print('.',end='')
        now=datetime.now()
        if self.active:
            self.render(now)
            self.sroot.after(tic_time, self.tick)


if 1:
    root = tk.Tk()
    root.geometry('600x400')
    timer = Timer(root)
    root.protocol("WM_DELETE_WINDOW", on_closing)
    root.mainloop()
    print(str_stopwatches())
    #save_timestamps()
else:
    buzz()