#ifndef _UTILS
#define _UTILS

#include <Arduino.h>
#include "Config.h"

#define PORT_BREAK_CHAR 5
//#define LED_CAMCON 15
#define LED_CAMCON SCC_PB08


// Repeatedly cycle LED on and off for a given duration.
// Default is one cycle.
void Blink(int delay_ms, byte repeat = 1) {
    pinMode(LED_CAMCON, OUTPUT);
    while (repeat--)
    {
        digitalWrite(LED_CAMCON, HIGH);
        delay(delay_ms);
        digitalWrite(LED_CAMCON, LOW);
        delay(delay_ms);
    }
}


// Pass bytes from input stream to output stream
void portpass(Stream * in, Stream * out, bool localecho = false) {
    while (true) {
        if (in->available()) {
            unsigned char c = in->read();
            if (c == PORT_BREAK_CHAR) {
                break;
            }
            else{
                out->write(c);
            }
        }
        if (out->available()) {
            in->write(out->read());
        }
    }
}


// Write prompt string to the stream
void issue_prompt(Stream * in, const char * prompt) {
    in->println();
    in->print(prompt);
}


// Prompt user for a specfic one-character response within a timeout in
// milliseconds (default response is 'y').
// Return true if the user responds with the given character within the
// timeout period. Otherwise returns false.
// User can reset the timer by responding with backquote character (`).
#define RESET_CHAR '`'
bool confirm(Stream * in, const char * prompt, unsigned int cmdTimeout,
                                                        char look4='y') {
    unsigned long startTimer = millis();

    issue_prompt(in, prompt);
    while (startTimer <= millis() && millis() - startTimer < cmdTimeout) {
        // Wait on user input
        if (in->available()) {
            // Read the next char and reset timer if necessary
            char c = in->read();
            if (RESET_CHAR == c) {
                startTimer = millis();
                issue_prompt(in, prompt);
                continue;
            }
            if (tolower(c) == look4) {
                return true;
            } else {
                return false;
            }
        }
    }
    // timed out
    in->println();
    return false;
}


// Determine if input string matches the command, ignoring case.
// Match up to n characters.
// Return 0 if they match. Return -1 if input is less than command.
// Return 1 if input is more than command.
int strncmp_ci(const char * input, const char * command, int n) {
    size_t maxLength = n;

    // Coerce to shortest string
    if (strlen(input) < maxLength)
        maxLength = strlen(input);

    if (strlen(command) < maxLength)
        maxLength = strlen(command);

    for (unsigned int i=0; i < maxLength; i++) {
        if (tolower(input[i]) < tolower(command[i]))
            return -1;
        if (tolower(input[i]) > tolower(command[i]))
            return 1;
    }

    // string match up to n chars
    return 0;
}

// Config and output pin
void configOutputPin(uint32_t pin, uint32_t state) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, state);
}

// Config and output pin
void configInputPin(uint32_t pin) {
    pinMode(pin, INPUT);
}



#endif