from tkinter import*
import math
import parser
import tkinter.messagebox

#create, sized, background color changed, change can't resizeble and add title name. If we want to change the name root we can change any name of it
root = Tk()
root.title("Scientific Calculator By KRP")
root.configure(background="powder blue")
root.resizable(width=False, height=False)
root.geometry("472x545+0+0")

calc = Frame(root)
calc.grid()

class Calc():
    def __init__(self):
        self.total =0
        self.current = ""
        self.input_value = True
        self.check_sum = False
        self.op =""
        self.result = False

    def numberEnter(self, num):
        self.result = False
        firstnum = txtDisplay.get()
        secondnum = str(num)
        if self.input_value:
            self.current = secondnum
            self.input_value =False
        else:
            if secondnum =='.':
                if secondnum in firstnum:
                    return
            self.current = firstnum + secondnum
        self.display(self.current)
    
    def sum_of_total(self):
        self.result = True
        self.current = float(self.current)
        if self.check_sum == True:
            self.valid_function()
        else:
            self.total = float(txtDisplay.get())

    def display(self, value):
        txtDisplay.delete(0, END)
        txtDisplay.insert(0, value)

    def valid_function(self):
        if self.op == "add":
            self.total +=self.current
        if self.op == "sub":
            self.total -=self.current
        if self.op == "multi":
            self.total *=self.current
        if self.op == "divide":
            self.total /=self.current
        if self.op == "mod":
            self.total %=self.current
        self.input_value = True
        self.check_sum = False
        self.display(self.total)

    def operation(self, op):
        self.current = float(self.current)
        if self.check_sum:
            self.valid_function()
        elif not self.result:
            self.total = self.current
            self.input_value = True
        self.check_sum = True
        self.op = op
        self.result = False

    def Clear_Entry(self):
        self.result = False
        self.current = "0"
        self.display(0)
        self.input_value = True

    def All_Clear_Entry(self):
        self.Clear_Entry()
        self.total = 0

    def Negative(self):
        self.result = False
        self.current = -(float(txtDisplay.get()))

    def squared(self):
        self.result = False
        self.current = math.sqrt (float(txtDisplay.get()))
        self.display(self.current)

    def pi(self):
        self.result = False
        self.current = math.pi
        self.display(self.current)

    def tau(self):
        self.result = False
        self.current = math.tau
        self.display(self.current)

    def e(self):
        self.result = False
        self.current = math.e
        self.display(self.current)

    def log(self):
        self.result = False
        self.current = math.log(float(txtDisplay.get()))
        self.display(self.current)

    def exp(self):
        self.result = False
        self.current = math.exp(float(txtDisplay.get()))
        self.display(self.current)

    def sin(self):
        self.result = False
        self.current = math.sin(float(txtDisplay.get()))
        self.display(self.current)

    def sinh(self):
        self.result = False
        self.current = math.sinh(float(txtDisplay.get()))
        self.display(self.current)

    def cos(self):
        self.result = False
        self.current = math.cos(float(txtDisplay.get()))
        self.display(self.current)

    def cosh(self):
        self.result = False
        self.current = math.cosh(float(txtDisplay.get()))
        self.display(self.current)

    def tan(self):
        self.result = False
        self.current = math.tan(float(txtDisplay.get()))
        self.display(self.current)

    def tanh(self):
        self.result = False
        self.current = math.tanh(float(txtDisplay.get()))
        self.display(self.current)

    def asinh(self):
        self.result = False
        self.current = math.asinh(float(txtDisplay.get()))
        self.display(self.current)

    def acosh(self):
        self.result = False
        self.current = math.acosh(float(txtDisplay.get()))
        self.display(self.current)

    def atanh(self):
        self.result = False
        self.current = math.atanh(float(txtDisplay.get()))
        self.display(self.current)

    def log2(self):
        self.result = False
        self.current = math.log2(float(txtDisplay.get()))
        self.display(self.current)

    def log1p(self):
        self.result = False
        self.current = math.log1p(float(txtDisplay.get()))
        self.display(self.current)

    def log10(self):
        self.result = False
        self.current = math.log10(float(txtDisplay.get()))
        self.display(self.current)

    def lgamma(self):
        self.result = False
        self.current = math.lgamma(float(txtDisplay.get()))
        self.display(self.current)

    def expm1(self):
        self.result = False
        self.current = math.expm1(float(txtDisplay.get()))
        self.display(self.current)

    def degrees(self):
        self.result = False
        self.current = math.degrees(float(txtDisplay.get()))
        self.display(self.current)

added_value = Calc()



menubar = Menu(calc)

added_value = Calc()
txtDisplay = Entry(calc, font=('arial', 20, 'bold'), bg="white", width=31, justify=RIGHT, bd=2)
txtDisplay.grid(row=0, column=0, columnspan=4 , padx=1)
txtDisplay.insert(0,"0")

#=========================Standerd calculaotr==============================================================
#Create buttons
numberpad = "789456123"
i=0
btn= []
for j in range(2,5):
    for k in range(3):
        btn.append(Button(calc, width=6, height=2, font=('arial', 20, 'bold'), bd=2, text=numberpad[i]))
        btn[i].grid(row=j, column=k, pady=1)
        btn[i]["command"] = lambda x = numberpad[i]: added_value.numberEnter(x)
        i +=1

btnClear =Button(calc, text=chr(67), width=6  , height=2, font=('arial', 20, 'bold'), bd=2, bg="powder blue", 
                        command=added_value.All_Clear_Entry).grid(row=1, column=0, pady=1)

btnAllClear =Button(calc, text=chr(67) +chr(69), width=6  , height=2, font=('arial', 20, 'bold'), bd=2, bg="powder blue", 
                        command=added_value.Clear_Entry).grid(row=1, column=1, pady=1)

btnSq =Button(calc, text="√", width=6  , height=2, font=('arial', 20, 'bold'), bd=2, bg="powder blue",
                        command=added_value.squared).grid(row=1, column=2, pady=1)

btnAdd =Button(calc, text="+", width=6  , height=2, font=('arial', 20, 'bold'), bd=2, 
                        bg="powder blue", command = lambda: added_value.operation("add")).grid(row=1, 
                        column=3, pady=1)

btnSub =Button(calc, text="-", width=6  , height=2, font=('arial', 20, 'bold'), bd=2, 
                        bg="powder blue", command = lambda: added_value.operation("sub")).grid(row=2, 
                        column=3, pady=1)

btnMult =Button(calc, text="x", width=6  , height=2, font=('arial', 20, 'bold'), bd=2, 
                        bg="powder blue", command = lambda: added_value.operation("multi")).grid(row=3, 
                        column=3, pady=1)

btnDiv =Button(calc, text="÷", width=6  , height=2, font=('arial', 20, 'bold'), bd=2, 
                        bg="powder blue", command = lambda: added_value.operation("devide")).grid(row=4, 
                        column=3, pady=1)

btnZero =Button(calc, text="0", width=6  , height=2, font=('arial', 20, 'bold'), bd=2, 
                        bg="powder blue", command = lambda: added_value.numberEnter(0)).grid(row=5, 
                        column=0, pady=1)

btnDot =Button(calc, text=".", width=6  , height=2, font=('arial', 20, 'bold'), bd=2, 
                        bg="powder blue", command = lambda: added_value.numberEnter(".")).grid(row=5, 
                        column=1, pady=1)

btnNegative =Button(calc, text=chr(177), width=6  , height=2, font=('arial', 20, 'bold'), bd=2, 
                        bg="powder blue").grid(row=5, column=2, pady=1)

btnEqual =Button(calc, text="=", width=6  , height=2, font=('arial', 20, 'bold'), bd=2, 
                        bg="powder blue", command=added_value.sum_of_total).grid(row=5, column=3, pady=1)

#==================================Scientific calculator===================================================

btnPi= Button(calc, text="π", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command= added_value.pi).grid(row=1, column=4, pady=1)

btnCos= Button(calc, text="Cos", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                       command=added_value.cos ).grid(row=1, column=5, pady=1)

btnTan= Button(calc, text="Tan", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command=added_value.tan).grid(row=1, column=6, pady=1)

btnSin= Button(calc, text="Sin", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command=added_value.sin).grid(row=1, column=7, pady=1)

#===========================================================================================================

btn2Pi= Button(calc, text="2π", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command= added_value.tau).grid(row=2, column=4, pady=1)

btnCosh= Button(calc, text="Cosh", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command= added_value.cosh).grid(row=2, column=5, pady=1)

btnTanh= Button(calc, text="Tanh", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command= added_value.tanh).grid(row=2, column=6, pady=1)

btnSinh= Button(calc, text="Sinh", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command= added_value.sinh).grid(row=2, column=7, pady=1)

#===========================================================================================================

btnlog= Button(calc, text="Log", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command= added_value.log).grid(row=3, column=4, pady=1)

btnExp= Button(calc, text="Exp", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command= added_value.exp).grid(row=3, column=5, pady=1)

btnMod= Button(calc, text="Mod", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command= lambda: added_value.operation("mod")).grid(row=3, column=6, pady=1)

btnE= Button(calc, text="e", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command=added_value.e).grid(row=3, column=7, pady=1)

#===========================================================================================================

btnlog2= Button(calc, text="Log2", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command=added_value.log2).grid(row=4, column=4, pady=1)

btnDeg= Button(calc, text="Deg", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command=added_value.degrees).grid(row=4, column=5, pady=1)

btnacosh= Button(calc, text="acosh", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command=added_value.acosh).grid(row=4, column=6, pady=1)

btnasinh= Button(calc, text="asinh", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command=added_value.asinh).grid(row=4, column=7, pady=1)

#===========================================================================================================

btnlog10= Button(calc, text="Log10", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command=added_value.log10).grid(row=5, column=4, pady=1)

btnlog1p= Button(calc, text="Log1p", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command=added_value.log1p).grid(row=5, column=5, pady=1)

btnExpm1= Button(calc, text="Exmp1", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                        command=added_value.expm1).grid(row=5, column=6, pady=1)

btnlgamma= Button(calc, text="lgamma", width=6, height=2, font=('arial', 20, 'bold'), bd=4, bg="powder blue",
                         command=added_value.lgamma).grid(row=5, column=7, pady=1)

lblDisplay = Label(calc, text="Scientific Calculator", font=('arial', 30, 'bold'), justify= CENTER)
lblDisplay.grid(row=0, column=4, columnspan=4)

lblDisplay = Label(calc, text="Created by Kavinda Rashmika Peiris", font=('arial', 10,'bold'), justify=CENTER)
lblDisplay.grid(row=6, column=0, columnspan=4 )

lblDisplay = Label(calc, text="Created by Kavinda Rashmika Peiris", font=('arial', 10,'bold'), justify=CENTER)
lblDisplay.grid(row=6, column=4, columnspan=4 )

#================================Menu and function=========================================================

def iExit():
    iExit = tkinter.messagebox.askyesno("Scientific Calculator By KRP", "Confirm if you want to exit")
    if iExit > 0:
        root.destroy()
        return

def Scientific():
    root.resizable(width=False, height=False)
    root.geometry("944x545+0+0")

def Standerd():
    root.resizable(width=False, height=False)
    root.geometry("472x545+0+0")

#create file menubar option
filemenu = Menu(menubar, tearoff= 0)
menubar.add_cascade(label= "File", menu=filemenu)
filemenu.add_cascade(label= "Standerd", command= Standerd)
filemenu.add_cascade(label= "Scientific", command= Scientific)
filemenu.add_separator()
filemenu.add_cascade(label= "Exit", command= iExit)

#create edit menubar option
editmenu = Menu(menubar, tearoff=0)
menubar.add_cascade(label= "Edit", menu=editmenu)
editmenu.add_cascade(label= "Cut")
editmenu.add_cascade(label= "Copy")
editmenu.add_separator()
editmenu.add_cascade(label= "Paste")

#create help menubar option
helpmenu = Menu(menubar, tearoff=0)
menubar.add_cascade(label= "Help", menu=helpmenu)
helpmenu.add_cascade(label= "View Help")

#call the window
root.config(menu=menubar)
root.mainloop()