"""DuckieDai Smart Kinematics for TI-84 Plus CE Python."""

from math import sqrt


def duckiedai_intro(program_name, wait=True):
    """Show the reusable DuckieDai program opening."""
    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" * 6)


def optional_number(prompt):
    """Return a number or None if left blank."""
    while True:
        raw = input(prompt)

        if raw == "":
            return None

        try:
            value = float(raw)

            if value > -1e100 and value < 1e100:
                return value

        except ValueError:
            pass

        print("Number or blank only.")


def show_answer(name, value, unit):
    input("Press enter for answer ")
    print("\n" * 6)
    print("ANSWER")
    print(name + " = " + str(value))
    print(unit)


def main():
    duckiedai_intro("KINEMATIC SOLVER")

    print("SMART KINEMATICS")
    print()
    print("What do you need?")
    print()
    print("1. Final velocity")
    print("2. Initial velocity")
    print("3. Acceleration")
    print("4. Time")
    print("5. Displacement")
    print()

    target = input("Choose 1-5: ")

    print()
    print("Enter known values.")
    print("Leave unknowns blank.")
    print()

    # -------------------------
    # GET KNOWN VALUES
    # -------------------------

    if target != "2":
        v0 = optional_number(
            "v0 (m/s): "
        )
    else:
        v0 = None

    if target != "1":
        v = optional_number(
            "v (m/s): "
        )
    else:
        v = None

    if target != "3":
        a = optional_number(
            "a (m/s^2): "
        )
    else:
        a = None

    if target != "4":
        t = optional_number(
            "t (s): "
        )
    else:
        t = None

    if target != "5":
        dx = optional_number(
            "dx (m): "
        )
    else:
        dx = None

    solved = False

    # ==================================================
    # 1. SOLVE FINAL VELOCITY
    # ==================================================

    if target == "1":

        # v = v0 + a*t

        if (v0 is not None and
                a is not None and
                t is not None):

            print()
            print("Using:")
            print("v = v0 + a*t")

            v = v0 + a * t

            print()
            print("v = " + str(v0) +
                  " + (" + str(a) +
                  " x " + str(t) + ")")

            show_answer(
                "v",
                v,
                "m/s"
            )

            solved = True

        # v^2 = v0^2 + 2*a*dx

        elif (v0 is not None and
              a is not None and
              dx is not None):

            inside = (
                v0 ** 2 +
                2 * a * dx
            )

            if inside >= 0:

                v = sqrt(inside)

                print()
                print("Using:")
                print("v^2=v0^2+2*a*dx")
                print()
                print("Rearranged:")
                print("v=+/-sqrt(")
                print("v0^2+2*a*dx)")

                print()
                print("ANSWER")
                print("v = +/- " + str(v))
                print("m/s")
                print()
                print("Direction decides")
                print("the correct sign.")

                solved = True


    # ==================================================
    # 2. SOLVE INITIAL VELOCITY
    # ==================================================

    elif target == "2":

        # v = v0 + a*t

        if (v is not None and
                a is not None and
                t is not None):

            print()
            print("Using:")
            print("v = v0 + a*t")
            print()
            print("Rearranged:")
            print("v0 = v - a*t")

            v0 = v - a * t

            show_answer(
                "v0",
                v0,
                "m/s"
            )

            solved = True

        # dx = v0*t + 0.5*a*t^2

        elif (dx is not None and
              a is not None and
              t is not None and
              t != 0):

            print()
            print("Using:")
            print("dx=v0*t+.5*a*t^2")
            print()
            print("Rearranged:")
            print("v0=(dx-.5*a*t^2)/t")

            v0 = (
                dx -
                0.5 * a * t ** 2
            ) / t

            show_answer(
                "v0",
                v0,
                "m/s"
            )

            solved = True

        # v^2 = v0^2 + 2*a*dx

        elif (v is not None and
              a is not None and
              dx is not None):

            inside = (
                v ** 2 -
                2 * a * dx
            )

            if inside >= 0:

                v0 = sqrt(inside)

                print()
                print("Using:")
                print("v^2=v0^2+2*a*dx")
                print()
                print("Rearranged:")
                print("v0=+/-sqrt(")
                print("v^2-2*a*dx)")

                print()
                print("ANSWER")
                print("v0 = +/- " + str(v0))
                print("m/s")
                print()
                print("Direction decides")
                print("the correct sign.")

                solved = True


    # ==================================================
    # 3. SOLVE ACCELERATION
    # ==================================================

    elif target == "3":

        # v = v0 + a*t

        if (v is not None and
                v0 is not None and
                t is not None and
                t != 0):

            print()
            print("Using:")
            print("v = v0 + a*t")
            print()
            print("Rearranged:")
            print("a = (v-v0)/t")

            a = (v - v0) / t

            show_answer(
                "a",
                a,
                "m/s^2"
            )

            solved = True

        # dx = v0*t + 0.5*a*t^2

        elif (dx is not None and
              v0 is not None and
              t is not None and
              t != 0):

            print()
            print("Using:")
            print("dx=v0*t+.5*a*t^2")
            print()
            print("Rearranged:")
            print("a=2(dx-v0*t)/t^2")

            a = (
                2 *
                (dx - v0 * t)
                / (t ** 2)
            )

            show_answer(
                "a",
                a,
                "m/s^2"
            )

            solved = True

        # v^2 = v0^2 + 2*a*dx

        elif (v is not None and
              v0 is not None and
              dx is not None and
              dx != 0):

            print()
            print("Using:")
            print("v^2=v0^2+2*a*dx")
            print()
            print("Rearranged:")
            print("a=(v^2-v0^2)/(2*dx)")

            a = (
                v ** 2 -
                v0 ** 2
            ) / (2 * dx)

            show_answer(
                "a",
                a,
                "m/s^2"
            )

            solved = True


    # ==================================================
    # 4. SOLVE TIME
    # ==================================================

    elif target == "4":

        # v = v0 + a*t

        if (v is not None and
                v0 is not None and
                a is not None and
                a != 0):

            print()
            print("Using:")
            print("v = v0 + a*t")
            print()
            print("Rearranged:")
            print("t = (v-v0)/a")

            t = (v - v0) / a

            show_answer(
                "t",
                t,
                "seconds"
            )

            solved = True

        # dx = v0*t + 0.5*a*t^2

        elif (dx is not None and
              v0 is not None and
              a is not None):

            print()
            print("Using:")
            print("dx=v0*t+.5*a*t^2")

            if a == 0:

                if v0 != 0:

                    t = dx / v0

                    print()
                    print("Since a = 0:")
                    print("t = dx/v0")

                    show_answer(
                        "t",
                        t,
                        "seconds"
                    )

                    solved = True

            else:

                inside = (
                    v0 ** 2 +
                    2 * a * dx
                )

                if inside >= 0:

                    root = sqrt(inside)

                    t1 = (
                        -v0 + root
                    ) / a

                    t2 = (
                        -v0 - root
                    ) / a

                    print()
                    print("Solving quadratic:")
                    print()

                    if t1 >= 0:
                        print("t = " + str(t1) +
                              " s")

                    if t2 >= 0:
                        print("t = " + str(t2) +
                              " s")

                    print()
                    print("Use physical")
                    print("positive time.")

                    solved = True


    # ==================================================
    # 5. SOLVE DISPLACEMENT
    # ==================================================

    elif target == "5":

        # dx = v0*t + 0.5*a*t^2

        if (v0 is not None and
                a is not None and
                t is not None):

            print()
            print("Using:")
            print("dx=v0*t+.5*a*t^2")

            dx = (
                v0 * t +
                0.5 * a * t ** 2
            )

            show_answer(
                "dx",
                dx,
                "meters"
            )

            solved = True

        # v^2 = v0^2 + 2*a*dx

        elif (v is not None and
              v0 is not None and
              a is not None and
              a != 0):

            print()
            print("Using:")
            print("v^2=v0^2+2*a*dx")
            print()
            print("Rearranged:")
            print("dx=(v^2-v0^2)/(2*a)")

            dx = (
                v ** 2 -
                v0 ** 2
            ) / (2 * a)

            show_answer(
                "dx",
                dx,
                "meters"
            )

            solved = True


    # ==================================================
    # COULD NOT SOLVE
    # ==================================================

    if not solved:
        print()
        print("Not enough usable")
        print("information.")
        print()
        print("Check the values")
        print("given in the problem.")

    print()
    print("DuckieDai says: done!")


# TI-Python imports the selected AppVar rather than
# setting __name__ to main.
main()
