#include "driver.h"
#include "TFT_eSPI.h"

#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>

#include "fortunes.h"
#include "coin_bitmaps.h"

#ifdef EPAPER_ENABLE
EPaper epaper;
#endif

Adafruit_MPU6050 mpu;

// =====================================================
// BITMAPS
// =====================================================

// =====================================================
// FORTUNE ICON
// =====================================================
static const unsigned char PROGMEM image_istockphoto_1759107584_612x612_bits[] = {0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x07,0xfe,0x1f,0xf0,0x00,0x00,0x00,0x00,0x00,0x1f,0xc0,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x07,0x80,0x00,0x00,0x00,0x01,0xe0,0x00,0x00,0x01,0xe0,0x00,0x00,0x00,0x07,0x80,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x03,0x80,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x01,0xc0,0x00,0x01,0xc0,0x00,0x00,0x00,0x00,0x01,0xe0,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x0c,0x00,0x00,0x00,0xc0,0x00,0x00,0x3c,0x00,0x1c,0x00,0x00,0x01,0xc0,0x00,0x00,0x3e,0x00,0x18,0x00,0x00,0x03,0x80,0x00,0x00,0x3e,0x00,0x18,0x00,0x00,0x03,0x80,0x00,0x00,0x1e,0x00,0x38,0x00,0x00,0x07,0x00,0x00,0x00,0x1f,0x00,0x30,0x00,0x00,0x0e,0x00,0x00,0x00,0x1b,0x00,0x30,0x00,0x00,0x1c,0x00,0x00,0x00,0x1b,0x00,0x70,0x00,0x00,0x18,0x00,0x00,0x00,0x1b,0x00,0x60,0x00,0x00,0x38,0x00,0x00,0x00,0x1b,0x00,0x60,0x00,0x00,0x70,0x00,0x00,0x00,0x1b,0x80,0x60,0x00,0x00,0x60,0x00,0x00,0x00,0x1b,0x80,0x60,0x00,0x00,0xe0,0x00,0x00,0x00,0x1b,0x80,0xe0,0x00,0x00,0xc0,0x00,0x00,0x00,0x19,0x80,0xc0,0x00,0x01,0xc0,0x00,0x00,0x00,0x3b,0x80,0xc0,0x00,0x03,0x80,0x00,0x00,0x00,0x33,0x80,0xc0,0x00,0x03,0x80,0x00,0x00,0x00,0x33,0x80,0xc0,0x00,0x03,0x00,0x00,0x00,0x00,0x33,0x80,0xc0,0x00,0x07,0x00,0x00,0x00,0x00,0x73,0x00,0xc0,0x00,0x1e,0x00,0x00,0x00,0x00,0x63,0x00,0xc0,0x00,0xfe,0x00,0x00,0x00,0x00,0xe3,0x00,0xe0,0x07,0xfc,0x00,0x00,0x00,0x00,0xc7,0x00,0x70,0x3f,0x8c,0x00,0x00,0x00,0x01,0xc7,0x00,0x7f,0xfc,0x1c,0x00,0x00,0x00,0x03,0x86,0x00,0x1f,0xc0,0x18,0x00,0x00,0x00,0x03,0x0e,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x07,0x8c,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x0f,0xdc,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x1d,0xfc,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x38,0xf8,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x70,0x78,0x00,0x00,0x00,0x70,0x00,0x00,0x01,0xe0,0x3c,0x00,0x00,0x00,0x60,0x00,0x00,0x03,0xc0,0x1e,0x00,0x00,0x00,0x60,0x00,0x00,0x0f,0x00,0x0f,0x00,0x00,0x00,0x60,0x00,0x00,0x3f,0x00,0x07,0x80,0x00,0x00,0x60,0x00,0x01,0xfb,0x80,0x03,0xc0,0x00,0x00,0x60,0x00,0x0f,0xe1,0xc0,0x01,0xe0,0x00,0x00,0x78,0x03,0xff,0x00,0xe0,0x00,0xe0,0x00,0x00,0x7f,0xff,0xf8,0x00,0x70,0x01,0xc0,0x00,0x00,0x7f,0xfe,0x00,0x01,0xf8,0x03,0x80,0x00,0x00,0x70,0x00,0x00,0x0f,0xdc,0x07,0x00,0x00,0x00,0x7c,0x00,0x00,0x7f,0x0e,0x0e,0x00,0x00,0x00,0x1f,0xf0,0x07,0xf8,0x07,0x1c,0x00,0x00,0x00,0x07,0xff,0xff,0xc0,0x03,0xb8,0x00,0x00,0x00,0x00,0x7f,0xfe,0x00,0x01,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00

  // PASTE FULL FORTUNE BITMAP ARRAY HERE

};

// =====================================================
// DICE ICON
// =====================================================
static const unsigned char PROGMEM image_sign_of_dice_symbol_is_isolated_on_a_white_background_dice_icon_color_editable_free_vector_bits[] = {0x00,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xe3,0xfd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x3f,0xc0,0x00,0x00,0x00,0x00,0x00,0x01,0xfc,0x00,0x1f,0xe0,0x00,0x00,0x00,0x00,0x00,0x07,0xf8,0x00,0x07,0xf8,0x00,0x00,0x00,0x00,0x00,0x3f,0xe0,0x00,0x01,0xfe,0x00,0x00,0x00,0x00,0x00,0x3f,0x80,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x3f,0xc0,0x00,0x00,0x00,0x03,0xfc,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x03,0xfc,0x00,0x00,0x00,0x3f,0xc0,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x7f,0x80,0x00,0x01,0xfe,0x00,0x00,0x00,0x00,0x00,0x1f,0xe0,0x00,0x03,0xf8,0x00,0x00,0x7f,0x80,0x00,0x07,0xf0,0x00,0x0f,0xe0,0x00,0x01,0xff,0xe0,0x00,0x01,0xfc,0x00,0x1f,0xc0,0x00,0x03,0xff,0xf0,0x00,0x00,0xfe,0x00,0x3f,0x80,0x00,0x07,0xff,0xf8,0x00,0x00,0x7e,0x00,0x3f,0x80,0x00,0x07,0xff,0xf8,0x00,0x00,0x7f,0x00,0x7f,0x80,0x00,0x07,0xff,0xf8,0x00,0x00,0x7f,0x80,0x7f,0x80,0x00,0x07,0xff,0xf8,0x00,0x00,0xff,0x80,0xff,0xe0,0x00,0x03,0xff,0xf0,0x00,0x01,0xff,0xc0,0xff,0xf8,0x00,0x00,0xff,0xc0,0x00,0x07,0xff,0xc0,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xc0,0xfe,0xff,0x00,0x00,0x00,0x00,0x00,0x7f,0xdf,0xc0,0xf8,0x3f,0x80,0x00,0x00,0x00,0x00,0x7f,0x07,0xc0,0xf0,0x1f,0xe0,0x00,0x00,0x00,0x01,0xfc,0x03,0xc0,0xf0,0x07,0xf8,0x00,0x00,0x00,0x07,0xf8,0x03,0xc0,0xf0,0x01,0xfe,0x00,0x00,0x00,0x1f,0xe0,0x03,0xc0,0xf0,0x00,0x7f,0x00,0x00,0x00,0x7f,0x80,0x03,0xc0,0xf0,0x00,0x3f,0xc0,0x00,0x00,0xfe,0x00,0x03,0xc0,0xf0,0x00,0x0f,0xf0,0x00,0x03,0xfc,0x07,0x83,0xc0,0xf0,0x30,0x03,0xfc,0x00,0x1f,0xf0,0x0f,0x83,0xc0,0xf0,0x7c,0x00,0xfe,0x00,0x1f,0xc0,0x1f,0x83,0xc0,0xf0,0x7e,0x00,0x7f,0x80,0x7f,0x80,0x1f,0x83,0xc0,0xf0,0x3e,0x00,0x1f,0xe1,0xfe,0x00,0x3f,0x03,0xc0,0xf0,0x3f,0x00,0x07,0xff,0xf8,0x00,0x1e,0x03,0xc0,0xf0,0x1f,0x00,0x03,0xff,0xe0,0x00,0x10,0x03,0xc0,0xf0,0x06,0x00,0x00,0xff,0x80,0x00,0x00,0x03,0xc0,0xf0,0x00,0x03,0x80,0x3f,0x00,0xe0,0x00,0x03,0xc0,0xf0,0x00,0x07,0xc0,0x1e,0x01,0xe0,0x00,0x03,0xc0,0xf0,0x00,0x03,0xe0,0x1e,0x03,0xe0,0x00,0x03,0xc0,0xf0,0x04,0x03,0xf0,0x1e,0x07,0xe0,0x00,0x03,0xc0,0xf0,0x78,0x01,0xf0,0x1e,0x07,0xc0,0x00,0x03,0xc0,0xf0,0x7c,0x00,0xf0,0x1e,0x07,0x80,0x00,0x03,0xc0,0xf0,0x3e,0x00,0x00,0x1e,0x00,0x00,0x00,0x03,0xc0,0xf0,0x3f,0x00,0x00,0x1e,0x00,0x00,0x00,0x03,0xc0,0xf0,0x1f,0x00,0x00,0x1e,0x00,0x00,0x00,0x03,0xc0,0xf0,0x0f,0x00,0x00,0x1e,0x00,0x00,0x00,0x03,0xc0,0xf0,0x00,0x03,0x00,0x1e,0x00,0x00,0x00,0x03,0xc0,0xf0,0x00,0x07,0xc0,0x1e,0x00,0x00,0x00,0x03,0xc0,0xf0,0x00,0x07,0xe0,0x1e,0x00,0x00,0x00,0x03,0xc0,0xf0,0x00,0x03,0xf0,0x1e,0x00,0x00,0x01,0xe3,0xc0,0xf0,0x38,0x01,0xf0,0x1e,0x00,0x00,0x03,0xe3,0xc0,0xf0,0x7c,0x01,0xf0,0x1e,0x00,0x00,0x0f,0xe3,0xc0,0xf0,0x7e,0x00,0x60,0x1e,0x00,0x00,0x0f,0xc3,0xc0,0xf0,0x3e,0x00,0x00,0x1e,0x00,0x00,0x0f,0x83,0xc0,0x70,0x3f,0x00,0x00,0x1e,0x00,0x00,0x0f,0x03,0x80,0x78,0x1f,0x00,0x00,0x1e,0x00,0x00,0x00,0x07,0x80,0x3c,0x06,0x00,0x00,0x1e,0x00,0x00,0x00,0x1f,0x00,0x1f,0x00,0x07,0xc0,0x1e,0x01,0xe0,0x00,0x3e,0x00,0x1f,0xc0,0x07,0xe0,0x1e,0x07,0xe0,0x00,0xfe,0x00,0x0f,0xf0,0x03,0xe0,0x1e,0x03,0xe0,0x03,0xf8,0x00,0x03,0xf8,0x03,0xf0,0x1e,0x07,0xe0,0x0f,0xf0,0x00,0x01,0xfe,0x01,0xf0,0x1e,0x07,0xc0,0x3f,0xe0,0x00,0x00,0x7f,0x80,0xf0,0x1e,0x07,0x80,0x7f,0x80,0x00,0x00,0x1f,0xc0,0x00,0x1e,0x00,0x01,0xfe,0x00,0x00,0x00,0x0f,0xf0,0x00,0x1e,0x00,0x03,0xf8,0x00,0x00,0x00,0x03,0xfc,0x00,0x1e,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,0xff,0x00,0x1e,0x00,0x3f,0xc0,0x00,0x00,0x00,0x00,0x3f,0x80,0x1e,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x1f,0xe0,0x1e,0x01,0xfc,0x00,0x00,0x00,0x00,0x00,0x07,0xf8,0x3f,0x07,0xf8,0x00,0x00,0x00,0x00,0x00,0x01,0xfe,0x7f,0x9f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00

  // PASTE FULL DICE BITMAP ARRAY HERE

};

// =====================================================
// COIN ICON
// =====================================================
static const unsigned char PROGMEM image_Screenshot_2026_05_12_101857_bits[] = {0x00,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0xf6,0x00,0x00,0x00,0x00,0x00,0x01,0xc7,0x00,0x00,0x00,0x00,0x00,0x03,0x0d,0x00,0x00,0x00,0x00,0x00,0x06,0x09,0x00,0x00,0x00,0x00,0x00,0x06,0x1b,0x00,0x00,0x00,0x00,0x00,0x04,0x72,0x00,0x00,0x00,0x00,0x00,0x0d,0xc6,0x20,0x00,0x00,0x00,0x00,0x07,0x9c,0x38,0x00,0x00,0x00,0x00,0x03,0x78,0x1c,0x00,0x00,0x00,0x00,0x01,0xe0,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x80,0x00,0x00,0x00,0x00,0x18,0x60,0x80,0x00,0x00,0x04,0x00,0x18,0x20,0xc0,0x00,0x00,0x0c,0x00,0x0c,0x30,0xc0,0x00,0x00,0x0c,0x00,0x04,0x18,0x40,0x00,0x03,0x0c,0x30,0x06,0x18,0x60,0x00,0x01,0x84,0x60,0x02,0x08,0x60,0x00,0x00,0xc0,0xc0,0x00,0x0c,0x60,0x00,0x00,0x00,0x00,0x00,0x0c,0x60,0x00,0x00,0x00,0x00,0x03,0x0c,0x60,0x00,0x00,0x3e,0x00,0x01,0x0c,0x60,0x00,0x0f,0x23,0x3e,0x01,0x00,0x60,0x00,0x00,0x21,0x80,0x01,0x00,0x40,0x00,0x00,0x21,0x80,0x03,0x00,0x40,0x00,0x00,0x20,0x80,0x03,0x00,0xc0,0x00,0x00,0x60,0x80,0x02,0x08,0xc0,0x00,0x00,0x60,0xc0,0x02,0x08,0x00,0x00,0x00,0x60,0xc0,0x06,0x18,0x00,0x00,0x00,0x40,0xc0,0x04,0x10,0x00,0x00,0x00,0x40,0xc0,0x0c,0x30,0x00,0x00,0x00,0xc0,0xc0,0x18,0x20,0x00,0x00,0x00,0x80,0xc0,0x30,0x60,0x00,0x00,0x01,0x80,0x80,0x30,0x00,0x00,0x00,0x03,0x00,0x80,0x20,0x00,0x00,0xff,0x86,0x01,0x80,0x00,0x00,0x00,0xff,0x8c,0x01,0x00,0x00,0x00,0x00,0xc1,0xf8,0x03,0xff,0xff,0xf0,0x00,0xc1,0x80,0x00,0x00,0x00,0x18,0x00,0xc1,0x80,0x00,0x00,0x00,0x0c,0x00,0xc1,0x80,0x00,0x00,0x00,0x0c,0x00,0xc1,0x80,0x00,0x00,0x00,0x0c,0x00,0xc1,0x80,0x00,0x00,0x00,0x18,0x00,0xc1,0x80,0x00,0x03,0xff,0xf0,0x00,0xc1,0x80,0x00,0x00,0x00,0xc0,0x00,0xc1,0x80,0x00,0x00,0x00,0x60,0x00,0xc1,0x80,0x00,0x00,0x00,0x20,0x00,0xc1,0x80,0x00,0x00,0x00,0x60,0x00,0xc1,0x80,0x00,0x00,0x00,0xc0,0x00,0xc1,0x80,0x00,0x03,0xff,0x80,0x00,0xc1,0x80,0x00,0x00,0x01,0x80,0x00,0xc1,0x80,0x00,0x00,0x01,0x80,0x00,0xc1,0x80,0x00,0x00,0x00,0x80,0x00,0xc1,0x80,0x00,0x00,0x01,0x80,0x00,0xc1,0x80,0x00,0x03,0xff,0x00,0x00,0xc1,0x80,0x00,0x03,0xfe,0x00,0x00,0xc1,0x80,0x00,0x00,0x0c,0x00,0x00,0xc1,0x80,0x00,0x00,0x04,0x00,0x00,0xc1,0xe0,0x00,0x00,0x04,0x00,0x00,0xc1,0xf8,0x00,0x00,0x0c,0x00,0x00,0xff,0x8f,0xff,0xff,0xf8,0x00,0x00,0xb6,0x03,0xff,0xff,0xe0,0x00,0x00

  // PASTE FULL COIN BITMAP ARRAY HERE

};

// =====================================================
// PINS
// =====================================================
#define BUTTON_PIN D9

// =====================================================
// APP MODES
// =====================================================
enum AppMode {
  FORTUNE_APP,
  DICE_APP,
  COIN_APP
};

AppMode currentApp = FORTUNE_APP;

// =====================================================
// SHAKE DETECTION
// =====================================================
float shakeThreshold = 30.0;

unsigned long lastShakeTime = 0;

unsigned long shakeCooldown = 1500;

// =====================================================
// BUTTON
// =====================================================
bool lastButtonState = HIGH;

// =====================================================
// FORTUNE RANDOMIZER
// =====================================================
int lastFortuneIndex = -1;

// =====================================================
// SETUP
// =====================================================
void setup() {

  Serial.begin(115200);

  pinMode(BUTTON_PIN, INPUT_PULLUP);

  // SDA = D4
  // SCL = D5
  Wire.begin(D4, D5);

#ifdef EPAPER_ENABLE
  epaper.begin();
#endif

  // =================================================
  // MPU6050 INIT
  // =================================================
  if (!mpu.begin()) {

    Serial.println("MPU6050 NOT FOUND");

#ifdef EPAPER_ENABLE

    epaper.fillScreen(TFT_WHITE);

    epaper.setTextColor(TFT_BLACK);

    epaper.setTextSize(2);

    epaper.drawCentreString("MPU6050", 100, 80, 1);

    epaper.drawCentreString("ERROR", 100, 110, 1);

    epaper.update();

#endif

    while (1) {
      delay(10);
    }
  }

  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);

  mpu.setGyroRange(MPU6050_RANGE_500_DEG);

  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);

  randomSeed(micros());

  showFortuneWelcome();
}

// =====================================================
// LOOP
// =====================================================
void loop() {

  handleButton();

  if (detectShake()) {

    switch (currentApp) {

      case FORTUNE_APP:
        showRandomFortune();
        break;

      case DICE_APP:
        rollDice();
        break;

      case COIN_APP:
        flipCoin();
        break;
    }
  }

  delay(50);
}

// =====================================================
// BUTTON HANDLING
// =====================================================
void handleButton() {

  bool buttonState = digitalRead(BUTTON_PIN);

  if (buttonState == LOW && lastButtonState == HIGH) {

    if (currentApp == FORTUNE_APP) {

      currentApp = DICE_APP;

      showDiceWelcome();
    }

    else if (currentApp == DICE_APP) {

      currentApp = COIN_APP;

      showCoinWelcome();
    }

    else {

      currentApp = FORTUNE_APP;

      showFortuneWelcome();
    }

    delay(300);
  }

  lastButtonState = buttonState;
}

// =====================================================
// SHAKE DETECTION
// =====================================================
bool detectShake() {

  sensors_event_t a, g, temp;

  mpu.getEvent(&a, &g, &temp);

  float totalAcceleration =
    abs(a.acceleration.x) +
    abs(a.acceleration.y) +
    abs(a.acceleration.z);

  if (totalAcceleration > shakeThreshold) {

    if (millis() - lastShakeTime > shakeCooldown) {

      lastShakeTime = millis();

      Serial.println("SHAKE DETECTED");

      return true;
    }
  }

  return false;
}

// =====================================================
// FORTUNE APP WELCOME
// =====================================================
void showFortuneWelcome() {

#ifdef EPAPER_ENABLE

  epaper.fillScreen(TFT_WHITE);

  // =================================================
  // ICON
  // =================================================
  epaper.drawBitmap(
    67,
    41,
    image_istockphoto_1759107584_612x612_bits,
    67,
    65,
    TFT_BLACK
  );

  // =================================================
  // TITLE
  // =================================================
  epaper.setTextColor(TFT_BLACK);

  epaper.setTextSize(2);

  epaper.setFreeFont(NULL);

  epaper.drawCentreString(
    "eFortune Cookie",
    100,
    126,
    1
  );

  // =================================================
  // SUBTEXT
  // =================================================
  epaper.setTextSize(1);

  epaper.drawCentreString(
    "Shake device to",
    100,
    173,
    1
  );

  epaper.drawCentreString(
    "know your fortune",
    100,
    185,
    1
  );

  epaper.update();

#endif
}

// =====================================================
// RANDOM FORTUNE
// =====================================================
void showRandomFortune() {

#ifdef EPAPER_ENABLE

  int randomIndex;

  do {

    randomIndex = random(fortuneCount);

  } while (randomIndex == lastFortuneIndex);

  lastFortuneIndex = randomIndex;

  String text = fortunes[randomIndex];

  epaper.fillScreen(TFT_WHITE);

  epaper.setTextColor(TFT_BLACK);

  epaper.setTextSize(2);


  // =================================================
  // TEXT SETTINGS
  // =================================================
  int maxWidth = 160;

  int lineHeight = 24;

  int maxLines = 7;

  String lines[10];

  int lineCount = 0;

  // =================================================
  // WORD WRAP
  // =================================================
  String currentLine = "";

  int start = 0;

  while (start < text.length()) {

    int spaceIndex = text.indexOf(' ', start);

    if (spaceIndex == -1) {
      spaceIndex = text.length();
    }

    String word = text.substring(start, spaceIndex);

    String testLine;

    if (currentLine.length() == 0) {

      testLine = word;
    }
    else {

      testLine = currentLine + " " + word;
    }

    int textWidth = epaper.textWidth(testLine);

    if (textWidth > maxWidth) {

      lines[lineCount] = currentLine;

      lineCount++;

      currentLine = word;

      if (lineCount >= maxLines) {
        break;
      }
    }
    else {

      currentLine = testLine;
    }

    start = spaceIndex + 1;
  }

  // =================================================
  // ADD LAST LINE
  // =================================================
  if (currentLine.length() > 0 && lineCount < maxLines) {

    lines[lineCount] = currentLine;

    lineCount++;
  }

  // =================================================
  // VERTICAL CENTER
  // =================================================
  int totalHeight = lineCount * lineHeight;

  int startY = (200 - totalHeight) / 2;

  // =================================================
  // DRAW TEXT
  // =================================================
  for (int i = 0; i < lineCount; i++) {

    epaper.drawCentreString(
      lines[i],
      100,
      startY + (i * lineHeight),
      1
    );
  }

  epaper.update();

#endif
}

// =====================================================
// DICE APP WELCOME
// =====================================================
void showDiceWelcome() {

#ifdef EPAPER_ENABLE

  epaper.fillScreen(TFT_WHITE);

  // =================================================
  // ICON
  // =================================================
  epaper.drawBitmap(
    63,
    25,
    image_sign_of_dice_symbol_is_isolated_on_a_white_background_dice_icon_color_editable_free_vector_bits,
    74,
    82,
    TFT_BLACK
  );

  // =================================================
  // TITLE
  // =================================================
  epaper.setTextColor(TFT_BLACK);

  epaper.setTextSize(2);

  epaper.setFreeFont(NULL);

  epaper.drawCentreString(
    "Roll a dice",
    100,
    126,
    1
  );

  // =================================================
  // SUBTEXT
  // =================================================
  epaper.setTextSize(1);

  epaper.drawCentreString(
    "Shake device to",
    100,
    173,
    1
  );

  epaper.drawCentreString(
    "Roll a dice",
    100,
    185,
    1
  );

  epaper.update();

#endif
}

// =====================================================
// ROLL DICE
// =====================================================
void rollDice() {

#ifdef EPAPER_ENABLE

  int diceNumber = random(1, 7);

  epaper.fillScreen(TFT_WHITE);

  epaper.drawRoundRect(
    25,
    25,
    150,
    150,
    20,
    TFT_BLACK
  );

  switch (diceNumber) {

    case 1:

      epaper.fillEllipse(100, 100, 10, 10, TFT_BLACK);

      break;

    case 2:

      epaper.fillEllipse(54, 54, 10, 10, TFT_BLACK);

      epaper.fillEllipse(145, 145, 10, 10, TFT_BLACK);

      break;

    case 3:

      epaper.fillEllipse(54, 54, 10, 10, TFT_BLACK);

      epaper.fillEllipse(100, 100, 10, 10, TFT_BLACK);

      epaper.fillEllipse(145, 145, 10, 10, TFT_BLACK);

      break;

    case 4:

      epaper.fillEllipse(54, 54, 10, 10, TFT_BLACK);

      epaper.fillEllipse(144, 54, 10, 10, TFT_BLACK);

      epaper.fillEllipse(54, 144, 10, 10, TFT_BLACK);

      epaper.fillEllipse(144, 144, 10, 10, TFT_BLACK);

      break;

    case 5:

      epaper.fillEllipse(54, 54, 10, 10, TFT_BLACK);

      epaper.fillEllipse(144, 54, 10, 10, TFT_BLACK);

      epaper.fillEllipse(100, 100, 10, 10, TFT_BLACK);

      epaper.fillEllipse(54, 144, 10, 10, TFT_BLACK);

      epaper.fillEllipse(144, 144, 10, 10, TFT_BLACK);

      break;

    case 6:

      epaper.fillEllipse(54, 54, 10, 10, TFT_BLACK);

      epaper.fillEllipse(144, 54, 10, 10, TFT_BLACK);

      epaper.fillEllipse(54, 100, 10, 10, TFT_BLACK);

      epaper.fillEllipse(144, 100, 10, 10, TFT_BLACK);

      epaper.fillEllipse(54, 144, 10, 10, TFT_BLACK);

      epaper.fillEllipse(144, 144, 10, 10, TFT_BLACK);

      break;
  }

  epaper.update();

#endif
}

// =====================================================
// COIN APP WELCOME
// =====================================================
void showCoinWelcome() {

#ifdef EPAPER_ENABLE

  epaper.fillScreen(TFT_WHITE);

  // =================================================
  // ICON
  // =================================================
  epaper.drawBitmap(
    74,
    37,
    image_Screenshot_2026_05_12_101857_bits,
    51,
    64,
    TFT_BLACK
  );

  // =================================================
  // TITLE
  // =================================================
  epaper.setTextColor(TFT_BLACK);

  epaper.setTextSize(2);

  epaper.setFreeFont(NULL);

  epaper.drawCentreString(
    "Flip a coin",
    100,
    129,
    1
  );

  // =================================================
  // SUBTEXT
  // =================================================
  epaper.setTextSize(1);

  epaper.drawCentreString(
    "Shake device to",
    100,
    173,
    1
  );

  epaper.drawCentreString(
    "Flip a coin",
    100,
    185,
    1
  );

  epaper.update();

#endif
}

// =====================================================
// FLIP COIN
// =====================================================
void flipCoin() {

#ifdef EPAPER_ENABLE

  bool isHead = random(0, 2);

  epaper.fillScreen(TFT_WHITE);

  
  if (isHead) {

    epaper.drawBitmap(
      0,
      0,
      head_bits,
      200,
      200,
      TFT_BLACK
    );
  }
  else {

    epaper.drawBitmap(
      0,
      0,
      tail_bits,
      200,
      200,
      TFT_BLACK
    );
  }

  epaper.update();

#endif
}