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


#ifndef ECXX_ECXX_SPI_LED_DRIVER_1D_SHORTCUT_H
#define ECXX_ECXX_SPI_LED_DRIVER_1D_SHORTCUT_H


//
// Include the needed header files
//
#include "eCxx_ColorAnimator1D.h"
#include "eCxx_LEDDriver.h"

#include "CTL/GFX/ColorAnimatorArray.h"


namespace eCxx {


//
// A wrapper class for convenience shortcuts
//
template <
    typename                 ColorT,
    template<uint16_t> class DisplayFrameFormatT,
    uint8_t                  PinDataN,
    uint8_t                  PinClockN,
    uint32_t                 ClockFrequencyN,
    uint8_t                  SegmentCountN,
    uint16_t                 LEDCountN,
    uint8_t                  AnimatorCountN      = 1,
    bool                     UseDoubleBufferring = false,
    typename                 ColorPGMPtrT        = PGMCharPointer
>
class ColorAnimator1D_Shortcut {
    static_assert(
        AnimatorCountN >= 1 && AnimatorCountN <= 9,
        "template argument substituting AnimatorCountN is not between 1 and 9"
    );

    public:
        using BufferSizeType           = typename eCxx::conditional< (LEDCountN < 255), CBP::SUInt, CBP::DUInt >::Type;
        using ColorType                = ColorT;
        using ColorFX1DType            = ColorFX1D<ColorType, LEDCountN, CBP::RawBuffer, BufferSizeType, UseDoubleBufferring, ColorPGMPtrT>;
        using ColorAnimator1DType      = ColorAnimator1D<SegmentCountN, ColorFX1DType>;
        using ColorAnimator1DArrayType = ColorAnimatorArray<AnimatorCountN, ColorAnimator1DType, ColorFX1DType>;
        using GenericSPILEDDriverType  = GenericSPILEDDriver<ColorFX1DType::BufferElementCount, PinDataN, PinClockN, ClockFrequencyN, ColorFX1DType, DisplayFrameFormatT>;

        static constexpr uint8_t ColorAnimator1DCount = AnimatorCountN;

    public:
        GenericSPILEDDriverType  genericSPILEDDriver;

        ColorFX1DType            colorFX1D;
        ColorAnimator1DArrayType colorAnim1D;

    public:
        inline ColorAnimator1D_Shortcut() __ECXX_ATTR_ALWAYS_INLINE
        : colorAnim1D{ colorFX1D }
        {}

        inline void begin() __ECXX_ATTR_ALWAYS_INLINE
        {
            for(uint8_t i = 0; i < ColorAnimator1DCount; ++i) colorAnim1D[i].reset();
            genericSPILEDDriver.begin(colorFX1D);
            genericSPILEDDriver.update();
        }

        inline void update() __ECXX_ATTR_ALWAYS_INLINE
        {
            for(uint8_t i = 0; i < ColorAnimator1DCount; ++i) colorAnim1D[i].update();
            genericSPILEDDriver.update();
        }
};


//
// Convenience shortcuts for APA102C and SK9822
//
template <
    template<typename> class XRGBColorT,
    uint8_t                  PinDataN,
    uint8_t                  PinClockN,
    uint32_t                 ClockFrequencyN,
    uint8_t                  SegmentCountN,
    uint16_t                 LEDCountN,
    uint8_t                  AnimatorCountN      = 1,
    bool                     UseDoubleBufferring = false,
    typename                 ColorPGMPtrT        = PGMCharPointer
>
using ColorAnimator1D_APA102C = ColorAnimator1D_Shortcut< XRGBColorT<APA102XPolicy>,
                                                          DisplayFrameFormatAPA102X,
                                                          PinDataN,
                                                          PinClockN,
                                                          ClockFrequencyN,
                                                          SegmentCountN,
                                                          LEDCountN,
                                                          AnimatorCountN,
                                                          UseDoubleBufferring,
                                                          ColorPGMPtrT
                                                        >;

template <
    template<typename> class XRGBColorT,
    uint8_t                  PinDataN,
    uint8_t                  PinClockN,
    uint32_t                 ClockFrequencyN,
    uint8_t                  SegmentCountN,
    uint16_t                 LEDCountN,
    uint8_t                  AnimatorCountN      = 1,
    bool                     UseDoubleBufferring = false,
    typename                 ColorPGMPtrT        = PGMCharPointer
>
using ColorAnimator1D_SK9822 = ColorAnimator1D_APA102C< XRGBColorT,
                                                        PinDataN,
                                                        PinClockN,
                                                        ClockFrequencyN,
                                                        SegmentCountN,
                                                        LEDCountN,
                                                        AnimatorCountN,
                                                        UseDoubleBufferring,
                                                        ColorPGMPtrT
                                                      >;


//
// Convenience shortcut for P9813BGR
//
template <
    template <typename> class XRGBColorT,
    uint8_t                   PinDataN,
    uint8_t                   PinClockN,
    uint32_t                  ClockFrequencyN,
    uint8_t                   SegmentCountN,
    uint16_t                  LEDCountN,
    uint8_t                   AnimatorCountN      = 1,
    bool                      UseDoubleBufferring = false,
    typename                  ColorPGMPtrT        = PGMCharPointer
>

using ColorAnimator1D_P9813BGR = ColorAnimator1D_Shortcut< typename MatchP9813BGRColorType<XRGBColorT>::ColorType,
                                                           DisplayFrameFormatP9813BGR,
                                                           PinDataN,
                                                           PinClockN,
                                                           ClockFrequencyN,
                                                           SegmentCountN,
                                                           LEDCountN,
                                                           AnimatorCountN,
                                                           UseDoubleBufferring,
                                                           ColorPGMPtrT
                                                         >;


//
// Convenience shortcut for LPD8806
//
template <
    typename RGBColorT,
    uint8_t  PinDataN,
    uint8_t  PinClockN,
    uint32_t ClockFrequencyN,
    uint8_t  SegmentCountN,
    uint16_t LEDCountN,
    uint8_t  AnimatorCountN      = 1,
    bool     UseDoubleBufferring = false,
    typename ColorPGMPtrT        = PGMCharPointer
>
using ColorAnimator1D_LPD8806 = ColorAnimator1D_Shortcut< RGBColorT,
                                                          DisplayFrameFormatLPD8806,
                                                          PinDataN,
                                                          PinClockN,
                                                          ClockFrequencyN,
                                                          SegmentCountN,
                                                          LEDCountN,
                                                          AnimatorCountN,
                                                          UseDoubleBufferring,
                                                          ColorPGMPtrT
                                                        >;


//
// Convenience shortcut for LPD6803
//
template <
    typename RGBColorT,
    uint8_t  PinDataN,
    uint8_t  PinClockN,
    uint32_t ClockFrequencyN,
    uint8_t  SegmentCountN,
    uint16_t LEDCountN,
    uint8_t  AnimatorCountN      = 1,
    bool     UseDoubleBufferring = false,
    typename ColorPGMPtrT        = PGMCharPointer
>
using ColorAnimator1D_LPD6803 = ColorAnimator1D_Shortcut< RGBColorT,
                                                          DisplayFrameFormatLPD6803,
                                                          PinDataN,
                                                          PinClockN,
                                                          ClockFrequencyN,
                                                          SegmentCountN,
                                                          LEDCountN,
                                                          AnimatorCountN,
                                                          UseDoubleBufferring,
                                                          ColorPGMPtrT
                                                        >;


//
// Convenience shortcut for WS2801
//
template <
    typename RGBColorT,
    uint8_t  PinDataN,
    uint8_t  PinClockN,
    uint32_t ClockFrequencyN,
    uint8_t  SegmentCountN,
    uint16_t LEDCountN,
    uint8_t  AnimatorCountN      = 1,
    bool     UseDoubleBufferring = false,
    typename ColorPGMPtrT        = PGMCharPointer
>
using ColorAnimator1D_WS2801 = ColorAnimator1D_Shortcut< RGBColorT,
                                                         DisplayFrameFormatWS2801,
                                                         PinDataN,
                                                         PinClockN,
                                                         ClockFrequencyN,
                                                         SegmentCountN,
                                                         LEDCountN,
                                                         AnimatorCountN,
                                                         UseDoubleBufferring,
                                                         ColorPGMPtrT
                                                       >;


//
// Convenience shortcut for SM16716
//
template <
    typename RGBColorT,
    uint8_t  PinDataN,
    uint8_t  PinClockN,
    uint32_t ClockFrequencyN,
    uint8_t  SegmentCountN,
    uint16_t LEDCountN,
    uint8_t  AnimatorCountN      = 1,
    bool     UseDoubleBufferring = false,
    typename ColorPGMPtrT        = PGMCharPointer
>
using ColorAnimator1D_SM16716 = ColorAnimator1D_Shortcut< RGBColorT,
                                                          DisplayFrameFormatSM16716,
                                                          PinDataN,
                                                          PinClockN,
                                                          ClockFrequencyN,
                                                          SegmentCountN,
                                                          LEDCountN,
                                                          AnimatorCountN,
                                                          UseDoubleBufferring,
                                                          ColorPGMPtrT
                                                        >;


} // namespace eCxx


#endif
