 Adafruit_SSD1306 Display(OLED_DC, OLED_RESET, OLED_CS);
 #endif
 
-#define ALARM_LENGTH 30000
+#define ALARM_LENGTH      30 * 1000 // 30 seconds
+#define SNUZE_LENGTH 10 * 60 * 1000 // 10 minutes TODO: make this configurable
+
 AlarmManager alarms = AlarmManager();
 
+State Start = State(enterStart, updateStart, exitStart);
+State Clock = State(updateClock);
+State Alarm = State(enterAlarm, updateAlarm, exitAlarm);
+State Snuze = State(enterSnuze, updateSnuze, exitSnuze); // Snooze is too many letters, broke my trend
+
+FSM stateMachine = FSM(Start);
+
+ClickButton button(BUTTON, HIGH);
+
 /*Thread renderer;*/
 
-/*Timer player(1, play);      // Play alarm tones 100x per second*/
-Timer renderer(100, render); // Render 10x per second
-Timer syncer(60000, sync);   // Sync cloud data once per minute
-
-Runtime alarmRuntime = Runtime();
-/*Runtime playerRuntime = Runtime();*/
-
-uint16_t speakerPin = D0;
-
-/*String song = "SMB Theme:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6";*/
-
-/*AlarmToneLanguage *parser;*/
+Timer player(1, play);       // Play alarm tone
+Timer renderer(200, render); // Render screen
+Timer syncer(1000, sync);   // Update Particle Cloud variables
+
+/*Runtime alarmRuntime  = Runtime();*/
+Runtime snuzeRuntime  = Runtime();
+Runtime playerRuntime = Runtime();
+
+String song = "SMB Theme:d=4,o=5,b=80:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6";
+
+AlarmToneLanguage *parser;
 
 int rssi = 0;
 uint32_t freeMemory = 0;
+uint32_t frameTime = 0;
+uint32_t loopTime = 0;
 
 uint8_t previousMinute;
 
 void setup() {
-  RGB.control(true);
+  pinMode(SPEAKER, OUTPUT);
+  pinMode(BUTTON, INPUT);
+
+  button.debounceTime   = 20;
+  button.multiclickTime = 20; // Only allow 1 click
+  button.longClickTime  = 2000;
 
   #if defined COLOR_SCREEN
   Display.begin();

#include "FiniteStateMachine.h"
#include "AlarmToneLanguage.h"
#include "AlarmManager.h"
#include "Runtime.h"

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);

State Start = State(NULL, updateStart, exitStart);
State Clock = State(updateClock);
State Alarm = State(enterAlarm, updateAlarm, exitAlarm);
// State Snuze = State(enterSnuze, updateSnuze, exitSnuze); // Snooze is too many letters, broke my trend

FSM stateMachine = FSM(Start);

// use hardware SPI
#define OLED_DC     D3
#define OLED_CS     D4
#define OLED_RESET  D5

#if defined COLOR_SCREEN
// Color definitions


  return result ? 1 : -1;
}

void drawIcon(uint16_t x, uint16_t y, uint16_t size, uint16_t signalStrength, uint16_t color, uint16_t dimColor) {
  uint16_t gap = size / 5;
  uint16_t unit = 127 / 5;

  x += gap / 2;
  y += size - gap / 2;

  for(int i = 0; i < 5; i++) {
    uint16_t radius = i * gap;
    Display.drawLine(x + radius, y, x + radius, y - (i + 1) * gap, signalStrength > i * unit ? color : dimColor);
  }
}
