// ESP32 WiFi Jokes Client
//
// https://wokwi.com/arduino/projects/336743172331799123
//
// Copyright (C) 2022, Uri Shaked

#include <WiFi.h>
#include <LiquidCrystal_I2C.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>

LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 20, 4);

String getJoke() {
  HTTPClient http;
  http.useHTTP10(true);
  http.begin("https://v2.jokeapi.dev/joke/Programming");
  http.GET();
  String result = http.getString();

  Serial.println(result);

  DynamicJsonDocument doc(2048);
  DeserializationError error = deserializeJson(doc, result);

  // Test if parsing succeeds.
  if (error) {
    Serial.print("deserializeJson() failed: ");
    Serial.println(error.c_str());
    return "<error>";
  }

  String type = doc["type"].as<String>();
  String joke = doc["joke"].as<String>();
  String setup = doc["setup"].as<String>();
  String delivery = doc["delivery"].as<String>();
  http.end();
  return type.equals("single") ? joke : setup + "  " + delivery;
}

void spinner() {
  static int8_t counter = 0;
  const char* glyphs = "\xa1\xa5\xdb";
  LCD.setCursor(15, 1);
  LCD.print(glyphs[counter++]);
  if (counter == strlen(glyphs)) {
    counter = 0;
  }
}

void setup() {
  Serial.begin(115200);
  delay(10);

  LCD.init();
  LCD.backlight();
  LCD.setCursor(0, 0);
  LCD.print("Connecting to ");
  LCD.setCursor(0, 1);
  LCD.print("WiFi ");

  WiFi.begin("Wokwi-GUEST", "");
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    spinner();
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  LCD.clear();
  LCD.setCursor(0, 0);
  LCD.println("Online");
  LCD.setCursor(0, 2);
  LCD.println("Getting jokes...");
}

void loop() {
  String joke = getJoke();
  LCD.clear();
  for (int line = 0; line < 4; line++) {
    LCD.setCursor(0, line);
    LCD.print(joke.substring(line * 20, (line + 1) * 20));
  }
  delay(4000);
}