  * Date: 17.09.2017
  */
 
+ STARTUP(WiFi.selectAntenna(ANT_EXTERNAL));
+ SYSTEM_MODE(AUTOMATIC)
+ SYSTEM_THREAD(ENABLED);
+
 #include "Grove_LCD_RGB_Backlight.h"
+
+#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)
 
 #define BUTTONPIN D2 // Button reserved for further usage
 #define BUZZERPIN D3 // Buzzer reserved for further usage

    Time.zone(+2.00);

    // Register the status of the box to Particle Cloud
    Particle.variable("switchState", (int32_t)switchState);

    // Register the configureTime as a cloud function
    Particle.function("time", configureTime);

#define SWITCHPIN D6 // Switch for "LOCKED" or "OPEN" status.
#define LEDPIN D7 // Status LED.

unsigned long lastSync = millis();

rgb_lcd lcd;

int switchState = LOW; // HIGH = locked, LOW = open
volatile bool requestDisplayStatus = true;
volatile bool requestDisplayTime = false;
volatile bool requestDisplayConfigurationTime = true;
volatile bool requestOpeningOperation = false;
volatile bool isLCDBusy = false;

class OpenOperation {
  public:

    OpenOperation() {
        _timer = new Timer(2000, (void (*)())&OpenOperation::callback, true);
    }

    void start() {
        // TODO: Check if box is arelady open
        // TODO: Delay 2 seconds after 2 consecutive open operations
        if (!isRunning()) {
            // Only open the box when it is closed
            if (switchState == HIGH) {
                lcd.setCursor(0,1);
                lcd.print("               ");
                lcd.setCursor(0,1);
                lcd.print("opening....");
                digitalWrite(RELAYPIN, HIGH);
                _timer->reset();
            }
        }
    }

    void stop() {
        digitalWrite(RELAYPIN, LOW);
        _timer->dispose();
    }

    bool isRunning() {
        return _timer->isActive();
    }

  private:
    Timer* _timer;
    void callback(void) {
        digitalWrite(RELAYPIN, LOW);
    }
};

Timer clockTimer(1000, updateTime); // timer used to display the clock on the lcd display

OpenOperation openOperation;
