//
// Created by robtor on 09.12.22.
//

#ifndef FLOATPUMP_LCD_I2C_DRIVER_H
#define FLOATPUMP_LCD_I2C_DRIVER_H

#include "stm32f4xx_hal.h"

namespace floatpump {

    class LCD_I2C_Driver {

    private:
        LCD_I2C_Driver(I2C_HandleTypeDef &handle, uint16_t displayAddr);

    public:
        static LCD_I2C_Driver &getInstance(I2C_HandleTypeDef &handle, uint16_t displayAddr);

        enum SpecialChars {
            RightArrow = 0x7e
        };

    public:
        // Explicitly delete these constructors
        LCD_I2C_Driver(LCD_I2C_Driver const &) = delete;

        void operator=(LCD_I2C_Driver const &) = delete;

        // Functions sending text
        void LCDSendCString(char *str);

        void LCDSendChar(char chr);

        // Functions for configuration
        void LCDClearDisplay();

        void LCDSetBacklight(bool enabled);

        void LCDPower(bool enabled);

        void LCDCursor(bool enabled);

        void LCDCursorBlink(bool enabled);

        // These configurations are normally not necessary to change
        void LCDCursorIncDec(bool enabled);

        void LCDDisplayShift(bool enabled);

        // Move Cursor
        void LCDSetCursor(uint8_t x, uint8_t y);

        // Position
        typedef struct {
            uint8_t x;
            uint8_t y;
        } pos_t;

    private:
        I2C_HandleTypeDef m_handle;
        uint16_t m_displayAddr;

        bool m_backlight{};
        bool m_cursor{};
        bool m_cursorBlink{};
        bool m_incrementDecrement{};
        bool m_autoShift{};
        bool m_powered;

        pos_t m_curPos;

        void m_lcdSendData(char data);

        void m_lcdSendCmnd(char cmnd);
    };

} // floatpump

#endif //FLOATPUMP_LCD_I2C_DRIVER_H
