from graphics import *
from time import sleep


# Button Variables
EMPTY_AREA_SIZE = 10 # The empty area between buttons
buttonList = [] # Using for managing buttons
RBS = True # reverse button statue: false negative, true positive

# Frame Variables
WIDTH = 320 + EMPTY_AREA_SIZE
HEIGHT = 500 + EMPTY_AREA_SIZE

# Calculator Bar Variables
operation = ""
current_op = 0 # 0 = Nothing, 1 = Addition, 2 = Subtraction, 3 = Multiplication, 4 = Division
current_num = "0"
first_num = 0
second_num = 0
num_count = 0 # num count in current_num

# Text Variables
CHARACTER_PT = 20
FONT = "arial"
text_optimizer = 15 # Using for text lean right

# Creating Frame
win = GraphWin("Calculator", WIDTH, HEIGHT, autoflush=False) # App title, frame-width, frame-height

#############################
class Button():
    def __init__(self, text = "", p1 = Point(0, 0), p2 = Point(0, 0)):
        self.typing = False
        self.special = False
        self.text = str(text)
        self.p1 = Point(p1.getX() + EMPTY_AREA_SIZE, p1.getY() + EMPTY_AREA_SIZE)
        self.p2 = p2

        self.rect = Rectangle(Point(self.p1.getX(), self.p1.getY()), Point(self.p2.getX(), self.p2.getY()))
        self.label = Text(Point(self.p1.getX() + 40 - EMPTY_AREA_SIZE/2, self.p1.getY() + 40 - EMPTY_AREA_SIZE/2), "")

    def draw(self, color = 68):
        self.rect.undraw()
        self.rect.setFill(color_rgb(color, color, color))
        self.rect.draw(win)

        self.label.setText(self.text)
        self.label.undraw()
        self.label.setFace(FONT)
        self.label.setSize(CHARACTER_PT)
        self.label.draw(win)
    
    def undraw(self):
        self.rect.undraw()
        self.label.undraw()

    def setText(self, text):
        self.text = str(text)
        self.draw()
#############################

def inside(p, pMin, pMax):
    if (p.getX() < pMax.getX()) and (p.getX() > pMin.getX()):
        if (p.getY() < pMax.getY()) and (p.getY() > pMin.getY()):
            return True
    
    return False
 
# Setting Frame
win.setCoords(0, HEIGHT, WIDTH, 0) # lower left corner x, y, upper right corner x, y
win.setBackground(color_rgb(68, 68, 68)) # red, blue, green color codes
#################

# Creating Calculator Bar
bar = Rectangle(Point(0, 0), Point(WIDTH, 100))
bar.setFill(color_rgb(100, 100, 100))
bar.draw(win)

current_num_label = Text(Point(WIDTH - text_optimizer - len(current_num)/2 * text_optimizer, 70), current_num)
current_num_label.setFace(FONT)
current_num_label.setSize(CHARACTER_PT)
current_num_label.draw(win)

# Creating 1-9 num buttons
for i in range(3):
    for j in range(3):
        button = Button("", Point(0 + (j * 80), 340 - (i * 80)),  Point(80 + (j * 80), 420 - (i * 80)))
        button.draw()
        buttonList.append(button)

text = 1

for b in buttonList:
    b.setText(text)
    text += 1

    if text == 10:
        break

# Creating Operation Buttons
for i in range(4):
    button = Button("", Point(240, 100 + (i * 80)), Point(320, 180 + (i * 80)))
    button.draw()
    buttonList.append(button)

for i in range(4):
    if (i == 0):
        buttonList[i + 9].setText("/")
        buttonList[i + 9].special = True
    elif (i == 1):
        buttonList[i + 9].setText("x")
        buttonList[i + 9].special = True
    elif (i == 2):
        buttonList[i + 9].setText("+")
        buttonList[i + 9].special = True
    elif (i == 3):
        buttonList[i + 9].setText("-")
        buttonList[i + 9].special = True

# Creating +/-, 0, ., = Buttons
for i in range(4):
    button = Button("", Point(0 + (i * 80), 420), Point(80 + (i * 80), 500))
    button.draw()
    buttonList.append(button)

for i in range(4):
    if (i == 0):
        buttonList[i + 13].setText("+/-")
        buttonList[i + 13].special = True
    elif (i == 1):
        buttonList[i + 13].setText("0")
    elif (i == 2):
        buttonList[i + 13].setText(".")
        buttonList[i + 13].special = True
    elif (i == 3):
        buttonList[i + 13].setText("=")
        buttonList[i + 13].special = True

# Creating CE, C, ⌫ Buttons
for i in range(3):
    button = Button("", Point(0 + (i * 80), 100), Point(80 + (i * 80), 180))
    button.draw()
    buttonList.append(button)

for i in range(3):
    if (i == 0):
        buttonList[i + 17].setText("CE")
        buttonList[i + 17].special = True
    elif (i == 1):
        buttonList[i + 17].setText("C")
        buttonList[i + 17].special = True
    elif (i == 2):
        buttonList[i + 17].setText("⌫")
        buttonList[i + 17].special = True

# Mouse Listener
def click(event):
    for b in buttonList:
        if inside(Point(event.x, event.y), b.p1, b.p2):
            b.typing = True
            b.undraw()
            b.draw(100)

win.bind("<Button-1>", click)
# Mouse Listener

# Using for change current_num to int or float
def text_to_num(text):
    result = 0

    for i in range(len(text)):
        try:
            if text[i] == ",":
                text = text[:i] + text[i + 1:]
        except:
            if (text.find(".") != -1):
                result = float(text)
            else:
                result = int(text)

        if (text.find(",") == -1 and text.find(".") == -1):
            result = int(text)
        
    if (text.find(".") != -1):
        result = float(text)

    return result

# Main Loop
while True:
    update(60)

    for b in buttonList:
        if b.typing:
            bar = Rectangle(Point(0, 0), Point(WIDTH, 100))
            bar.setFill(color_rgb(100, 100, 100))
            bar.draw(win)

            # Addition Button
            if b.text == "+":
                if first_num == 0:
                    current_op = 1
                    b.editing_num = second_num

                    first_num = text_to_num(current_num)
                    current_num = "0"

                    operation = str(first_num) + " + "
                    num_count = 0

            # Subtraction Button
            if b.text == "-":
                if first_num == 0:
                    current_op = 2
                    b.editing_num = second_num

                    first_num = text_to_num(current_num)
                    current_num = "0"

                    operation = str(first_num) + " - "
                    num_count = 0

            # Multiplication Button
            if b.text == "x":
                if first_num == 0:
                    current_op = 3
                    b.editing_num = second_num

                    first_num = text_to_num(current_num)
                    current_num = "0"

                    operation = str(first_num) + " x "
                    num_count = 0

            # Division Button
            if b.text == "/":
                if first_num == 0:
                    current_op = 4
                    b.editing_num = second_num

                    first_num = text_to_num(current_num)
                    current_num = "0"

                    operation = str(first_num) + " / "
                    num_count = 0

            # Reverse Button
            if b.text == "+/-":
                if RBS:
                    RBS = False
                    current_num = "-" + current_num

                elif not(RBS):
                    RBS = True
                    current_num = current_num[1:]

            # Floater Button
            if b.text == ".":
                if (list(current_num).count(".") == 0 and len(current_num) < 19):
                    current_num += "."

            # CE Button
            if b.text == "CE":
                operation = ""
                current_num = "0"
                first_num = 0
                second_num = 0
                num_count = 0

            # C Button
            if b.text == "C":
                current_num = "0"
                num_count = 0

            # ⌫ Button
            if b.text == "⌫":
                if current_num != "0":
                    current_num = current_num[:-1]

                    if current_num.find(".") == -1:
                        num_count -= 1
                        
                    try:
                        if current_num[len(current_num) - 1] == ",":
                            current_num = current_num[:-1]
                        
                        if current_num[len(current_num) - 1] == ".":
                            current_num = current_num[:-1]
                    except:
                        current_num = "0"

            # = Button
            if b.text == "=":
                if current_op != 0:
                    second_num = text_to_num(current_num)
                    operation += str(second_num) + " = "

                if current_op == 1:
                    current_num = str(first_num + second_num)
                
                if current_op == 2:
                    current_num = str(first_num - second_num)

                if current_op == 3:
                    current_num = str(first_num * second_num)

                if current_op == 4:
                    try:
                        current_num = str(round((first_num / second_num), 4))
                    except:
                        current_num = "ERROR"

                if current_op != 0:
                    j = 0

                    if current_num.find(".") == -1:
                        
                        for i in range(len(current_num), 0, -1):
                            if j % 3 == 0:
                                current_num = current_num[:i] + "," + current_num[i:]

                            if (current_num.rfind(",") == len(current_num) - 1):
                                current_num = current_num[:len(current_num) - 1]
                            
                            j += 1

                    else:
                        temp_float = current_num[current_num.index("."):]
                        current_num = current_num[:current_num.index(".")]

                        for i in range(len(current_num), 0, -1):
                            if j % 3 == 0:
                                current_num = current_num[:i] + "," + current_num[i:]
                                    
                            if (current_num.rfind(",") == len(current_num) - 1):
                                current_num = current_num[:len(current_num) - 1]
                            
                            j += 1

                        current_num += temp_float

            # Num Buttons
            if len(current_num) < 19 and not(b.special):
                if (current_num == "0"):
                    current_num = ""

                current_num += str(b.text)

                if current_num.find(".") == -1:
                    num_count += 1

                if (current_num.find(".") == -1):
                    for i in range(len(current_num)):
                        try:
                            if current_num[i] == ",":
                                current_num = current_num[:i] + current_num[i + 1:]
                        except:
                            pass

                    j = 0

                    for i in range(num_count, 0, -1):
                        if j % 3 == 0:
                            current_num = current_num[:i] + "," + current_num[i:]

                            if (current_num.rfind(",") == len(current_num) - 1):
                                current_num = current_num[:len(current_num) - 1]
                            
                            if (current_num.rfind(",") == current_num.find(".") - 1):
                                current_num = current_num[:len(current_num) - 2]
                        
                        j += 1

            current_num_label = Text(Point(WIDTH - text_optimizer - len(current_num)/2 * text_optimizer, 70), current_num)
            current_num_label.setFace(FONT)
            current_num_label.setSize(CHARACTER_PT)
            current_num_label.draw(win)

            if (operation != ""):
                operation_label = Text(Point(WIDTH - text_optimizer - len(operation)/2 * text_optimizer/2, 30), operation)
                operation_label.setFace(FONT)
                operation_label.setSize(int(CHARACTER_PT/2))
                operation_label.setFill(color_rgb(30, 30, 30))
                operation_label.draw(win)

            b.typing = False
            sleep(0.1)
            b.draw()

from graphics import *
from time import sleep


# Button Variables
EMPTY_AREA_SIZE = 10 # The empty area between buttons
buttonList = [] # Using for managing buttons
RBS = True # reverse button statue: false negative, true positive

# Frame Variables
WIDTH = 320 + EMPTY_AREA_SIZE
HEIGHT = 500 + EMPTY_AREA_SIZE

# Calculator Bar Variables
operation = ""
current_op = 0 # 0 = Nothing, 1 = Addition, 2 = Subtraction, 3 = Multiplication, 4 = Division
current_num = "0"
first_num = 0
second_num = 0
num_count = 0 # num count in current_num

# Text Variables
CHARACTER_PT = 20
FONT = "arial"
text_optimizer = 15 # Using for text lean right

# Creating Frame
win = GraphWin("Calculator", WIDTH, HEIGHT, autoflush=False) # App title, frame-width, frame-height

#############################
class Button():
    def __init__(self, text = "", p1 = Point(0, 0), p2 = Point(0, 0)):
        self.typing = False
        self.special = False
        self.text = str(text)
        self.p1 = Point(p1.getX() + EMPTY_AREA_SIZE, p1.getY() + EMPTY_AREA_SIZE)
        self.p2 = p2

        self.rect = Rectangle(Point(self.p1.getX(), self.p1.getY()), Point(self.p2.getX(), self.p2.getY()))
        self.label = Text(Point(self.p1.getX() + 40 - EMPTY_AREA_SIZE/2, self.p1.getY() + 40 - EMPTY_AREA_SIZE/2), "")

    def draw(self, color = 68):
        self.rect.undraw()
        self.rect.setFill(color_rgb(color, color, color))
        self.rect.draw(win)

        self.label.setText(self.text)
        self.label.undraw()
        self.label.setFace(FONT)
        self.label.setSize(CHARACTER_PT)
        self.label.draw(win)
    
    def undraw(self):
        self.rect.undraw()
        self.label.undraw()

    def setText(self, text):
        self.text = str(text)
        self.draw()
#############################

def inside(p, pMin, pMax):
    if (p.getX() < pMax.getX()) and (p.getX() > pMin.getX()):
        if (p.getY() < pMax.getY()) and (p.getY() > pMin.getY()):
            return True
    
    return False
 
# Setting Frame
win.setCoords(0, HEIGHT, WIDTH, 0) # lower left corner x, y, upper right corner x, y
win.setBackground(color_rgb(68, 68, 68)) # red, blue, green color codes
#################

# Creating Calculator Bar
bar = Rectangle(Point(0, 0), Point(WIDTH, 100))
bar.setFill(color_rgb(100, 100, 100))
bar.draw(win)

current_num_label = Text(Point(WIDTH - text_optimizer - len(current_num)/2 * text_optimizer, 70), current_num)
current_num_label.setFace(FONT)
current_num_label.setSize(CHARACTER_PT)
current_num_label.draw(win)

# Creating 1-9 num buttons
for i in range(3):
    for j in range(3):
        button = Button("", Point(0 + (j * 80), 340 - (i * 80)),  Point(80 + (j * 80), 420 - (i * 80)))
        button.draw()
        buttonList.append(button)

text = 1

for b in buttonList:
    b.setText(text)
    text += 1

    if text == 10:
        break

# Creating Operation Buttons
for i in range(4):
    button = Button("", Point(240, 100 + (i * 80)), Point(320, 180 + (i * 80)))
    button.draw()
    buttonList.append(button)

for i in range(4):
    if (i == 0):
        buttonList[i + 9].setText("/")
        buttonList[i + 9].special = True
    elif (i == 1):
        buttonList[i + 9].setText("x")
        buttonList[i + 9].special = True
    elif (i == 2):
        buttonList[i + 9].setText("+")
        buttonList[i + 9].special = True
    elif (i == 3):
        buttonList[i + 9].setText("-")
        buttonList[i + 9].special = True

# Creating +/-, 0, ., = Buttons
for i in range(4):
    button = Button("", Point(0 + (i * 80), 420), Point(80 + (i * 80), 500))
    button.draw()
    buttonList.append(button)

for i in range(4):
    if (i == 0):
        buttonList[i + 13].setText("+/-")
        buttonList[i + 13].special = True
    elif (i == 1):
        buttonList[i + 13].setText("0")
    elif (i == 2):
        buttonList[i + 13].setText(".")
        buttonList[i + 13].special = True
    elif (i == 3):
        buttonList[i + 13].setText("=")
        buttonList[i + 13].special = True

# Creating CE, C, ⌫ Buttons
for i in range(3):
    button = Button("", Point(0 + (i * 80), 100), Point(80 + (i * 80), 180))
    button.draw()
    buttonList.append(button)

for i in range(3):
    if (i == 0):
        buttonList[i + 17].setText("CE")
        buttonList[i + 17].special = True
    elif (i == 1):
        buttonList[i + 17].setText("C")
        buttonList[i + 17].special = True
    elif (i == 2):
        buttonList[i + 17].setText("⌫")
        buttonList[i + 17].special = True

# Mouse Listener
def click(event):
    for b in buttonList:
        if inside(Point(event.x, event.y), b.p1, b.p2):
            b.typing = True
            b.undraw()
            b.draw(100)

win.bind("<Button-1>", click)
# Mouse Listener

# Using for change current_num to int or float
def text_to_num(text):
    result = 0

    for i in range(len(text)):
        try:
            if text[i] == ",":
                text = text[:i] + text[i + 1:]
        except:
            if (text.find(".") != -1):
                result = float(text)
            else:
                result = int(text)

        if (text.find(",") == -1 and text.find(".") == -1):
            result = int(text)
        
    if (text.find(".") != -1):
        result = float(text)

    return result

# Main Loop
while True:
    update(60)

    for b in buttonList:
        if b.typing:
            bar = Rectangle(Point(0, 0), Point(WIDTH, 100))
            bar.setFill(color_rgb(100, 100, 100))
            bar.draw(win)

            # Addition Button
            if b.text == "+":
                if first_num == 0:
                    current_op = 1
                    b.editing_num = second_num

                    first_num = text_to_num(current_num)
                    current_num = "0"

                    operation = str(first_num) + " + "
                    num_count = 0

            # Subtraction Button
            if b.text == "-":
                if first_num == 0:
                    current_op = 2
                    b.editing_num = second_num

                    first_num = text_to_num(current_num)
                    current_num = "0"

                    operation = str(first_num) + " - "
                    num_count = 0

            # Multiplication Button
            if b.text == "x":
                if first_num == 0:
                    current_op = 3
                    b.editing_num = second_num

                    first_num = text_to_num(current_num)
                    current_num = "0"

                    operation = str(first_num) + " x "
                    num_count = 0

            # Division Button
            if b.text == "/":
                if first_num == 0:
                    current_op = 4
                    b.editing_num = second_num

                    first_num = text_to_num(current_num)
                    current_num = "0"

                    operation = str(first_num) + " / "
                    num_count = 0

            # Reverse Button
            if b.text == "+/-":
                if RBS:
                    RBS = False
                    current_num = "-" + current_num

                elif not(RBS):
                    RBS = True
                    current_num = current_num[1:]

            # Floater Button
            if b.text == ".":
                if (list(current_num).count(".") == 0 and len(current_num) < 19):
                    current_num += "."

            # CE Button
            if b.text == "CE":
                operation = ""
                current_num = "0"
                first_num = 0
                second_num = 0
                num_count = 0

            # C Button
            if b.text == "C":
                current_num = "0"
                num_count = 0

            # ⌫ Button
            if b.text == "⌫":
                if current_num != "0":
                    current_num = current_num[:-1]

                    if current_num.find(".") == -1:
                        num_count -= 1
                        
                    try:
                        if current_num[len(current_num) - 1] == ",":
                            current_num = current_num[:-1]
                        
                        if current_num[len(current_num) - 1] == ".":
                            current_num = current_num[:-1]
                    except:
                        current_num = "0"

            # = Button
            if b.text == "=":
                if current_op != 0:
                    second_num = text_to_num(current_num)
                    operation += str(second_num) + " = "

                if current_op == 1:
                    current_num = str(first_num + second_num)
                
                if current_op == 2:
                    current_num = str(first_num - second_num)

                if current_op == 3:
                    current_num = str(first_num * second_num)

                if current_op == 4:
                    try:
                        current_num = str(round((first_num / second_num), 4))
                    except:
                        current_num = "ERROR"

                if current_op != 0:
                    j = 0

                    if current_num.find(".") == -1:
                        
                        for i in range(len(current_num), 0, -1):
                            if j % 3 == 0:
                                current_num = current_num[:i] + "," + current_num[i:]

                            if (current_num.rfind(",") == len(current_num) - 1):
                                current_num = current_num[:len(current_num) - 1]
                            
                            j += 1

                    else:
                        temp_float = current_num[current_num.index("."):]
                        current_num = current_num[:current_num.index(".")]

                        for i in range(len(current_num), 0, -1):
                            if j % 3 == 0:
                                current_num = current_num[:i] + "," + current_num[i:]
                                    
                            if (current_num.rfind(",") == len(current_num) - 1):
                                current_num = current_num[:len(current_num) - 1]
                            
                            j += 1

                        current_num += temp_float

            # Num Buttons
            if len(current_num) < 19 and not(b.special):
                if (current_num == "0"):
                    current_num = ""

                current_num += str(b.text)

                if current_num.find(".") == -1:
                    num_count += 1

                if (current_num.find(".") == -1):
                    for i in range(len(current_num)):
                        try:
                            if current_num[i] == ",":
                                current_num = current_num[:i] + current_num[i + 1:]
                        except:
                            pass

                    j = 0

                    for i in range(num_count, 0, -1):
                        if j % 3 == 0:
                            current_num = current_num[:i] + "," + current_num[i:]

                            if (current_num.rfind(",") == len(current_num) - 1):
                                current_num = current_num[:len(current_num) - 1]
                            
                            if (current_num.rfind(",") == current_num.find(".") - 1):
                                current_num = current_num[:len(current_num) - 2]
                        
                        j += 1

            current_num_label = Text(Point(WIDTH - text_optimizer - len(current_num)/2 * text_optimizer, 70), current_num)
            current_num_label.setFace(FONT)
            current_num_label.setSize(CHARACTER_PT)
            current_num_label.draw(win)

            if (operation != ""):
                operation_label = Text(Point(WIDTH - text_optimizer - len(operation)/2 * text_optimizer/2, 30), operation)
                operation_label.setFace(FONT)
                operation_label.setSize(int(CHARACTER_PT/2))
                operation_label.setFill(color_rgb(30, 30, 30))
                operation_label.draw(win)

            b.typing = False
            sleep(0.1)
            b.draw()

# Button Variables # The empty area between buttons # Using for managing buttons # reverse button statue: false negative, true positive # Frame Variables # Calculator Bar Variables # 0 = Nothing, 1 = Addition, 2 = Subtraction, 3 = Multiplication, 4 = Division # num count in current_num # Text Variables # Using for text lean right # Creating Frame # App title, frame-width, frame-height ############################# ############################# # Setting Frame # lower left corner x, y, upper right corner x, y # red, blue, green color codes ################# # Creating Calculator Bar # Creating 1-9 num buttons # Creating Operation Buttons # Creating +/-, 0, ., = Buttons # Creating CE, C, ⌫ Buttons # Mouse Listener # Mouse Listener # Using for change current_num to int or float # Main Loop # Addition Button # Subtraction Button # Multiplication Button # Division Button # Reverse Button # Floater Button # CE Button # C Button # ⌫ Button # = Button # Num Buttons