/*
 * Copyright (C) 2020-2021 Aloysius Indrayanto
 *
 * This file is part of the eCxx library, see LICENSE file for the license details.
 */


//
// Instantiate the WS2812B driver
//
static eCxx::WS2812BDriver ws2812b;


//
// Animation-related variables
//
typedef eCxx::ColorFX1D<eCxx::HSVColor, 4, eCxx::CBP::EncapsulatedBuffer> CFXEncHSV;
typedef eCxx::ColorFX1D<eCxx::GRBColor, 4, eCxx::CBP::RawBuffer         > CFXRawRGB;

static constexpr eCxx::uint8_t NumLEDs = CFXRawRGB::BufferElementCount;

static const eCxx::uint8_t PROGMEM hsvColor[ (2 + 1 + 1) * 4 ] {
  //  H         S    V
      0,   0, 200,   0, // Red
    120,   0, 200,   0, // Green
    240,   0, 200,   0, // Blue
      0,   0,   0,   0  // White
};
static const eCxx::HSVColor hsvMaxV(0, 0, 200);

static       CFXEncHSV      cfxSrc;
static       CFXRawRGB      cfxDst;


//
// Helper functions
//
static void eCxx_user_task_updateWS2812BLEDStripAnimation()
{
    // Process event and delay
    static eCxx::uint32_t prvMillis = 0;
           eCxx::uint32_t curMillis = App::processEvent();
    if(curMillis - prvMillis < 10) return;
    else                           prvMillis = curMillis;

    // Initialize LED animation as needed
    static bool laInit = false;
    if(!laInit) {
        laInit = true;
        cfxSrc.set<eCxx::HSVColor>( eCxx::PGM_PTR(hsvColor) );
    }

    // Update the LED animation
    static bool          dir = true;
    static eCxx::uint8_t val = 0;

    if(dir) {
        if(val < 60) {
            ++val;
        }
        else {
            val = 60;
            dir = false;
        }
    }
    else {
        if(val > 0) {
            --val;
        }
        else {
            val = 0;
            dir = true;
            cfxSrc.rotateRight();
        }
    }

    cfxDst.lerp<eCxx::HSVColor::V>( cfxSrc.colorBufferData(), hsvMaxV, val);

    // Update the WS2812B
    ws2812b.update();
}
