#include "U8glib.h"

// simple project using Arduino UNO and 128x64 OLED Display, showing a message with the fireworks animation
// created by upir, 2022
// youtube channel: https://www.youtube.com/channel/UCWHHWV_tkafsHNZ65V64sNQ

// youtube full tutorial: https://youtu.be/hIFDcksXgBk

// image2cpp (convert images into C code): https://javl.github.io/image2cpp/
// u8g fonts (fonts available for u8g library): https://nodemcu-build.com/u8g-fonts.php
// u8g documentation: https://github.com/olikraus/u8glib/wiki/userreference#getstrwidth
// Photopea (online Photoshop-like tool): https://www.photopea.com/
// Wokwi starting project: https://wokwi.com/arduino/projects/300867986768527882
// Transparent display buy: https://a.aliexpress.com/_mKGmhKg
// Arduino uno: http://store.arduino.cc/products/arduino-uno-rev3
// Arduino breadboard prototyping shield: https://www.adafruit.com/product/2077

// select SPI or IIC connection from the list below, or change it to match your display settings
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0 | U8G_I2C_OPT_NO_ACK | U8G_I2C_OPT_FAST); // Fast I2C / TWI
//U8GLIB_SSD1306_128X64 u8g(13, 11, 8, 9, 10); // SPI connection

int frame = 0;

const int sprite_count = 10; // number of sprites
int sprite_x[sprite_count];
int sprite_y[sprite_count];
int sprite_img[sprite_count];


// images generated by image2cpp

// 'frame_01', 8x8px
const unsigned char epd_bitmap_frame_01 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00
};
// 'frame_02', 8x8px
const unsigned char epd_bitmap_frame_02 [] PROGMEM = {
  0x00, 0x00, 0x28, 0x10, 0x28, 0x00, 0x00, 0x00
};
// 'frame_03', 8x8px
const unsigned char epd_bitmap_frame_03 [] PROGMEM = {
  0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00
};
// 'frame_04', 8x8px
const unsigned char epd_bitmap_frame_04 [] PROGMEM = {
  0x82, 0x44, 0x28, 0x00, 0x28, 0x44, 0x82, 0x00
};
// 'frame_05', 8x8px
const unsigned char epd_bitmap_frame_05 [] PROGMEM = {
  0x82, 0x44, 0x00, 0x10, 0x00, 0x44, 0x82, 0x00
};
// 'frame_06', 8x8px
const unsigned char epd_bitmap_frame_06 [] PROGMEM = {
  0x82, 0x00, 0x10, 0x38, 0x10, 0x00, 0x82, 0x00
};
// 'frame_07', 8x8px
const unsigned char epd_bitmap_frame_07 [] PROGMEM = {
  0x00, 0x10, 0x10, 0x6c, 0x10, 0x10, 0x00, 0x00
};
// 'frame_08', 8x8px
const unsigned char epd_bitmap_frame_08 [] PROGMEM = {
  0x10, 0x10, 0x00, 0xc6, 0x00, 0x10, 0x10, 0x00
};
// 'frame_09', 8x8px
const unsigned char epd_bitmap_frame_09 [] PROGMEM = {
  0x10, 0x00, 0x00, 0x82, 0x00, 0x00, 0x10, 0x00
};

// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 288)
const int epd_bitmap_allArray_LEN = 9;
const unsigned char* epd_bitmap_allArray[9] = {
  epd_bitmap_frame_01,
  epd_bitmap_frame_02,
  epd_bitmap_frame_03,
  epd_bitmap_frame_04,
  epd_bitmap_frame_05,
  epd_bitmap_frame_06,
  epd_bitmap_frame_07,
  epd_bitmap_frame_08,
  epd_bitmap_frame_09
};

const unsigned char upir_logo [] PROGMEM = {  // this is another way how to define images, using binary notation
B00010101,  B11010111,
B00010101,  B01000101,
B00010101,  B10010110,
B00011001,  B00010101     
};



void setup() {
  //u8g.setFont(u8g_font_tpssb);
  u8g.setColorIndex(1); // set color to white

  // setup random X and Y position and image for sprites
  for (int i = 0; i < sprite_count; i++) {
    sprite_x[i] = random(0, 128-8);
    sprite_y[i] = random(0, 64-8);
    sprite_img[i] = i % 8; // previously was sprite_img[i] = random(0, 8);, but this one looks better
  }
}

void loop() {
  u8g.firstPage();
  do {

      // draw all sprites
      for (int i = 0; i < sprite_count; i++) {
          u8g.drawBitmapP( sprite_x[i], sprite_y[i], 8/8, 8, epd_bitmap_allArray[sprite_img[i]]);
      }

      // draw first line of text, centered
      u8g.setFont(u8g_font_7x14);
      u8g.drawStr(128/2-u8g.getStrWidth("Thank you!")/2, 25, "Thank you!");

      // draw second line of text, centered
      u8g.setFont(u8g_font_6x13);
      u8g.drawStr(128/2-u8g.getStrWidth("For 100 Subscribers")/2, 45, "For 100 Subscribers");   

      // draw upir logo
      u8g.drawBitmapP(128-16, 64-4, 16/8, 4, upir_logo); 


  } while ( u8g.nextPage() );


  // update sprites with next image
  for (int i = 0; i < sprite_count; i++) {
    sprite_img[i]++; // increase current image
    if (sprite_img[i] > 8) {
      // last image == set new random position and first image
      sprite_x[i] = random(0, 128-8);
      sprite_y[i] = random(0, 64-8);
      sprite_img[i] = 0;
    }  
  }

  //delay(10);   // this is no longer needed, perhaps for the emulator to slow down the drawing a little bit

 
   
}