#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Initialize the LCD with I2C address 0x27 and 16x2 dimensions
LiquidCrystal_I2C lcd(0x27, 16, 2);

const int led = 8;
const int buz = 12;

String morseCode = "";
int length = 0;

char ch;
char newChar;

int morseDot = 200;
int morseDash = 500;
int morseBetween = 500;
int morseSpace = 2000;
int morseLetters = 1000;

void dot() {
  Serial.print(".");
  lcd.print(".");
  digitalWrite(led, HIGH);
  tone(12, 1000);
  delay(morseDot);
  digitalWrite(led, LOW);
  noTone(12);
  delay(morseBetween);
}

void dash() {
  Serial.print("-");
  lcd.print("-");
  digitalWrite(led, HIGH);
  tone(12, 1000);
  delay(morseDash);
  digitalWrite(led, LOW);
  noTone(12);
  delay(morseBetween);
}

void let_A() { dot(); dash(); }
void let_B() { dash(); dot(); dot(); dot(); }
void let_C() { dash(); dot(); dash(); dot(); }
void let_D() { dash(); dot(); dot(); }
void let_E() { dot(); }
void let_F() { dot(); dot(); dash(); dot(); }
void let_G() { dash(); dash(); dot(); }
void let_H() { dot(); dot(); dot(); dot(); }
void let_I() { dot(); dot(); }
void let_J() { dot(); dash(); dash(); dash(); }
void let_K() { dash(); dot(); dash(); }
void let_L() { dot(); dash(); dot(); dot(); }
void let_M() { dash(); dash(); }
void let_N() { dash(); dot(); }
void let_O() { dash(); dash(); dash(); }
void let_P() { dot(); dash(); dash(); dot(); }
void let_Q() { dash(); dash(); dot(); dash(); }
void let_R() { dot(); dash(); dot(); }
void let_S() { dot(); dot(); dot(); }
void let_T() { dash(); }
void let_U() { dot(); dot(); dash(); }
void let_V() { dot(); dot(); dot(); dash(); }
void let_W() { dot(); dash(); dash(); }
void let_X() { dash(); dot(); dot(); dash(); }
void let_Y() { dash(); dot(); dash(); dash(); }
void let_Z() { dash(); dash(); dot(); dot(); }
void num1() { dot(); dash(); dash(); dash(); dash(); }
void num2() { dot(); dot(); dash(); dash(); dash(); }
void num3() { dot(); dot(); dot(); dash(); dash(); }
void num4() { dot(); dot(); dot(); dot(); dash(); }
void num5() { dot(); dot(); dot(); dot(); dot(); }
void num6() { dash(); dot(); dot(); dot(); dot(); }
void num7() { dash(); dash(); dot(); dot(); dot(); }
void num8() { dash(); dash(); dash(); dot(); dot(); }
void num9() { dash(); dash(); dash(); dash(); dot(); }
void num0() { dash(); dash(); dash(); dash(); dash(); }

void morse() {
  lcd.setCursor(0, 1); // Set cursor to the beginning of the second line
  lcd.clear(); // Clear the display before showing new letter
  lcd.setCursor(0, 1); // Reset cursor to second line after clearing
  if (ch == 'A' || ch == 'a') let_A();
  if (ch == 'B' || ch == 'b') let_B();
  if (ch == 'C' || ch == 'c') let_C();
  if (ch == 'D' || ch == 'd') let_D();
  if (ch == 'E' || ch == 'e') let_E();
  if (ch == 'F' || ch == 'f') let_F();
  if (ch == 'G' || ch == 'g') let_G();
  if (ch == 'H' || ch == 'h') let_H();
  if (ch == 'I' || ch == 'i') let_I();
  if (ch == 'J' || ch == 'j') let_J();
  if (ch == 'K' || ch == 'k') let_K();
  if (ch == 'L' || ch == 'l') let_L();
  if (ch == 'M' || ch == 'm') let_M();
  if (ch == 'N' || ch == 'n') let_N();
  if (ch == 'O' || ch == 'o') let_O();
  if (ch == 'P' || ch == 'p') let_P();
  if (ch == 'Q' || ch == 'q') let_Q();
  if (ch == 'R' || ch == 'r') let_R();
  if (ch == 'S' || ch == 's') let_S();
  if (ch == 'T' || ch == 't') let_T();
  if (ch == 'U' || ch == 'u') let_U();
  if (ch == 'V' || ch == 'v') let_V();
  if (ch == 'W' || ch == 'w') let_W();
  if (ch == 'X' || ch == 'x') let_X();
  if (ch == 'Y' || ch == 'y') let_Y();
  if (ch == 'Z' || ch == 'z') let_Z();
  if (ch == '1') num1();
  if (ch == '2') num2();
  if (ch == '3') num3();
  if (ch == '4') num4();
  if (ch == '5') num5();
  if (ch == '6') num6();
  if (ch == '7') num7();
  if (ch == '8') num8();
  if (ch == '9') num9();
  if (ch == '0') num0();
  if (ch == ' ') {
    delay(morseSpace);
    Serial.print(" / ");
    lcd.print(" / ");
  }

  Serial.print(" ");
  lcd.print(" ");
  delay(morseLetters);
}

void stringToMorse() {
  length = morseCode.length();
  for (int i = 0; i < length; i++) {
    ch = morseCode.charAt(i);
    lcd.setCursor(0, 0); // Set cursor to the first line to display the character
    lcd.print(ch); // Display the character on line 1
    morse();
  }
}

void setup() {
  Serial.begin(9600);
  lcd.init();  // Initialize the LCD
  lcd.backlight();  // Turn on the backlight
  pinMode(led, OUTPUT);
  pinMode(buz, OUTPUT);
  Serial.println("Apa yang mau ditulis: ");
  lcd.clear();
  lcd.print("Masukkan teks:");
}

void loop() {
  while (Serial.available()) {
    morseCode = Serial.readString();
    Serial.println(morseCode + " = ");
    lcd.clear();
    stringToMorse();
  }

  delay(1000);
}