#include <Keypad.h>
#include <Wire.h>
#include <U8g2lib.h>

// Configuration du clavier
const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
  { '1', '2', '3', '+' },
  { '4', '5', '6', '-' },
  { '7', '8', '9', '/' },
  { '*', '0', '=', 'D' }
};

uint8_t colPins[COLS] = { 7, 6, 5, 4 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 1, 0, 3, 2 }; // Pins connected to R1, R2, R3, R4

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// Configuration de l'écran OLED
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

String inputString = ""; // Pour stocker l'entrée du clavier

void setup() {
  Serial.begin(9600);
  u8g2.begin();
}

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

  if (key != NO_KEY) {
    Serial.println(key);

    if (key == 'C') {
      // Effacer l'écran et réinitialiser la chaîne d'entrée
      inputString = "";
      displayKey(inputString);
    } else if (key == '=') {
      // Évaluer l'expression mathématique et afficher le résultat
      double result = evaluateExpression(inputString);
      inputString = String(result);
      displayKey(inputString);
    } else {
      // Ajouter la touche à la chaîne d'entrée
      inputString += key;
      displayKey(inputString);
    }
  }
}

void displayKey(String str) {
  u8g2.clearBuffer();                 // Effacer le tampon de l'écran
  u8g2.setFont(u8g2_font_ncenB08_tr); // Sélectionner une police
  u8g2.drawStr(0, 10, str.c_str());   // Dessiner la chaîne à afficher
  u8g2.sendBuffer();                  // Transférer le tampon à l'écran
}

double evaluateExpression(String expr) {
  double result = 0;
  char op = 0;
  String number = "";
  
  for (int i = 0; i < expr.length(); i++) {
    char c = expr.charAt(i);
    
    if (c >= '0' && c <= '9') {
      number += c;
    } else {
      if (number.length() > 0) {
        if (op == 0) {
          result = number.toDouble();
        } else {
          result = performOperation(result, number.toDouble(), op);
        }
        number = "";
      }
      op = c;
    }
  }
  
  if (number.length() > 0) {
    result = performOperation(result, number.toDouble(), op);
  }
  
  return result;
}

double performOperation(double num1, double num2, char op) {
  switch (op) {
    case '+': return num1 + num2;
    case '-': return num1 - num2;
    case '*': return num1 * num2;
    case '/': return num2 != 0 ? num1 / num2 : 0; // Eviter la division par zéro
    default: return num1;
  }
}