"""DuckieDai Quadratic Solver for TI-84 Plus CE Python."""

from math import sqrt


def duckiedai_intro(program_name, wait=True):
    title = program_name[:16]
    empty = 16 - len(title)
    left = empty // 2
    right = empty - left

    print("+----------------------+")
    print("|   " + " " * left + title + " " * right + "   |")
    print("|                      |")
    print("|       __             |")
    print("|   ___(o )>  quack!   |")
    print("|   \\ <_. )           |")
    print("|    `---'             |")
    print("|     by DuckieDai     |")
    print("+----------------------+")
    print("Loading...")

    if wait:
        input("Press enter to start ")
        print("\n" * 8)


def clear_screen():
    print("\n" * 8)


def clean_num(n):
    if abs(n - round(n)) < 0.0000001:
        return int(round(n))
    return round(n, 6)


def number(prompt):
    while True:
        try:
            text = input(prompt)

            if "/" in text:
                parts = text.split("/")

                if len(parts) != 2:
                    raise ValueError

                top = float(parts[0])
                bottom = float(parts[1])

                if bottom == 0:
                    print("Cannot divide by 0")
                    continue

                return top / bottom

            return float(text)

        except ValueError:
            print("Enter a number")
            print("or fraction")


def run_solver():
    clear_screen()

    print("ENTER QUADRATIC")
    print("ax^2+bx+c=0")
    print("")

    a = number("a: ")
    b = number("b: ")
    c = number("c: ")

    if a == 0:
        clear_screen()
        print("NOT QUADRATIC")
        print("a cannot be 0")
        return

    disc = b * b - 4 * a * c

    # SCREEN 1
    clear_screen()

    print("DISCRIMINANT")
    print("------------")
    print(clean_num(disc))

    if disc > 0:
        print("2 real roots")
    elif abs(disc) < 0.0000001:
        print("1 repeated root")
    else:
        print("2 complex roots")

    input("\nPress enter ")

    # SCREEN 2
    clear_screen()

    print("ROOTS")
    print("-----")

    if abs(disc) < 0.0000001:
        x = -b / (2 * a)

        print("x =", clean_num(x))

    elif disc > 0:
        x1 = (-b + sqrt(disc)) / (2 * a)
        x2 = (-b - sqrt(disc)) / (2 * a)

        print("x1 =", clean_num(x1))
        print("x2 =", clean_num(x2))

        input("\nPress enter ")

        # SCREEN 3
        clear_screen()

        print("EXACT FORM")
        print("----------")
        print(clean_num(-b), "+/-")
        print("sqrt(", clean_num(disc), ")")
        print("over", clean_num(2 * a))

    else:
        real = -b / (2 * a)
        imag = sqrt(-disc) / abs(2 * a)

        print("x1 =")
        print(clean_num(real), "+")
        print(clean_num(imag), "i")

        print("")
        print("x2 =")
        print(clean_num(real), "-")
        print(clean_num(imag), "i")

        input("\nPress enter ")

        # SCREEN 3
        clear_screen()

        print("EXACT COMPLEX")
        print("-------------")

        imag_disc = int(round(-disc))

        outside = 1
        inside = imag_disc

        factor = 2

        while factor * factor <= inside:
            square = factor * factor

            while inside % square == 0:
                outside *= factor
                inside //= square

            factor += 1

        den = int(round(abs(2 * a)))

        # Reduce outside / denominator
        x = outside
        y = den

        while y != 0:
            x, y = y, x % y

        common = x

        outside //= common
        den //= common

        if abs(real) < 0.0000001:
            if outside == 1 and den == 1:
                print("x = +/- i")
                print("* sqrt(", inside, ")")

            elif den == 1:
                print("x = +/-", outside, "i")
                print("* sqrt(", inside, ")")

            else:
                print("x = +/-")
                print(outside, "i*sqrt(", inside, ")")
                print("over", den)

        else:
            print("Real part:")
            print(clean_num(real))

            print("")
            print("Imaginary part:")

            if outside == 1 and den == 1:
                print("+/- i")
                print("* sqrt(", inside, ")")

            elif den == 1:
                print("+/-", outside, "i")
                print("* sqrt(", inside, ")")

            else:
                print("+/-")
                print(outside, "i*sqrt(", inside, ")")
                print("over", den)


duckiedai_intro("Quadratic")

while True:
    run_solver()

    print("")
    again = input("Again? y/n: ")

    if again.lower() != "y":
        break


clear_screen()
print("DuckieDai says: done!")

