#include <Arduino.h>

void printBin(uint32_t value) {
  for (size_t i = 0; i < 32; i++) {
    Serial.printf("%d", value >> i & 1);
  }
  Serial.println();
}

struct Silbe {
  uint8_t start;
  uint8_t length;
  const char* name;
};

void printSilbe(const Silbe& silbe) {
  Serial.printf("%s", silbe.name);
}


const Silbe stundenSilben[] {
  {7,  4, "null"}, // NULL
  {11, 3, "ein"}, // EIN
  {24, 4, "zwei"}, // ZWEI
  {19, 4, "drei"}, // DREI
  {14, 4, "vier"}, // VIER
  {30, 4, "fuenf"}, // FÜNF
  {35, 4, "sech"}, // SECH
  {35, 5, "sechs"}, // SECHS
  {52, 4, "sieb"}, // SIEB
  {50, 6, "sieben"}, // SIEBEN
  {46, 4, "acht"}, // ACHT
  {42, 4, "neun"}, // NEUN
  {56, 4, "zehn"}, // ZEHN
  {61, 3, "elf"}, // ELF
  {65, 5, "zwoelf"}, // ZWÖLF
  {81, 3, "und"}, // UND
  {72, 7, "zwanzig"}  // ZWANZIG
};

const Silbe minutenSilben[] {
  {0,   0, ""},    // leer (keine Minute "Null")
  {88,  3, "ein"},   // EIN
  {88,  4, "eins"},   // EINS
  {93,  4, "zwei"},   // ZWEI
  {108, 4, "drei"},  // DREI
  {103, 4, "vier"},  // VIER
  {98,  4, "fuenf"},   // FÜNF
  {113, 4, "sech"},  // SECH
  {113, 5, "sechs"},  // SECHS
  {119, 4, "sieb"},  // SIEB
  {119, 6, "sieben"},  // SIEBEN
  {136, 4, "acht"},  // ACHT
  {131, 4, "neun"},  // NEUN
  {126, 4, "zehn"},  // ZEHN
  {140, 3, "und"},  // UND
  {144, 3, "elf"},  // ELF
  {148, 5, "zwoelf"},  // ZWÖLF
  {161, 7, "zwanzig"},  // ZWANZIG
  {154, 7, "dreiszig"},  // DREIßIG
  {168, 7, "vierzig"},  // VIERZIG
  {175, 7, "fuenfzig"}   // FÜNFZIG
};

const Silbe permanentSilben[] {
  {0, 2}, // ES
  {3, 3}, // IST
  {84, 3} // UHR
};

#define P_ES 1<<1
#define P_IST 1<<2
#define P_UHR 1<<3

#define  S_NULL 1<<0
#define  S_EIN  1<<1
#define  S_ZWEI 1<<2
#define  S_DREI 1<<3
#define  S_VIER 1<<4
#define  S_FUENF 1<<5
#define  S_SECH 1<<6
#define  S_SECHS 1<<7
#define  S_SIEB 1<<8
#define  S_SIEBEN 1<<9
#define  S_ACHT 1<<10
#define  S_NEUN 1<<11
#define  S_ZEHN 1<<12
#define  S_ELF 1<<13
#define  S_ZWOELF 1<<14
#define  S_UND 1<<15
#define  S_ZWANZIG 1<<16

#define M_NULL 0<<0
#define M_EIN 1<<1
#define M_EINS 1<<2
#define M_ZWEI 1<<3
#define M_DREI 1<<4
#define M_VIER 1<<5
#define M_FUENF 1<<6
#define M_SECH 1<<7
#define M_SECHS 1<<8
#define M_SIEB 1<<9
#define M_SIEBEN 1<<10
#define M_ACHT 1<<11
#define M_NEUN 1<<12
#define M_ZEHN 1<<13
#define M_UND 1<<14
#define M_ELF 1<<15
#define M_ZWOELF 1<<16
#define M_ZWANZIG 1<<17
#define M_DREISZIG 1<<18
#define M_VIERZIG 1<<19
#define M_FUENFZIG 1<<20

const uint32_t stunden[] {
  S_NULL,
  S_EIN,
  S_ZWEI,
  S_DREI,
  S_VIER,
  S_FUENF,
  S_SECHS,
  S_SIEBEN,
  S_ACHT,
  S_NEUN,
  S_ZEHN,
  S_ELF,
  S_ZWOELF,
  S_DREI  | S_ZEHN,
  S_VIER  | S_ZEHN,
  S_FUENF | S_ZEHN,
  S_SECH  | S_ZEHN,
  S_SIEB  | S_ZEHN,
  S_ACHT  | S_ZEHN,
  S_NEUN  | S_ZEHN,
  S_ZWANZIG,
  S_EIN  | S_UND | S_ZWANZIG,
  S_ZWEI | S_UND | S_ZWANZIG,
  S_DREI | S_UND | S_ZWANZIG,
};

const uint32_t minuten [] {
  M_NULL,
  M_EINS,
  M_ZWEI,
  M_DREI,
  M_VIER,
  M_FUENF,
  M_SECHS,
  M_SIEBEN,
  M_ACHT,
  M_NEUN,
  M_ZEHN,
  M_ELF,
  M_ZWOELF,
  M_DREI  | M_ZEHN,
  M_VIER  | M_ZEHN,
  M_FUENF | M_ZEHN,
  M_SECH  | M_ZEHN,
  M_SIEB  | M_ZEHN,
  M_ACHT  | M_ZEHN,
  M_NEUN  | M_ZEHN,
  M_ZWANZIG,
  M_EIN  | M_UND | M_ZWANZIG,
  M_ZWEI  | M_UND | M_ZWANZIG,
  M_DREI  | M_UND | M_ZWANZIG,
  M_VIER  | M_UND | M_ZWANZIG,
  M_FUENF  | M_UND | M_ZWANZIG,
  M_SECHS  | M_UND | M_ZWANZIG,
  M_SIEBEN  | M_UND | M_ZWANZIG,
  M_ACHT  | M_UND | M_ZWANZIG,
  M_NEUN  | M_UND | M_ZWANZIG,
  M_DREISZIG,
  M_EIN  | M_UND | M_DREISZIG,
  M_ZWEI  | M_UND | M_DREISZIG,
  M_DREI  | M_UND | M_DREISZIG,
  M_VIER  | M_UND | M_DREISZIG,
  M_FUENF  | M_UND | M_DREISZIG,
  M_SECHS  | M_UND | M_DREISZIG,
  M_SIEBEN  | M_UND | M_DREISZIG,
  M_ACHT  | M_UND | M_DREISZIG,
  M_NEUN  | M_UND | M_DREISZIG,
  M_VIERZIG,
  M_EIN  | M_UND | M_VIERZIG,
  M_ZWEI  | M_UND | M_VIERZIG,
  M_DREI  | M_UND | M_VIERZIG,
  M_VIER  | M_UND | M_VIERZIG,
  M_FUENF  | M_UND | M_VIERZIG,
  M_SECHS  | M_UND | M_VIERZIG,
  M_SIEBEN  | M_UND | M_VIERZIG,
  M_ACHT  | M_UND | M_VIERZIG,
  M_NEUN  | M_UND | M_VIERZIG,
  M_FUENFZIG,
  M_EIN  | M_UND | M_FUENFZIG,
  M_ZWEI  | M_UND | M_FUENFZIG,
  M_DREI  | M_UND | M_FUENFZIG,
  M_VIER  | M_UND | M_FUENFZIG,
  M_FUENF  | M_UND | M_FUENFZIG,
  M_SECHS  | M_UND | M_FUENFZIG,
  M_SIEBEN  | M_UND | M_FUENFZIG,
  M_ACHT  | M_UND | M_FUENFZIG,
  M_NEUN  | M_UND | M_FUENFZIG,
};

const uint8_t permanent[] {
  P_ES | P_IST | P_UHR
};

void printStunde(uint8_t stunde) {
  uint32_t silben = stunden[stunde];
  Serial.printf("Stunde %02d: ", stunde);
  for (uint32_t i = 0; i < 32; i++) {
    if ((silben >> i) & 1 == 1) printSilbe(stundenSilben[i]);
  }
  Serial.println();
}

void printMinute(uint8_t minute) {
  uint32_t silben = minuten[minute];
  Serial.printf("%02d: ", minute);
  for (uint32_t i = 0; i < 32; i++) {
    if ((silben >> i) & 1 == 1) printSilbe(minutenSilben[i]);
  }
  Serial.println();
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
//   for (uint8_t stunde=0; stunde <= 23; stunde++) printStunde(stunde);
  for (uint8_t minute=0; minute <= 59; minute++) printMinute(minute);

}

void loop() {
}