#include <Arduino.h>

#include "Utils.h"
#include "Config.h"
#include "SystemControl.h"
#include "Sensors.h"
#include "SystemTrigger.h"
#include "SystemConfig.h"

// Global system control variable
SystemControl sys;

// High Mag Trigger Callback
void TriggerCallback()
{
    // TODO: Add heartbeat or other periodic events
}

// Wrapper for updaing timers and flashes from callback functions
void setTriggers() {
    sys.setTriggers();
}

void setFlashes() {
    sys.configureFlashDurations();
}

void setPolling() {
    sys.setPolling();
}


void setup() {

    // Blink LED quickly so humans see that we are up and running
    Blink(50, 5);

    // Start the debug port
    DEBUGPORT.begin(115200);
    // TODO: Do we need this for the other serial ports?

    delay(1000);
    Blink(50, 2);

    // Startup all system processes
    sys.begin();

    // Add config parameters for system
    // IMPORTANT: add parameters at the end of the list, otherwise you'll need to reflash the saved params in EEPROM before reading
    sys.cfg.addParam(LOGINT, "Time in ms between log events", "ms", 0, 100000, 250);
    sys.cfg.addParam(LOCALECHO, "When > 0, echo serial input", "", 0, 1, 1);
    sys.cfg.addParam(CMDTIMEOUT, "time in ms before timeout waiting for user input", "ms", 1000, 100000, 10000);
    // Probably only need 1 or 2 of these ports
    sys.cfg.addParam(HWPORT1BAUD, "Serial Port 1 baud rate", "baud", 9600, 115200, 115200);
    sys.cfg.addParam(HWPORT3BAUD, "Serial Port 3 baud rate", "baud", 9600, 115200, 115200);
    sys.cfg.addParam(HWPORT5BAUD, "Serial Port 5 baud rate", "baud", 9600, 115200, 115200);
    sys.cfg.addParam(STROBEDELAY, "Time between camera trigger and strobe trigger in us", "us", 5, 1000, 50, false, setFlashes);
    sys.cfg.addParam(FRAMERATE, "Camera frame rate in Hz", "Hz", 1, 60, 10, false, setTriggers);
    sys.cfg.addParam(TRIGWIDTH, "Width of the camera trigger pulse in us", "us", 30, 10000, 100, false, setFlashes);
    sys.cfg.addParam(FLASHDUR, "Width of the flash in us", "us", 1, 100000, 10, false, setFlashes);
    sys.cfg.addParam(CHECKHOURLY, "0 = check every minute, 1 = check every hour", "", 0, 1, 0);
    sys.cfg.addParam(STARTUPTIME, "Time in seconds before performing any system checks", "s", 0, 60, 10);
    sys.cfg.addParam(WATCHDOG, "0 = no watchdog, 1 = hardware watchdog timer with 8 sec timeout","", 0, 1, 0);
    sys.cfg.addParam(TEMPLIMIT, "Temerature in C where controller will shutdown and power off camera","C", 0, 80, 55);
    sys.cfg.addParam(HUMLIMIT, "Humidity in % where controller will shutdown and power off camera","%", 0, 100, 60);
    sys.cfg.addParam(MAXSHUTDOWNTIME, "Max time in seconds we wait before cutting power to camera", "s", 15, 60, 60);
    sys.cfg.addParam(CHECKINTERVAL, "Time in seconds between check for bad operating evironment", "s", 10, 3600, 30);

    // configure watchdog timer if enabled
    //sys.configWatchdog();

    // Start the UARTs
    HWPORT1.begin(sys.cfg.getInt(HWPORT1BAUD));
    HWPORT3.begin(sys.cfg.getInt(HWPORT3BAUD));
    HWPORT5.begin(sys.cfg.getInt(HWPORT5BAUD));

    // Config the SERCOM muxes AFTER starting the ports
    configSerialPins();

    // Load the last config from EEPROM
    sys.readConfig();

    // User opportunity to run some tests before entering the main loop
    // Moved this to a command rather than always running at startup
    //scctest.test_interactively();

    // Setup flashes triggers and polling
    //setFlashes();
    //setTriggers();
    //setPolling();

    // Turn on the system
    //sys.turnOnSystem();

}

void loop() {

    sys.update();
    sys.checkInput();

    int logInt = sys.cfg.getInt(LOGINT);
    delay(logInt);
    Blink(10, 1);

}
