/*
 * 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_2D_SHORTCUT_H
#define ECXX_ECXX_SPI_LED_DRIVER_2D_SHORTCUT_H


//
// Include the needed header files
//
#include "eCxx_ColorAnimator2D.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,
    CBP::SUInt                XSizeN,
    CBP::SUInt                YSizeN,
    typename                  LayoutPolicyT       = CBP::DefaultLayout,
    CBP::SUInt                BlockXSizeN         = 0,
    CBP::SUInt                BlockYSizeN         = 0,
    CBP::SUInt                InterYSizeN         = 0,
    uint8_t                   AnimatorCountN      = 1,
    bool                      UseDoubleBufferring = false,
    typename                  ColorPGMPtrT        = PGMCharPointer
>
class ColorAnimator2D_Shortcut {
    static_assert(
        AnimatorCountN >= 1 && AnimatorCountN <= 9,
        "template argument substituting AnimatorCountN is not between 1 and 9"
    );

    public:
        using BufferSizeType           = CBP::DUInt;
        using ColorType                = ColorT;
        using ColorFX2DType            = ColorFX2D<ColorType, XSizeN, YSizeN, LayoutPolicyT, CBP::RawBuffer, BlockXSizeN, BlockYSizeN, InterYSizeN, UseDoubleBufferring, ColorPGMPtrT>;
        using ColorAnimator2DType      = ColorAnimator2D<SegmentCountN, ColorFX2DType>;
        using ColorAnimator2DArrayType = ColorAnimatorArray<AnimatorCountN, ColorAnimator2DType, ColorFX2DType>;
        using GenericSPILEDDriverType  = GenericSPILEDDriver<ColorFX2DType::BufferElementCount, PinDataN, PinClockN, ClockFrequencyN, ColorFX2DType, DisplayFrameFormatT>;

        static constexpr uint8_t ColorAnimator2DCount = AnimatorCountN;

    public:
        GenericSPILEDDriverType  genericSPILEDDriver;

        ColorFX2DType            colorFX2D;
        ColorAnimator2DArrayType colorAnim2D;

    public:
        inline ColorAnimator2D_Shortcut() __ECXX_ATTR_ALWAYS_INLINE
        : colorAnim2D{ colorFX2D }
        {}

        inline void begin() __ECXX_ATTR_ALWAYS_INLINE
        {
            genericSPILEDDriver.begin(colorFX2D);
            genericSPILEDDriver.update();
        }

        inline void update() __ECXX_ATTR_ALWAYS_INLINE
        {
            for(uint8_t i = 0; i < ColorAnimator2DCount; ++i) colorAnim2D[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,
    CBP::SUInt               XSizeN,
    CBP::SUInt               YSizeN,
    typename                 LayoutPolicyT       = CBP::DefaultLayout,
    CBP::SUInt               BlockXSizeN         = 0,
    CBP::SUInt               BlockYSizeN         = 0,
    CBP::SUInt               InterYSizeN         = 0,
    uint8_t                  AnimatorCountN      = 1,
    bool                     UseDoubleBufferring = false,
    typename                 ColorPGMPtrT        = PGMCharPointer
>
using ColorAnimator2D_APA102C = ColorAnimator2D_Shortcut< XRGBColorT<APA102XPolicy>,
                                                          DisplayFrameFormatAPA102X,
                                                          PinDataN,
                                                          PinClockN,
                                                          ClockFrequencyN,
                                                          SegmentCountN,
                                                          XSizeN,
                                                          YSizeN,
                                                          LayoutPolicyT,
                                                          BlockXSizeN,
                                                          BlockYSizeN,
                                                          InterYSizeN,
                                                          AnimatorCountN,
                                                          UseDoubleBufferring,
                                                          ColorPGMPtrT
                                                        >;

template <
    template<typename> class XRGBColorT,
    uint8_t                  PinDataN,
    uint8_t                  PinClockN,
    uint32_t                 ClockFrequencyN,
    uint8_t                  SegmentCountN,
    CBP::SUInt               XSizeN,
    CBP::SUInt               YSizeN,
    typename                 LayoutPolicyT       = CBP::DefaultLayout,
    CBP::SUInt               BlockXSizeN         = 0,
    CBP::SUInt               BlockYSizeN         = 0,
    CBP::SUInt               InterYSizeN         = 0,
    uint8_t                  AnimatorCountN      = 1,
    bool                     UseDoubleBufferring = false,
    typename                 ColorPGMPtrT        = PGMCharPointer
>
using ColorAnimator2D_SK9822 = ColorAnimator2D_APA102C< XRGBColorT,
                                                        PinDataN,
                                                        PinClockN,
                                                        ClockFrequencyN,
                                                        SegmentCountN,
                                                        XSizeN,
                                                        YSizeN,
                                                        LayoutPolicyT,
                                                        BlockXSizeN,
                                                        BlockYSizeN,
                                                        InterYSizeN,
                                                        AnimatorCountN,
                                                        UseDoubleBufferring,
                                                        ColorPGMPtrT
                                                      >;


//
// Convenience shortcut for P9813BGR
//
template <
    template<typename> class XRGBColorT,
    uint8_t                  PinDataN,
    uint8_t                  PinClockN,
    uint32_t                 ClockFrequencyN,
    uint8_t                  SegmentCountN,
    CBP::SUInt               XSizeN,
    CBP::SUInt               YSizeN,
    typename                 LayoutPolicyT       = CBP::DefaultLayout,
    CBP::SUInt               BlockXSizeN         = 0,
    CBP::SUInt               BlockYSizeN         = 0,
    CBP::SUInt               InterYSizeN         = 0,
    uint8_t                  AnimatorCountN      = 1,
    bool                     UseDoubleBufferring = false,
    typename                 ColorPGMPtrT        = PGMCharPointer
>
using ColorAnimator2D_P9813BGR = ColorAnimator2D_Shortcut< typename MatchP9813BGRColorType<XRGBColorT>::ColorType,
                                                           DisplayFrameFormatP9813BGR,
                                                           PinDataN,
                                                           PinClockN,
                                                           ClockFrequencyN,
                                                           SegmentCountN,
                                                           XSizeN,
                                                           YSizeN,
                                                           LayoutPolicyT,
                                                           BlockXSizeN,
                                                           BlockYSizeN,
                                                           InterYSizeN,
                                                           AnimatorCountN,
                                                           UseDoubleBufferring,
                                                           ColorPGMPtrT
                                                         >;


//
// Convenience shortcut for LPD8806
//
template <
    typename   RGBColorT,
    uint8_t    PinDataN,
    uint8_t    PinClockN,
    uint32_t   ClockFrequencyN,
    uint8_t    SegmentCountN,
    CBP::SUInt XSizeN,
    CBP::SUInt YSizeN,
    typename   LayoutPolicyT       = CBP::DefaultLayout,
    CBP::SUInt BlockXSizeN         = 0,
    CBP::SUInt BlockYSizeN         = 0,
    CBP::SUInt InterYSizeN         = 0,
    uint8_t    AnimatorCountN      = 1,
    bool       UseDoubleBufferring = false,
    typename   ColorPGMPtrT        = PGMCharPointer
>
using ColorAnimator2D_LPD8806 = ColorAnimator2D_Shortcut< RGBColorT,
                                                          DisplayFrameFormatLPD8806,
                                                          PinDataN,
                                                          PinClockN,
                                                          ClockFrequencyN,
                                                          SegmentCountN,
                                                          XSizeN,
                                                          YSizeN,
                                                          LayoutPolicyT,
                                                          BlockXSizeN,
                                                          BlockYSizeN,
                                                          InterYSizeN,
                                                          AnimatorCountN,
                                                          UseDoubleBufferring,
                                                          ColorPGMPtrT
                                                        >;


//
// Convenience shortcut for LPD6803
//
template <
    typename   RGBColorT,
    uint8_t    PinDataN,
    uint8_t    PinClockN,
    uint32_t   ClockFrequencyN,
    uint8_t    SegmentCountN,
    CBP::SUInt XSizeN,
    CBP::SUInt YSizeN,
    typename   LayoutPolicyT       = CBP::DefaultLayout,
    CBP::SUInt BlockXSizeN         = 0,
    CBP::SUInt BlockYSizeN         = 0,
    CBP::SUInt InterYSizeN         = 0,
    uint8_t    AnimatorCountN      = 1,
    bool       UseDoubleBufferring = false,
    typename   ColorPGMPtrT        = PGMCharPointer
>
using ColorAnimator2D_LPD6803 = ColorAnimator2D_Shortcut< RGBColorT,
                                                          DisplayFrameFormatLPD6803,
                                                          PinDataN,
                                                          PinClockN,
                                                          ClockFrequencyN,
                                                          SegmentCountN,
                                                          XSizeN,
                                                          YSizeN,
                                                          LayoutPolicyT,
                                                          BlockXSizeN,
                                                          BlockYSizeN,
                                                          InterYSizeN,
                                                          AnimatorCountN,
                                                          UseDoubleBufferring,
                                                          ColorPGMPtrT
                                                        >;


//
// Convenience shortcut for WS2801
//
template <
    typename   RGBColorT,
    uint8_t    PinDataN,
    uint8_t    PinClockN,
    uint32_t   ClockFrequencyN,
    uint8_t    SegmentCountN,
    CBP::SUInt XSizeN,
    CBP::SUInt YSizeN,
    typename   LayoutPolicyT       = CBP::DefaultLayout,
    CBP::SUInt BlockXSizeN         = 0,
    CBP::SUInt BlockYSizeN         = 0,
    CBP::SUInt InterYSizeN         = 0,
    uint8_t    AnimatorCountN      = 1,
    bool       UseDoubleBufferring = false,
    typename   ColorPGMPtrT        = PGMCharPointer
>
using ColorAnimator2D_WS2801 = ColorAnimator2D_Shortcut< RGBColorT,
                                                         DisplayFrameFormatWS2801,
                                                         PinDataN,
                                                         PinClockN,
                                                         ClockFrequencyN,
                                                         SegmentCountN,
                                                         XSizeN,
                                                         YSizeN,
                                                         LayoutPolicyT,
                                                         BlockXSizeN,
                                                         BlockYSizeN,
                                                         InterYSizeN,
                                                         AnimatorCountN,
                                                         UseDoubleBufferring,
                                                         ColorPGMPtrT
                                                       >;


//
// Convenience shortcut for SM16716
//
template <
    typename   RGBColorT,
    uint8_t    PinDataN,
    uint8_t    PinClockN,
    uint32_t   ClockFrequencyN,
    uint8_t    SegmentCountN,
    CBP::SUInt XSizeN,
    CBP::SUInt YSizeN,
    typename   LayoutPolicyT       = CBP::DefaultLayout,
    CBP::SUInt BlockXSizeN         = 0,
    CBP::SUInt BlockYSizeN         = 0,
    CBP::SUInt InterYSizeN         = 0,
    uint8_t    AnimatorCountN      = 1,
    bool       UseDoubleBufferring = false,
    typename   ColorPGMPtrT        = PGMCharPointer
>
using ColorAnimator2D_SM16716 = ColorAnimator2D_Shortcut< RGBColorT,
                                                          DisplayFrameFormatSM16716,
                                                          PinDataN,
                                                          PinClockN,
                                                          ClockFrequencyN,
                                                          SegmentCountN,
                                                          XSizeN,
                                                          YSizeN,
                                                          LayoutPolicyT,
                                                          BlockXSizeN,
                                                          BlockYSizeN,
                                                          InterYSizeN,
                                                          AnimatorCountN,
                                                          UseDoubleBufferring,
                                                          ColorPGMPtrT
                                                        >;


} // namespace eCxx


#endif
