#include <Arduino.h>
#include <M5Unified.h>

void setup() {
  auto cfg = M5.config();
  cfg.serial_baudrate = 115200; // シリアル通信を利用する。通信速度(ボーレート)を設定。
  M5.begin(cfg);

  M5.Display.setRotation(3);
  M5.Display.setTextScroll(true);
  M5.Display.setFont(&fonts::lgfxJapanGothic_16);
  M5.Display.println("整数 または 6文字の16進数(RRGGBB)を入力してください。");
  Serial.println("整数 または 6文字の16進数(RRGGBB)を入力してください。");
}

String str = ""; // String: 可変長の文字列クラス
void loop() {
  char buf[100] = {0};
  int pos = 0;
  while (Serial.available()) { //PCから送信された文字があるあいだ、くりかえす
    char c = Serial.read(); // 1バイト読み取る
    buf[pos] = c;           // 配列buf に格納
    pos++;    // 格納位置をひとつ右へ
  }
  if (pos > 0) {
    buf[pos] = 0;
    String sbuf = buf;
    sbuf.trim(); //文字列の前と後の空白と改行を取り除く（破壊的メソッド）
    str.concat(sbuf); // 文字列の連結 (意味としては、str = str + sbuf)
    Serial.println(str);
    if (isDigit(sbuf)) {
      int num = sbuf.toInt();
      Serial.println( num * num );
    }
    if (sbuf.length() == 6) { // RRGGBBとして、LCD画面の背景を塗りつぶす
      sbuf.toLowerCase();
      uint8_t r = hexToDec( sbuf.substring(0, 2) );
      uint8_t g = hexToDec( sbuf.substring(2, 4) );
      uint8_t b = hexToDec( sbuf.substring(4, 6) );
      M5.Display.fillScreen( getColorUInt16( r , g , b ) );
      M5.Display.setCursor(0, 70, 4);
      M5.Display.printf(" %02x %02x %02x \n", r, g, b);
      M5.Display.printf(" %d %d %d ", r, g, b);
    }
  }
  M5.delay(50);
}
//全ての文字が0〜9なら、1(true)を返す
bool isDigit(String s) {
  bool isAllDigit = true;
  const char *p = s.c_str(); // String.c_str() は、NULLで終端されたchar配列の先頭アドレスを返す
  while ( *p != 0 ) {
    if (*p < '0' || '9' < *p) isAllDigit = false;
    p++;
  }
  return isAllDigit;
}
// M5 用の、16ビットカラー値に変換 引用：https://qiita.com/nnn112358/items/ea6b5e81623ba690343c
uint16_t getColorUInt16(uint8_t red, uint8_t green, uint8_t blue) {
  return ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
}
// 引数hex が16進表記の文字列だと仮定して、10進の値を返す
uint8_t hexToDec(String hex) {
  int dec = 0;
  int tmp = 0;
  for (int p = 0; p < hex.length(); p++) {
    tmp = int(hex.charAt(p));
    if ( '0' <= tmp && tmp <= '9' ) tmp = tmp - '0';
    if ( 'a' <= tmp && tmp <= 'f' ) tmp = tmp - 'a' + 10;
    if ( 'A' <= tmp && tmp <= 'F' ) tmp = tmp - 'A' + 10;
    tmp = constrain(tmp, 0, 15); //例外処理
    dec = (dec * 16) + tmp;
  }
  return dec;
}