# Text To Gcode
# Copyright (C) 2021  Ryan Zmuda
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


import time
from os import remove, rename
from math import cos, sin, radians


class ttg:
    def __init__(self, text, size, rotation, method, feedRate):
        # set basic passed args
        self.text = text
        self.size = size
        self.rotation = radians(rotation)
        self.method = method
        self.feedRate = str(feedRate)

        # set global class vars
        self.rotationNeeded = False
        self.readyForReturn = False
        self.operations = []
        self.currentXOffset = 0
        self.parsed = False
        self.verts = []

        # set defualts commands
        self.offCmd = "M5"
        self.onCmd = "M3"
        self.fastCmd = "G0"
        self.slowCmd = "G1"

        # check if the user has specified a positive or negative rotation
        if self.rotation != 0:
            self.rotationNeeded = True

    def finalize(self):
        finalOperations = []

        for point in self.operations:
            if type(point) is tuple:
                # if size is not 1mm scale the points, if it is do nothing
                if self.size != 1:
                    scaledPoint = (point[0] * self.size, point[1] * self.size)
                else:
                    scaledPoint = (point[0], point[1])

                # if we need to rotate the text verticies, rotate them by the specified radians
                # if we dont send the point to final operations without rotating
                if self.rotationNeeded:
                    originX = 0
                    originY = 0
                    newpointX = (
                        originX
                        + cos(self.rotation) * (scaledPoint[0] - originX)
                        - sin(self.rotation) * (scaledPoint[1] - originY)
                    )
                    newpointY = (
                        originY
                        + sin(self.rotation) * (scaledPoint[0] - originX)
                        + cos(self.rotation) * (scaledPoint[1] - originY)
                    )
                    newpoint = (newpointX, newpointY)
                else:
                    newpoint = (scaledPoint[0], scaledPoint[1])

                finalOperations.append(newpoint)

            elif isinstance(point, str):
                finalOperations.append(point)

        # replace placeholder string commands with GCODE commands
        for count, command in enumerate(finalOperations):
            if command == "off":
                finalOperations[count] = self.offPowerCmd
            elif command == "on":
                finalOperations[count] = self.onPowerCmd
            elif command == "fast":
                finalOperations[count] = self.fastCmd
            elif command == "slow":
                finalOperations[count] = self.slowCmd

        if self.method == "visualize":
            return finalOperations

        elif self.method == "return" or self.method == "file":

            # initial preperation for file if user wants to output to gcode file
            if self.method == "file":
                try:
                    remove("output.txt")  # get rid of the temp output if it exists
                except:
                    pass
                gFile = open("output.txt", "a")  # create temp file

                # stamp temp file
                gFile.write(";generated by ttglib: Ryan Zmuda 2021\n")

            # Add neccessary header commands
            # EXPLANATION:
            # G90 - absolute positioning
            # G21 - metric values
            # G1 F[string of number] - feedrate
            finalOperations.insert(0, "G90")
            finalOperations.insert(0, "G21")
            finalOperations.insert(0, "G1 F" + self.feedRate)

            returnList = []
            lastMoveType = ""

            for command in finalOperations:
                currentCommand = ""

                if (
                    command == "G90"
                    or command == "G21"
                    or command == "G1 F" + self.feedRate
                ):
                    currentCommand = command

                if command == self.onPowerCmd:
                    currentCommand = self.onPowerCmd
                elif command == self.offPowerCmd:
                    currentCommand = self.offPowerCmd

                if command == self.slowCmd:
                    lastMoveType = "slow"
                    pass
                elif command == self.fastCmd:
                    lastMoveType = "slow"
                    pass

                if type(command) == tuple:
                    if lastMoveType == "slow":
                        currentCommand += self.slowCmd
                    elif lastMoveType == "fast":
                        currentCommand += self.fastCmd
                    # TODO text size
                    currentCommand += " X" + str(command[0])
                    currentCommand += " Y" + str(command[1])

                if currentCommand != "":
                    returnList.append(currentCommand)

            if self.method == "return":
                return returnList

            elif self.method == "file":
                for line in returnList:
                    gFile.write(line + "\n")

                gFile.close()

                try:
                    remove("output.gcode")
                except:
                    pass

                rename(r"output.txt", r"output.gcode")

                return "output.gcode file generated successfully"

    def appendPoints(self, points):
        for point in points:
            self.operations.append(point)

    #  .o88b. db   db  .d8b.  d8888b.  .d8b.   .o88b. d888888b d88888b d8888b. .d8888.
    # d8P  Y8 88   88 d8' `8b 88  `8D d8' `8b d8P  Y8 `~~88~~' 88'     88  `8D 88'  YP
    # 8P      88ooo88 88ooo88 88oobY' 88ooo88 8P         88    88ooooo 88oobY' `8bo.
    # 8b      88~~~88 88~~~88 88`8b   88~~~88 8b         88    88~~~~~ 88`8b     `Y8b.
    # Y8b  d8 88   88 88   88 88 `88. 88   88 Y8b  d8    88    88.     88 `88. db   8D
    #  `Y88P' YP   YP YP   YP 88   YD YP   YP  `Y88P'    YP    Y88888P 88   YD `8888Y'

    def whiteSpace(self):
        # whitespace function for spaces
        self.currentXOffset += 4

    def a(self):

        #           .   .
        #       .           .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .   .   .   .   .   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (0 + xOff, 0),
            (0 + xOff, 7),
            (1 + xOff, 8),
            (2 + xOff, 9),
            (3 + xOff, 9),
            (4 + xOff, 8),
            (5 + xOff, 7),
            (5 + xOff, 0),
            "off",
            "fast",
            (5 + xOff, 4),
            "on",
            "slow",
            (0 + xOff, 4),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def b(self):

        #   .   .   .   .
        #   .               .
        #   .                   .
        #   .                   .
        #   .               .
        #   .   .   .   .
        #   .               .
        #   .                   .
        #   .                   .
        #   .   .   .   .   .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (0 + xOff, 0),
            (0 + xOff, 9),
            (3 + xOff, 9),
            (4 + xOff, 8),
            (5 + xOff, 7),
            (5 + xOff, 6),
            (4 + xOff, 5),
            (3 + xOff, 4),
            (0 + xOff, 4),
            "off",
            "fast",
            (3 + xOff, 4),
            "on",
            "slow",
            (4 + xOff, 3),
            (5 + xOff, 2),
            (5 + xOff, 1),
            (4 + xOff, 0),
            (0 + xOff, 0),
            "off",
            "fast",
        ]

        ttg.appendPoints(self, points)

    def c(self):

        #       .   .   .   .
        #   .                   .
        #   .
        #   .
        #   .
        #   .
        #   .
        #   .
        #   .                   .
        #       .   .   .   .

        xOff = self.currentXOffset

        points = [
            "off",
            "fast",
            (5 + xOff, 1),
            "on",
            "slow",
            (4 + xOff, 0),
            (1 + xOff, 0),
            (0 + xOff, 1),
            (0 + xOff, 8),
            (1 + xOff, 9),
            (4 + xOff, 9),
            (5 + xOff, 8),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def d(self):

        #   .   .   .   .
        #   .               .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .               .
        #   .   .   .   .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (0 + xOff, 9),
            (3 + xOff, 9),
            (4 + xOff, 8),
            (5 + xOff, 7),
            (5 + xOff, 2),
            (4 + xOff, 1),
            (3 + xOff, 0),
            (0 + xOff, 0),
            "off",
            "fast",
        ]

        ttg.appendPoints(self, points)

    def e(self):

        #   .   .   .   .   .   .
        #   .
        #   .
        #   .
        #   .   .   .   .   .   .
        #   .
        #   .
        #   .
        #   .
        #   .   .   .   .   .   .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (0 + xOff, 9),
            (5 + xOff, 9),
            "off",
            "fast",
            (5 + xOff, 5),
            "on",
            "slow",
            (0 + xOff, 5),
            "off",
            "fast",
            (5 + xOff, 0),
            "on",
            "slow",
            (0 + xOff, 0),
            "off",
            "fast",
        ]

        ttg.appendPoints(self, points)

    def f(self):

        #   .   .   .   .   .   .
        #   .
        #   .
        #   .
        #   .
        #   .   .   .   .   .   .
        #   .
        #   .
        #   .
        #   .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (0 + xOff, 9),
            (5 + xOff, 9),
            "off",
            "fast",
            (5 + xOff, 5),
            "on",
            "slow",
            (0 + xOff, 5),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def g(self):

        #       .   .   .   .
        #   .                   .
        #   .
        #   .
        #   .
        #   .               .   .
        #   .                   .
        #   .                   .
        #   .                   .
        #       .   .   .   .

        xOff = self.currentXOffset

        points = [
            "off",
            "fast",
            (5 + xOff, 8),
            "on",
            "slow",
            (4 + xOff, 9),
            (1 + xOff, 9),
            (0 + xOff, 8),
            (0 + xOff, 1),
            (1 + xOff, 0),
            (4 + xOff, 0),
            (5 + xOff, 1),
            (5 + xOff, 4),
            (4 + xOff, 4),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def h(self):

        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .   .   .   .   .   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (0 + xOff, 9),
            "off",
            "fast",
            (5 + xOff, 9),
            "on",
            "slow",
            (5 + xOff, 0),
            "off",
            "fast",
            (0 + xOff, 5),
            "on",
            "slow",
            (0 + xOff, 5),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def i(self):

        #   .   .   .   .   .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .
        #   .   .   .   .   .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (4 + xOff, 0),
            "off",
            "fast",
            (4 + xOff, 9),
            "on",
            "slow",
            (0 + xOff, 9),
            "off",
            "fast",
            (2 + xOff, 9),
            "on",
            "slow",
            (2 + xOff, 0),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def j(self):

        #   .   .   .   .   .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .
        #   .   .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (1 + xOff, 0),
            (2 + xOff, 1),
            (2 + xOff, 9),
            (0 + xOff, 9),
            "off",
            "fast",
            (2 + xOff, 9),
            "on",
            "slow",
            (4 + xOff, 9),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def k(self):

        #   .                   .
        #   .                   .
        #   .                   .
        #   .               .
        #   .           .
        #   .   .   .
        #   .           .
        #   .               .
        #   .                   .
        #   .                   .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (0 + xOff, 9),
            "off",
            "fast",
            (5 + xOff, 9),
            "on",
            "slow",
            (5 + xOff, 7),
            (4 + xOff, 6),
            (3 + xOff, 5),
            (2 + xOff, 4),
            (1 + xOff, 4),
            (2 + xOff, 4),
            (3 + xOff, 3),
            (4 + xOff, 2),
            (5 + xOff, 1),
            (5 + xOff, 0),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def l(self):

        #   .
        #   .
        #   .
        #   .
        #   .
        #   .
        #   .
        #   .
        #   .
        #   .   .   .   .   .   .

        xOff = self.currentXOffset

        points = [
            (0 + xOff, 9),
            "on",
            "slow",
            (0 + xOff, 0),
            (5 + xOff, 0),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def m(self):

        #   .                       .
        #   .   .               .   .
        #   .       .       .       .
        #   .           .           .
        #   .           .           .
        #   .                       .
        #   .                       .
        #   .                       .
        #   .                       .
        #   .                       .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (0 + xOff, 9),
            (1 + xOff, 8),
            (2 + xOff, 7),
            (3 + xOff, 6),
            (3 + xOff, 5),
            (3 + xOff, 6),
            (4 + xOff, 7),
            (5 + xOff, 8),
            (6 + xOff, 9),
            (6 + xOff, 0),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def n(self):

        #   .                   . APROXIMATE, letting the cnc handle this movement
        #   . .                 .
        #   .   .               .
        #   .      .            .
        #   .                   .
        #   .        .          .
        #   .                   .
        #   .          .        .
        #   .             .     .
        #   .                .  .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (0 + xOff, 9),
            (5 + xOff, 0),
            (5 + xOff, 9),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def o(self):

        #       .   .   .   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #       .   .   .   .

        xOff = self.currentXOffset

        points = [
            (0 + xOff, 1),
            "on",
            "slow",
            (0 + xOff, 8),
            (1 + xOff, 9),
            (4 + xOff, 9),
            (5 + xOff, 8),
            (5 + xOff, 1),
            (4 + xOff, 0),
            (1 + xOff, 0),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def p(self):

        #       .   .   .   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .   .   .   .   .
        #   .
        #   .
        #   .
        #   .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (0 + xOff, 8),
            (1 + xOff, 9),
            (4 + xOff, 9),
            (5 + xOff, 8),
            (5 + xOff, 5),
            (4 + xOff, 4),
            (0 + xOff, 4),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def q(self):

        #       .   .   .   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .               .
        #       .   .   .       .

        xOff = self.currentXOffset

        points = [
            (0 + xOff, 1),
            "on",
            "slow",
            (0 + xOff, 8),
            (1 + xOff, 9),
            (4 + xOff, 9),
            (5 + xOff, 8),
            (5 + xOff, 2),
            (4 + xOff, 1),
            (5 + xOff, 0),
            "off",
            "fast",
            (3 + xOff, 0),
            "on",
            "slow",
            (1 + xOff, 0),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def r(self):

        #       .   .   .
        #   .               .
        #   .                   .
        #   .                   .
        #   .               .
        #   .   .   .   .
        #   .               .
        #   .                   .
        #   .                   .
        #   .                   .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (0 + xOff, 8),
            (1 + xOff, 9),
            (3 + xOff, 9),
            (4 + xOff, 8),
            (5 + xOff, 7),
            (5 + xOff, 6),
            (4 + xOff, 5),
            (3 + xOff, 4),
            (0 + xOff, 4),
            "off",
            "fast",
            (3 + xOff, 4),
            "on",
            "slow",
            (4 + xOff, 3),
            (5 + xOff, 2),
            (5 + xOff, 0),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def s(self):

        #       .   .   .   .   .
        #   .
        #   .
        #   .
        #   .
        #       .   .   .   .
        #                       .
        #                       .
        #                       .
        #   .   .   .   .   .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (4 + xOff, 0),
            (5 + xOff, 1),
            (5 + xOff, 3),
            (4 + xOff, 4),
            (1 + xOff, 4),
            (0 + xOff, 5),
            (0 + xOff, 8),
            (1 + xOff, 9),
            (5 + xOff, 9),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def t(self):

        #   .   .   .   .   .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .

        xOff = self.currentXOffset

        points = [
            (2 + xOff, 0),
            "on",
            "slow",
            (2 + xOff, 9),
            "off",
            "fast",
            (0 + xOff, 9),
            "on",
            "slow",
            (4 + xOff, 9),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def u(self):

        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #   .                   .
        #       .   .   .   .

        xOff = self.currentXOffset

        points = [
            (0 + xOff, 9),
            "on",
            "slow",
            (0 + xOff, 1),
            (1 + xOff, 0),
            (4 + xOff, 0),
            (5 + xOff, 1),
            (5 + xOff, 9),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def v(self):

        #   .               .
        #   .               .
        #   .               .
        #   .               .
        #   .               . this one is also
        #   .               . interpolated as top left
        #   .               . bottom middle top right
        #   .               .
        #       .       .
        #           .

        xOff = self.currentXOffset

        points = [
            (0 + xOff, 9),
            "on",
            "slow",
            (2 + xOff, 0),
            (4 + xOff, 9),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def w(self):

        # this is gonna be really weird unvisualized interpolation, sorry
        # youre gonna have to read tuples to understand the point to point movement
        #   .       .       .       .
        #
        #
        #
        #
        #
        #
        #
        #
        #       .       .       .

        xOff = self.currentXOffset

        points = [
            (0 + xOff, 9),
            "on",
            "slow",
            (1 + xOff, 0),
            (2 + xOff, 9),
            (3 + xOff, 0),
            (4 + xOff, 9),
            (5 + xOff, 0),
            (6 + xOff, 9),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def x(self):

        # once again, gonna be interpolation
        #   .               .
        #
        #
        #
        #
        #           .
        #
        #
        #
        #   .               .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (4 + xOff, 9),
            "off",
            "fast",
            (0 + xOff, 9),
            "on",
            "slow",
            (4 + xOff, 0),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def y(self):

        #   .               .
        #   .               .
        #   .               .
        #   .               .
        #       .       .
        #           .
        #           .
        #           .
        #           .
        #           .

        xOff = self.currentXOffset

        points = [
            (2 + xOff, 0),
            "on",
            "slow",
            (2 + xOff, 4),
            (0 + xOff, 6),
            (0 + xOff, 9),
            "off",
            "fast",
            (4 + xOff, 9),
            "on",
            "slow",
            (4 + xOff, 6),
            (2 + xOff, 4),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def z(self):

        # more point to point interpolation? yeah lmao
        #   .                   .
        #
        #
        #
        #
        #
        #
        #
        #
        #   .                   .

        xOff = self.currentXOffset

        points = [
            (0 + xOff, 9),
            "on",
            "slow",
            (5 + xOff, 9),
            (0 + xOff, 0),
            (5 + xOff, 0),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    # d8b   db db    db .88b  d88. d8888b. d88888b d8888b. .d8888.
    # 888o  88 88    88 88'YbdP`88 88  `8D 88'     88  `8D 88'  YP
    # 88V8o 88 88    88 88  88  88 88oooY' 88ooooo 88oobY' `8bo.
    # 88 V8o88 88    88 88  88  88 88~~~b. 88~~~~~ 88`8b     `Y8b.
    # 88  V888 88b  d88 88  88  88 88   8D 88.     88 `88. db   8D
    # VP   V8P ~Y8888P' YP  YP  YP Y8888P' Y88888P 88   YD `8888Y'

    def one(self):

        #           .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .
        #           .

        xOff = self.currentXOffset

        points = [
            (2 + xOff, 0),
            "on",
            "slow",
            (2 + xOff, 9),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def two(self):

        #           .
        #   .               .
        #
        #
        #
        #
        #
        #
        #
        #   .   .   .   .   .

        xOff = self.currentXOffset

        points = [
            (4 + xOff, 0),
            "on",
            "slow",
            (0 + xOff, 0),
            (4 + xOff, 8),
            (2 + xOff, 9),
            (0 + xOff, 8),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def three(self):

        #  TODO might need to rewrite this, not the best 3
        #           .
        #   .               .
        #                   .
        #                   .
        #                   .
        #   .   .   .   .
        #                   .
        #                   .
        #   .               .
        #           .

        xOff = self.currentXOffset

        points = [
            (0 + xOff, 1),
            "on",
            "slow",
            (2 + xOff, 0),
            (4 + xOff, 1),
            (4 + xOff, 3),
            (3 + xOff, 4),
            (0 + xOff, 4),
            "off",
            "fast",
            (3 + xOff, 4),
            "on",
            "slow",
            (4 + xOff, 5),
            (4 + xOff, 8),
            (2 + xOff, 9),
            (0 + xOff, 8),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def four(self):

        #   .               .
        #   .               .
        #   .               .
        #   .               .
        #   .   .   .   .   .
        #                   .
        #                   .
        #                   .
        #                   .
        #                   .

        xOff = self.currentXOffset

        points = [
            (0 + xOff, 9),
            "on",
            "slow",
            (0 + xOff, 5),
            (4 + xOff, 5),
            "off",
            "fast",
            (4 + xOff, 9),
            "on",
            "slow",
            (4 + xOff, 0),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def five(self):

        #   .   .   .   .   .
        #   .
        #   .
        #   .
        #   .   .   .
        #               .
        #                   .
        #                   .
        #                   .
        #   .   .   .   .

        xOff = self.currentXOffset

        points = [
            (4 + xOff, 9),
            "on",
            "slow",
            (0 + xOff, 9),
            (0 + xOff, 5),
            (2 + xOff, 5),
            (4 + xOff, 3),
            (4 + xOff, 1),
            (3 + xOff, 0),
            (0 + xOff, 0),
            "off",
            "fast",
        ]

        ttg.appendPoints(self, points)

    def six(self):

        #           .   .   .
        #
        #   .
        #   .
        #   .       .
        #   .
        #   .               .
        #   .               .
        #   .
        #       .   .   .

        xOff = self.currentXOffset

        points = [
            (4 + xOff, 9),
            "on",
            "slow",
            (2 + xOff, 9),
            (0 + xOff, 7),
            (0 + xOff, 1),
            (1 + xOff, 0),
            (3 + xOff, 0),
            (4 + xOff, 2),
            (4 + xOff, 3),
            (2 + xOff, 5),
            (0 + xOff, 4),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def seven(self):

        #   .               .
        #
        #
        #
        #
        #
        #
        #
        #
        #   .

        xOff = self.currentXOffset

        points = [
            "on",
            "slow",
            (4 + xOff, 9),
            (0 + xOff, 9),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def eight(self):

        #       .       .
        #   .               .
        #   .               .
        #   .               .
        #       .       .
        #   .               .
        #   .               .
        #   .               .
        #   .               .
        #       .   .   .

        xOff = self.currentXOffset

        points = [
            (2 + xOff, 0),
            "on",
            "slow",
            (3 + xOff, 0),
            (4 + xOff, 1),
            (4 + xOff, 4),
            (3 + xOff, 5),
            (1 + xOff, 5),
            (0 + xOff, 6),
            (0 + xOff, 8),
            (1 + xOff, 9),
            (3 + xOff, 9),
            (4 + xOff, 8),
            (4 + xOff, 6),
            (3 + xOff, 5),
            (1 + xOff, 5),
            (0 + xOff, 4),
            (0 + xOff, 1),
            (1 + xOff, 0),
            (3 + xOff, 0),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def nine(self):

        #       .       .
        #
        #   .               .
        #
        #                   .
        #       .           .
        #                   .
        #                   .
        #                   .
        #                   .

        xOff = self.currentXOffset

        points = [
            (4 + xOff, 0),
            "on",
            "slow",
            (4 + xOff, 7),
            (3 + xOff, 9),
            (1 + xOff, 9),
            (0 + xOff, 7),
            (1 + xOff, 4),
            (4 + xOff, 4),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    def zero(self):

        #       .   .   .
        #   .               .
        #   .               .
        #   .               .
        #   .               .
        #   .               .
        #   .               .
        #   .               .
        #   .               .
        #       .   .   .

        xOff = self.currentXOffset

        points = [
            (0 + xOff, 1),
            "on",
            "slow",
            (0 + xOff, 8),
            (1 + xOff, 9),
            (3 + xOff, 9),
            (4 + xOff, 8),
            (4 + xOff, 1),
            (3 + xOff, 0),
            (1 + xOff, 0),
            (0 + xOff, 1),
            "off",
            "fast",
            (0 + xOff, 0),
        ]

        ttg.appendPoints(self, points)

    # d88888b  .d88b.   .d88b.  d888888b d88888b d8888b.
    # 88'     .8P  Y8. .8P  Y8. `~~88~~' 88'     88  `8D
    # 88ooo   88    88 88    88    88    88ooooo 88oobY'
    # 88~~~   88    88 88    88    88    88~~~~~ 88`8b
    # 88      `8b  d8' `8b  d8'    88    88.     88 `88.
    # YP       `Y88P'   `Y88P'     YP    Y88888P 88   YD

    # get and call functions for letter in given text and append them to queue
    def collectCharacters(self):

        # if anyone is currently reading this i want to apoligize
        # for these dogshit if statements, i dont want to make a dict and
        # python doesent let you use switches which would save me so many brain cells

        # side note, i have no idea why but these are running within .000001ms so i dont care anymore

        for char in self.text:
            if char == " ":
                ttg.whiteSpace(self)
                self.currentXOffset += 8

            elif char == "a" or char == "A":
                ttg.a(self)
                self.currentXOffset += 8

            elif char == "b" or char == "B":
                ttg.b(self)
                self.currentXOffset += 8

            elif char == "c" or char == "C":
                ttg.c(self)
                self.currentXOffset += 8

            elif char == "d" or char == "D":
                ttg.d(self)
                self.currentXOffset += 8

            elif char == "e" or char == "E":
                ttg.e(self)
                self.currentXOffset += 8

            elif char == "f" or char == "F":
                ttg.f(self)
                self.currentXOffset += 8

            elif char == "g" or char == "G":
                ttg.g(self)
                self.currentXOffset += 8

            elif char == "h" or char == "H":
                ttg.h(self)
                self.currentXOffset += 8

            elif char == "i" or char == "I":
                ttg.i(self)
                self.currentXOffset += 7

            elif char == "j" or char == "J":
                ttg.j(self)
                self.currentXOffset += 7

            elif char == "k" or char == "K":
                ttg.k(self)
                self.currentXOffset += 8

            elif char == "l" or char == "L":
                ttg.l(self)
                self.currentXOffset += 8

            elif char == "m" or char == "M":
                ttg.m(self)
                self.currentXOffset += 8

            elif char == "n" or char == "N":
                ttg.n(self)
                self.currentXOffset += 8

            elif char == "o" or char == "O":
                ttg.o(self)
                self.currentXOffset += 8

            elif char == "p" or char == "P":
                ttg.p(self)
                self.currentXOffset += 8

            elif char == "q" or char == "Q":
                ttg.q(self)
                self.currentXOffset += 8

            elif char == "r" or char == "R":
                ttg.r(self)
                self.currentXOffset += 8

            elif char == "s" or char == "S":
                ttg.s(self)
                self.currentXOffset += 8

            elif char == "t" or char == "T":
                ttg.t(self)
                self.currentXOffset += 7

            elif char == "u" or char == "U":
                ttg.u(self)
                self.currentXOffset += 8

            elif char == "v" or char == "V":
                ttg.v(self)
                self.currentXOffset += 7

            elif char == "w" or char == "W":
                ttg.w(self)
                self.currentXOffset += 9

            elif char == "x" or char == "X":
                ttg.x(self)
                self.currentXOffset += 7

            elif char == "y" or char == "Y":
                ttg.y(self)
                self.currentXOffset += 7

            elif char == "z" or char == "Z":
                ttg.z(self)
                self.currentXOffset += 8

            elif char == "1":
                ttg.one(self)
                self.currentXOffset += 7

            elif char == "2":
                ttg.two(self)
                self.currentXOffset += 7

            elif char == "3":
                ttg.three(self)
                self.currentXOffset += 7

            elif char == "4":
                ttg.four(self)
                self.currentXOffset += 7

            elif char == "5":
                ttg.five(self)
                self.currentXOffset += 7

            elif char == "6":
                ttg.six(self)
                self.currentXOffset += 7

            elif char == "7":
                ttg.seven(self)
                self.currentXOffset += 7

            elif char == "8":
                ttg.eight(self)
                self.currentXOffset += 7

            elif char == "9":
                ttg.nine(self)
                self.currentXOffset += 7

            elif char == "0":
                ttg.zero(self)
                self.currentXOffset += 7
            else:
                print("TextToGcode Error: Unsupported character ->", char)
                exit()

        return ttg.finalize(self)

    def encode(self):
        if self.readyForReturn and self.method == "visualize":
            return self.verts

        elif not self.readyForReturn:
            return ttg.collectCharacters(self)

    def toGcode(self, onPower, offPower, fast, slow):
        self.onPowerCmd = onPower
        self.offPowerCmd = offPower
        self.fastCmd = fast
        self.slowCmd = slow

        return ttg.encode(self)