#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "_sprite24x32.h"

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET 4

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  //  Serial.begin(9600);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  delay(50);
  display.invertDisplay(true);
  display.setTextSize(2);
  display.setTextColor(WHITE);
}

void loop() {
  test_icon();
  test48x64_v2();
}

void test_icon() {
  for (uint8_t i = 0; i < 7; i++) {
    set48x48(40, 1, i);
    display.setCursor(1, 1);
    display.println(i);
    delayAndClear(200);
  }
}

void test48x64_v2() {
  for (uint8_t j = 0; j < 4; j++) {
    for (uint8_t i = 0; i < 10; i++) {
      set48x64(40 + 24 + 4, 0, j, i, 0);
      set48x64(40 - 24 - 4, 0, 4 + j, i, 1);
      display.setCursor(1, 1);
      display.println(i);
      delayAndClear(200);
    }
  }
  for (uint8_t i = 0; i < 10; i++) {
    set48x64(40, 0, 8, i, 0);
    display.setCursor(1, 1);
    display.println(i);
    delayAndClear(200);
  }
}

void test48x64() {
  for (uint8_t j = 0; j < 9; j++) {
    for (uint8_t i = 0; i < 10; i++) {
      set48x64(40, 0, j, i, 0);
      delayAndClear(150);
    }
  }
}

/* Functions */

void delayAndClear(int x) {
  display.display();
  delay(x);
  display.clearDisplay();
}

/*
  void set24x32(int x, int y, int mon, int act, int mirror ) {
  readData_24x32(mon, act); // 讀取資料到 24x32暫存區
  if (mirror != 0) {        // 判斷是否鏡像
    SRAM_32to32_R(SRAM_32); // 鏡像 24x32暫存區
  }
  ssd1306_writeBuffer(24, 32, x, y, SRAM_32); //將 24x32暫存區 的資料寫入 螢幕的緩衝區
  }
*/

void set48x48(int x, int y, int icon) {
  readData_24x24(icon); // 讀取資料到 24x32暫存區
  SRAM_24to48(SRAM_32);
  ssd1306_writeBuffer(48, 48, x, y, SRAM_64); //將 48x64暫存區 的資料寫入 螢幕的緩衝區
}

void set48x64(int x, int y, int mon, int act, int mirror ) {
  readData_24x32(mon, act); // 讀取資料到 24x32暫存區
  if (mirror != 0) {        // 判斷是否鏡像
    SRAM_32to32_R(SRAM_32); // 鏡像 24x32暫存區
  }
  SRAM_32to64(SRAM_32);
  ssd1306_writeBuffer(48, 64, x, y, SRAM_64); //將 48x64暫存區 的資料寫入 螢幕的緩衝區
}

void ssd1306_writeBuffer(int size_X, int size_Y, int x, int y, uint8_t inarr[]) { // 比例, x座標, y座標*8, 暫存區陣列名稱
  char BufferX = size_X;
  char BufferY = size_Y;
  int BufferAdd;
  int tempX = x;
  tempX = (x < -48) ? -48 : x;
  tempX = (tempX > 128) ? 128 : tempX;
  /*
    for (int i = 0; i < (BufferY / 8); i++) {
      for (int j = 0; j < BufferX; j++) {
        BufferAdd = j + i * 128 + tempX + y * 128;
        display.getBuffer()[BufferAdd] = inarr[i * BufferX + j];
      }
    }
  */
  for (int i = 0; i < (BufferY / 8); i++) {
    for (int j = 0; j < BufferX; j++) {
      BufferAdd = j + i * 128 + tempX + y * 128;
      if ((tempX == -48) || tempX == 128) {
      }
      else if (BufferAdd < 0) {
      }
      else if (tempX < 0) {
        if ((j + i * 128 + x + y * 128) % 128 < 63) {
          display.getBuffer()[BufferAdd] = inarr[i * BufferX + j];
        }
      }
      else if (tempX > 79) {
        if ((j + i * 128 + x + y * 128) % 128 >= 63) {
          display.getBuffer()[BufferAdd] = inarr[i * BufferX + j];
        }
      }
      else {
        display.getBuffer()[BufferAdd] = inarr[i * BufferX + j];
      }
    }
  }
}