// due to numerous delays throughout the program, the button only registers while the 
// letter is off the screen hold the button for 1 second

// include manually created library that contains the letter matrices
#include "letter.h"
#include <EEPROM.h> // include library for memory 

String text; // Text to display on leds
boolean directionLR; // define direction boolean

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // begin serial monitor
  // serial print requesting text input
  Serial.println("Please enter text to display (no special characters or numbers)");

  //for loop that defines the pins that are connected to leds, pins conneced from pin
  // 23 to 53 in everysecond pin
  for (int i = 23; i < 55; i +=2 ){ 
    pinMode(i,OUTPUT); //declare led pins as outputs
    digitalWrite(i,LOW); // set leds off
  }

  pinMode(8, INPUT_PULLUP); // declare button pin
  directionLR = true; // set direction LR true, ie moving to the left
}

void loop() {
  // put your main code here, to run repeatedly:
  // if memory has an integer at the first position (purely for hard reset in wokwi, ie not used when reset button on mega pressed)
  if(EEPROM.read(0) == 1 || EEPROM.read(0) == 2 ||EEPROM.read(0) == 3 ||EEPROM.read(0) == 4 ||EEPROM.read(0) == 5||EEPROM.read(0) == 6 ||EEPROM.read(0) == 7 ||EEPROM.read(0) == 8||EEPROM.read(0) == 9){
  //do nothing
  } else { // if there is not an input in the memory then set the slot 0 to '1'
    EEPROM.write(0,1);
  }

  if (Serial.available() > 0) { //if there has been a user input
    text = Serial.readString(); // read the user input and save in string text
    EEPROM.write(0, text.length()); // write the length of the string in first slot of memory
    // this is used so the text constantly loops through
    for (int i = 1; i < EEPROM.read(0); i++){ // for the character after the length of the text 
    // for the text length 
      EEPROM.write(i, text.charAt(i-1)); // save the text letter to the associated memory slot
    }
  }

 // put your main code here, to run repeatedly:
  // define letter integer value, used for which letter being called in letter.h
  int letter = 0;
  char textLetter; //define character for storing each letter within text
  
    for (int i = 1; i < EEPROM.read(0); i++){ // for all letter slots in the memory
      textLetter = EEPROM.read(i);  // text letter = the letter in the text that the loop is currently up to
      // collected from the memory

      //case statement to find the letter int value assigned to each alphabet letter and compare
      // to the current letter (char) in the loop
      switch (textLetter){
        case 'A': // if letter capital A then 
          letter = 0; // define int letter = 0, for referencing in the letter.h
          break; // end the case checking once a comparison has been made for that letter
        //repeat for every letter of the alphabet, both capital and lowercase.
        case 'B':
          letter = 1;
          break;
        case 'C':
          letter = 2;
          break;
        case 'D':
          letter = 3;
          break;
        case 'E':
          letter = 4;
          break;
        case 'F':
          letter = 5;
          break;
        case 'G':
          letter = 6;
          break;
        case 'H':
          letter = 7;
          break;
        case 'I':
          letter = 8;
          break;
        case 'J':
          letter = 9;
          break;
        case 'K':
          letter = 10;
          break;
        case 'L':
          letter = 11;
          break;
        case 'M':
          letter = 12;
          break;
        case 'N':
          letter = 13;
          break;
        case 'O':
          letter = 14;
          break;
        case 'P':
          letter = 15;
          break;
        case 'Q':
          letter = 16;
          break;
        case 'R':
          letter = 17;
          break;
        case 'S':
          letter = 18;
          break;
        case 'T':
          letter = 19;
          break;
        case 'U':
          letter = 20;
          break;
        case 'V':
          letter = 21;
          break;
        case 'W':
          letter = 22;
          break;
        case 'X':
          letter = 23;
          break;
        case 'Y':
          letter = 24;
          break;
        case 'Z':
          letter = 25;
          break;
        case 'a':
          letter = 0;
          break;
        case 'b':
          letter = 1;
          break;
        case 'c':
          letter = 2;
          break;
        case 'd':
          letter = 3;
          break;
        case 'e':
          letter = 4;
          break;
        case 'f':
          letter = 5;
          break;
        case 'g':
          letter = 6;
          break;
        case 'h':
          letter = 7;
          break;
        case 'i':
          letter = 8;
          break;
        case 'j':
          letter = 9;
          break;
        case 'k':
          letter = 10;
          break;
        case 'l':
          letter = 11;
          break;
        case 'm':
          letter = 12;
          break;
        case 'n':
          letter = 13;
          break;
        case 'o':
          letter = 14;
          break;
        case 'p':
          letter = 15;
          break;
        case 'q':
          letter = 16;
          break;
        case 'r':
          letter = 17;
          break;
        case 's':
          letter = 18;
          break;
        case 't':
          letter = 19;
          break;
        case 'u':
          letter = 20;
          break;
        case 'v':
          letter = 21;
          break;
        case 'w':
          letter = 22;
          break;
        case 'x':
          letter = 23;
          break;
        case 'y':
          letter = 24;
          break;
        case 'z':
          letter = 25;
          break;
        case ' ': // if 'letter' in text is a space 
          letter = 26;
          break;
        default: // if the 'letter' we are up to is not a letter or a space
          letter = 27;
          break;
      }

    
    if(digitalRead(8) == LOW && directionLR == true){ // if button has been pressed and is currently
    // moving to the left then 
      delay(500); // delay so program doesnt read one press as numerous
      directionLR = false; // set direction as false to move from left to right
    } else if (digitalRead(8) == LOW && directionLR == false){ // if button has been pressed and is 
    //currently moving to the right then 
      delay(500); // delay so program doesnt read one press as numerous
      directionLR = true; // set direction as true to move from right to left
    }

    if (directionLR == true){ // if running to the left 
      for (int m = -6 ; m < 6; m++){ //for loop to run through the columns lit up,
      // -6 to 6, rather than range of 8 so that the letters scroll starting off the leds and moving
      // all the way across and off.
        for (int k = 0; k < 8 ; k++){ // for loop to run to control columns so each so each 
        // can display something different on the rows 
          if (k + m <= 8 && k + m >= 0){ //if the range within the 0 to 8, ie on the led, then turn the
          // the appropriate leds on, otherwise don't. This prevents the text from wrapping.
            
            // library_display is the function within the letter.h to call each letter
            // digitalWrite(pin from top to bottom, library_display[letter][corresponding row to pin][column]
            digitalWrite(23, library_display[letter][0][k+m]);
            digitalWrite(25, library_display[letter][1][k+m]);
            digitalWrite(27, library_display[letter][2][k+m]);
            digitalWrite(29, library_display[letter][3][k+m]);
            digitalWrite(31, library_display[letter][4][k+m]);
            digitalWrite(33, library_display[letter][5][k+m]);
            digitalWrite(35, library_display[letter][6][k+m]);
            digitalWrite(37, library_display[letter][7][k+m]);

            digitalWrite((39 + 2*k ), LOW); // set the output of every second pin connected
            // to led cathode to low at the time of the k value
            delay(1); // very short delay to appear constantly on
            digitalWrite((39 + 2*k ), HIGH); // set the output of every second pin connected
            // to led cathode (same pin as above) to high at the time of the k value
          }
        }
        // delay of 0.1 seconds between each movement of the letter across leds
        delay(100);
      }
    }

    if (directionLR == false){ // if running to the right
      for (int m = 6 ; m > -6; m--){//for loop to run through the columns lit up,
      // 6 to -6, rather than range of 8 so that the letters scroll starting off the leds and moving
      // all the way across and off, 6 as the start going down to start at the left and increment to right
        for (int k = 0; k < 8 ; k++){ // for loop to run to control columns so each so each 
        // can display something different on the rows 
          if (k + m <= 8 && k + m >= 0){ //if the range within the 0 to 8, ie on the led, then turn the
          // the appropriate leds on, otherwise don't. This prevents the text from wrapping.
            
            // library_display is the function within the letter.h to call each letter
            // digitalWrite(pin from top to bottom, library_display[letter][corresponding row to pin][column]
            digitalWrite(23, library_display[letter][0][k+m]);
            digitalWrite(25, library_display[letter][1][k+m]);
            digitalWrite(27, library_display[letter][2][k+m]);
            digitalWrite(29, library_display[letter][3][k+m]);
            digitalWrite(31, library_display[letter][4][k+m]);
            digitalWrite(33, library_display[letter][5][k+m]);
            digitalWrite(35, library_display[letter][6][k+m]);
            digitalWrite(37, library_display[letter][7][k+m]);

            digitalWrite((39 + 2*k ), LOW); // set the output of every second pin connected
            // to led cathode to low at the time of the k value
            delay(1); // very short delay to appear constantly on
            digitalWrite((39 + 2*k ), HIGH); // set the output of every second pin connected
            // to led cathode (same pin as above) to high at the time of the k value
          }
        }
          // delay of 0.1 seconds between each movement of the letter across leds
          delay(100);
      }
    }
  }
}