from tkinter import *
import random # for simulating random decay of atoms.


def main():

    window = Tk()
    initialNumberOfAtoms = IntVar()
    chanceOfDecay = IntVar()
    count = IntVar()
    count.set(0)
    
    window.title("Radioactive Decay")
    window.geometry("400x600") 
    window.resizable(0, 0)
    titleLabel = Label(window, text = "Welcome to the Half-Life Simulator!", fg = "black", bg = "white")
    titleLabel.pack()
    Inputs(window, initialNumberOfAtoms, chanceOfDecay,count)

    
def Simulation(initialNumberOfAtoms, window, chanceOfDecay):

    currentNumberOfAtoms = IntVar()
    currentNumberOfAtoms.set(initialNumberOfAtoms.get())
    time = IntVar()
    time.set(0)
    halfLifeFound = BooleanVar()
    halfLifeFound.set(False)
    
    #Label to display the number of atoms which haven't decayed.
    chanceOfDecayLabel = Label(window, text = "Chance of Decay = 1/%d" %chanceOfDecay.get())
    chanceOfDecayLabel.pack()
    labelUndecayedAtoms = Label(window, text = "Number of undecayed atoms: %d" %initialNumberOfAtoms.get(), bg = "white", fg = "black")
    labelUndecayedAtoms.pack()
    

    
    # A canvas frame
    frame1 = Frame(window)
    frame1.pack()
    canvas = Canvas(frame1, width = 200, height = 200, bg = "white")
    canvas.pack()

    timeLabel = Label(frame1, text = "Time = 0 seconds", fg = "black", bg = "white")
    timeLabel.pack()
    halfLifeLabel = Label(frame1, text = "", fg = "black", bg = "white")
    halfLifeLabel.pack()
    
    #Generate the atoms
    for i in range(0, currentNumberOfAtoms.get()):
        x1 = random.randrange(10, 380)
        y1 = random.randrange(10, 460)
        x2 = x1 + 20
        y2 = y1 + 20
        coords = x1, y1, x2, y2
        canvas.create_oval(coords, fill = "yellow", tags = "atom")

        
    # A button frame
    frame2 = Frame(window)
    frame2.pack()
    timeStepBtn = Button(frame2, text = "Seconds + 1", command = lambda: TimeStep(canvas, currentNumberOfAtoms, initialNumberOfAtoms, labelUndecayedAtoms, alertLabel, timeLabel, halfLifeLabel, time, halfLifeFound, chanceOfDecay))
    timeStepBtn.pack()

    #A label to alert the user that all atoms have already decayed
    alertLabel = Label(frame2, text = "", fg = "black", bg = "white")
    alertLabel.pack()

    window.mainloop()

def TimeStep(canvas, currentNumberOfAtoms, initialNumberOfAtoms, labelUndecayedAtoms, alertLabel, timeLabel, halfLifeLabel, time, halfLifeFound, chanceOfDecay):

    if currentNumberOfAtoms.get() == 0:
        alertLabel.configure(text = "All Atoms have decayed!")
    else:
        atomsDecayed = 0
        
        for i in range(0, currentNumberOfAtoms.get()):      
            chance = random.randint(0, chanceOfDecay.get() -1)
            if chance == 0:
                atomsDecayed += 1
                
        currentNumberOfAtoms.set(currentNumberOfAtoms.get() - atomsDecayed)
        time.set(time.get() + 1)
        if halfLifeFound.get() == False:
            if currentNumberOfAtoms.get() <= initialNumberOfAtoms.get()/2:
                halfLifeLabel.configure(text = "The half life for this sample is between %d and %d seconds" %(time.get() - 1, time.get()))
                halfLifeFound.set(True)
        timeLabel.configure(text = "Time = %d seconds" %time.get())

        labelUndecayedAtoms.configure(text = "Number of undecayed atoms: %d" %currentNumberOfAtoms.get()) #Change the number in the label
        canvas.delete("atom") #Clear the Canvas of all atoms
        
        for i in range(0, currentNumberOfAtoms.get()): #Randomly generate the undecayed yellow atoms
            x1 = random.randrange(10, 380)
            y1 = random.randrange(10, 460)
            x2 = x1 + 20
            y2 = y1 + 20
            coords = x1, y1, x2, y2
            canvas.create_oval(coords, fill = "yellow", tags = "atom")


        for i in range(0, initialNumberOfAtoms.get() - currentNumberOfAtoms.get()): #Randomly generate the decayed red atoms
            x1 = random.randrange(10, 380)
            y1 = random.randrange(10, 460)
            x2 = x1 + 20
            y2 = y1 + 20
            coords = x1, y1, x2, y2
            canvas.create_oval(coords, fill = "red", tags = "atom")
        
        canvas.update()        


#Allows user Input for number of Atoms and chance of each atom decaying
def Inputs(window, initialNumberOfAtoms, chanceOfDecay, count):
    numberOfAtomsLabel = Label(window, text = "Please enter an initial number of radioactive atoms:", fg = "black", bg = "white")
    numberOfAtomsLabel.pack()
    numberOfAtomsEntry = Entry(window, text = "Number of Atoms", fg = "black", bg = "white")
    numberOfAtomsEntry.pack()
    chanceOfDecayLabel = Label(window, text = "Enter the chances of an atom decaying i.e. 1/x :", fg = "black", bg = "white")
    chanceOfDecayLabel.pack()
    chanceOfDecayEntry = Entry(window, text = "Chance Of Decay", fg = "black", bg = "white")
    chanceOfDecayEntry.pack()
    storeInputsButton = Button(window, text = "Enter", fg = "black", bg = "white", command = lambda: storeInputs(numberOfAtomsEntry, chanceOfDecayEntry, initialNumberOfAtoms, chanceOfDecay, window, count))
    storeInputsButton.pack()
    resetButton = Button(window, text = "Reset", fg = "black", bg = "white", command = lambda: Reset(window))
    resetButton.pack()

#Store inputs for the number of atoms and the chance of decay
def storeInputs(numberOfAtomsEntry, chanceOfDecayEntry, initialNumberOfAtoms, chanceOfDecay, window, count):
    try:
        initialNumberOfAtoms.set(numberOfAtomsEntry.get())
        chanceOfDecay.set(chanceOfDecayEntry.get())
        Simulation(initialNumberOfAtoms, window, chanceOfDecay)
    except:
        print("You need to enter an input!")
#Reset the program.
def Reset(window):
    window.destroy()
    main()

main()
