#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
#include <HX711_ADC.h>
#include <Ultrasonic.h>


#define trigPin 11 // Pin trigger sensor ultrasonik
#define echoPin 12 // Pin echo sensor ultrasonik
#define ledPin 13
#define hx711_dt A0
#define hx711_sck A1
#define ROWS 4
#define COLS 4
#define cal 0.42
#define batasBeras 30

char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte colPins[COLS] = {5, 4, 3, 2};
byte rowPins[ROWS] = {9, 8, 7, 6};

int selectedWeight = 0;
int totalBungkus = 0;
int page = 1;
String input;

LiquidCrystal_I2C lcd(0x27, 20, 4);
Ultrasonic ul(trigPin, echoPin);
Servo myServo;
HX711_ADC scale(hx711_dt, hx711_sck);
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);


void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  keypad.addEventListener(keypadEvent);

  scale.begin();
  scale.start(2000, true);
  if (scale.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
  }
  else {
    scale.setCalFactor(cal); // set calibration value (float)
    Serial.println("Startup is complete");
  }

  lcd.init(); // initialize the lcd
  lcd.backlight();

  myServo.attach(10); // Attach the servo to pin 10
  myServo.write(0); // Move the servo to the initial position (0 degrees)
}

void loop() {
  char key = keypad.getKey();

  if (ul.read() < batasBeras) {
    digitalWrite(ledPin, HIGH); // LED menyala
  } else {
    digitalWrite(ledPin, LOW);  // LED mati
  }
  
  switch(page) {
    case 1:
      lcd.setCursor(0,0);
      lcd.print("Select Weight :");
      if (!digitalRead(ledPin)) {
        lcd.setCursor(4, 1);
        lcd.print("Beras Kosong");
      } 
    break;

    case 2:
      lcd.setCursor(0,0);
      lcd.print("Enter Quantity :");
    break;

    case 3:
      lcd.setCursor(2,0);
      lcd.print("Penimbangan Beras");
      int i = 0;

      while (i < totalBungkus) {
        char key = keypad.getKey();
        lcd.setCursor(4, 1);
        lcd.print("Bungkus ke-");
        lcd.print(i + 1);
        if (ul.read() < batasBeras) {
          lcd.setCursor(0, 2);
          lcd.print("                    ");
          lcd.setCursor(0, 3);
          lcd.print("                    ");
          myServo.write(90); // Move the servo to the active position (90 degrees)
          do {
            scale.update();
          } while (scale.getData() < selectedWeight);

          myServo.write(0); // Move the servo back to the initial position (0 degrees)
          do {
            scale.update();
          } while (scale.getData() > 0);
        i++;
        } else {
          digitalWrite(ledPin, LOW);
          lcd.setCursor(4,2);
          lcd.print("Beras Habis!");
          lcd.setCursor(2,3);
          lcd.print("Kurang ");
          lcd.print(totalBungkus - i);
          lcd.print(" Bungkus");
        }
      }
      lcd.clear();
      page = 1;
    break;
  }
}

void keypadEvent(KeypadEvent key){
  switch (keypad.getState())	{
  case PRESSED:
    switch(page) {
      case 1:
      if (ul.read() < batasBeras) {
        lcd.setCursor(0, 1);
        lcd.print("                    ");
        if (key == 'A') {
          selectedWeight = 250;
          lcd.setCursor(8, 1);
          lcd.print("250g");
        } else if (key == 'B') {
          selectedWeight = 500;
          lcd.setCursor(8, 1);
          lcd.print("500g");
        } else if (key == 'C') {
          selectedWeight = 750;
          lcd.setCursor(8, 1);
          lcd.print("750g");
        } else if (key == 'D') {
          selectedWeight = 1000;
          lcd.setCursor(7, 1);
          lcd.print("1000g");
        } else if (key == '*') {
          selectedWeight = 0;
          lcd.setCursor(0, 1);
          lcd.print("                    ");
        } else if (key == '#' && selectedWeight != 0) {
          page = 2;
          lcd.clear();
        }
      }
      break;
      
      case 2:
        if (key == '#') {
          if (input != ""){
            page = 3;
            totalBungkus = input.toInt();
            lcd.clear();
            input = "";
          }
        } else if (key == '*') {
          // totalBungkus = 0;
          input = "";
          lcd.setCursor(0, 1);
          lcd.print("                    ");
        } else if (key != 'A' && key != 'B' && key != 'C' && key != 'D') {
          // totalBungkus = key - '0';
          input += key;
          lcd.setCursor(0,1);
          lcd.print(input);
        }
      break;

      case 3:
        if (key == '*' && ul.read() > batasBeras) {
          selectedWeight = 0;
          totalBungkus = 0;
          page = 1;
        }
      break;

    }
  }
}