#ifndef _LED_H_
#define _LED_H_


#include <Adafruit_NeoPixel.h>


#define LED_PIN 3
#define LED_COUNT  16

// NeoPixel brightness, 0 (min) to 255 (max)
#define BRIGHTNESS 50 // Set BRIGHTNESS to about 1/5 (max = 255)

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);

unsigned long last_ledupdate=0;
#define LEDUPDATEINTERVAL 100

uint8_t led_errorcount=0; //count led progress errors. used for delay at end if any errors occured

void led_dotcircle(unsigned long loopmillis);
void led_voltage(unsigned long loopmillis,float vbat,float vbat_min,float vbat_max);

void init_led() {
  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(BRIGHTNESS);
}

void led_testLEDSBlocking(){
    strip.clear();
    strip.show();
    delay(10);
    uint32_t color=strip.Color(0,   0,   0, 0);

    for(int i=0; i<strip.numPixels()*4; i++) { // For each pixel in strip...
        switch(i/strip.numPixels()) {
            case 0:
                color=strip.Color(255,   0,   0, 0);
            break;
            case 1:
                color=strip.Color(0,   255,   0, 0);
            break;
            case 2:
                color=strip.Color(0,   0,   255, 0);
            break;
            case 3:
                color=strip.Color(0,   0,   0, 255);
            break;
        }
        strip.setPixelColor(i%strip.numPixels(), color);
        strip.show();
        delay(25);
    }
    strip.clear();
    strip.show();
}

void led_simpeProgress(uint8_t progressID,uint8_t result){
    if (result!=1) {
        led_errorcount++;
    }
    uint32_t color=strip.Color(0,   0,   0, 0);
    switch(result) {
        case 0: //fail
            color=strip.Color(255,   0,   0, 0);
        break;
        case 1: //success
            color=strip.Color(0,   255,   0, 0);
        break;
        case 2: //warning
            color=strip.Color(127,   127,   0, 0);
        break;
    }
    strip.setPixelColor(progressID, color);
    strip.show();
}

void led_simpleProgressWait() {
    if (led_errorcount>0) {
        delay(5000);
    }else{
        delay(100);
    }
}

void led_update(unsigned long loopmillis,ESCSerialComm& escFront, ESCSerialComm& escRear) {
    if (loopmillis>last_ledupdate+LEDUPDATEINTERVAL) {
        last_ledupdate=loopmillis;

        float vbat=min(escRear.getFeedback_batVoltage(),escFront.getFeedback_batVoltage());

        //led_dotcircle(loopmillis);
        led_voltage(loopmillis,vbat,3*12,4.2*12);
        strip.show();                          //  Update strip to match
    }
}

void led_voltage(unsigned long loopmillis,float vbat,float vbat_min,float vbat_max) {
    uint32_t colorBG=strip.Color(0,   255,   0, 0);
    uint32_t colorEmpty=strip.Color(255,  0,   0, 0);
    uint8_t position=map( max(min(vbat,vbat_max),vbat_min)  ,vbat_min,vbat_max, 0,strip.numPixels());
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
        uint8_t pp=strip.numPixels()- ((i+10)%strip.numPixels()) ; //Offset and invert
        if (i<=position) {
            strip.setPixelColor(pp, colorBG);         //  Set pixel's color (in RAM)
        }else{
            strip.setPixelColor(pp, colorEmpty);         //  Set pixel's color (in RAM)
        }
    }
}

void led_dotcircle(unsigned long loopmillis) {
    uint32_t color=strip.Color(0,   0,   0, 255);
    uint32_t colorOff=strip.Color(30,  0,   0, 0);
    uint8_t position=(loopmillis/100)%strip.numPixels();
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
        if (i==position) {
            strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
        }else{
            strip.setPixelColor(i, colorOff);         //  Set pixel's color (in RAM)
        }
    }
}

#endif