#pragma once
#include <ESPMegaDisplay.hpp>
#include <TimeStructure.hpp>
#include <DigitalInputCard.hpp>
#include <DigitalOutputCard.hpp>
#include <ClimateCard.hpp>

/*
Pin Mapping
0-3: Lights
4-6: Fans
7: Air Purifier
*/

// Touch Types
#define TOUCH_TYPE_PRESS 1
#define TOUCH_TYPE_RELEASE 0

// Page IDs
#define PAGE_BOOT 0
#define PAGE_DASHBOARD 1

// Dashboard Toggle Buttons
#define COMPONENT_LIGHT_TOGGLE_BUTTON 11
#define COMPONENT_LIGHT_TOGGLE_PIC_ON 4
#define COMPONENT_LIGHT_TOGGLE_PIC_OFF 3
#define COMPONENT_FAN_TOGGLE_BUTTON 12
#define COMPONENT_FAN_TOGGLE_PIC_ON 6
#define COMPONENT_FAN_TOGGLE_PIC_OFF 5
#define COMPONENT_AIR_PURIFIER_TOGGLE_BUTTON 13
#define COMPONENT_AIR_PURIFIER_TOGGLE_PIC_ON 8
#define COMPONENT_AIR_PURIFIER_TOGGLE_PIC_OFF 7

// Dashboard AC Controls
#define COMPONENT_AC_TEMP_UP_BUTTON 2
#define COMPONENT_AC_TEMP_DOWN_BUTTON 3
#define COMPONENT_AC_MODE_OFF_BUTTON 4
#define COMPONENT_AC_MODE_OFF_PIC_ACTIVE 14
#define COMPONENT_AC_MODE_OFF_PIC_INACTIVE 13
#define COMPONENT_AC_MODE_FAN_ONLY_BUTTON 5
#define COMPONENT_AC_MODE_FAN_ONLY_PIC_ACTIVE 16
#define COMPONENT_AC_MODE_FAN_ONLY_PIC_INACTIVE 15
#define COMPONENT_AC_MODE_COOL_BUTTON 6
#define COMPONENT_AC_MODE_COOL_PIC_ACTIVE 18
#define COMPONENT_AC_MODE_COOL_PIC_INACTIVE 17
#define COMPONENT_AC_FAN_MODE_AUTO_BUTTON 7
#define COMPONENT_AC_FAN_MODE_AUTO_PIC_ACTIVE 20
#define COMPONENT_AC_FAN_MODE_AUTO_PIC_INACTIVE 19
#define COMPONENT_AC_FAN_MODE_LOW_BUTTON 8
#define COMPONENT_AC_FAN_MODE_LOW_PIC_ACTIVE 26
#define COMPONENT_AC_FAN_MODE_LOW_PIC_INACTIVE 25
#define COMPONENT_AC_FAN_MODE_MEDIUM_BUTTON 9
#define COMPONENT_AC_FAN_MODE_MEDIUM_PIC_ACTIVE 24
#define COMPONENT_AC_FAN_MODE_MEDIUM_PIC_INACTIVE 23
#define COMPONENT_AC_FAN_MODE_HIGH_BUTTON 10
#define COMPONENT_AC_FAN_MODE_HIGH_PIC_ACTIVE 22
#define COMPONENT_AC_FAN_MODE_HIGH_PIC_INACTIVE 21

#define COMPONENT_BACKGROUND_AC_LOCK 2
#define COMPONENT_BACKGROUND_AC_UNLOCK 1

/**
 * @brief A class for controlling the ESPMegaDisplay.
 * 
 * Made for Chulalongkorn University Demonstration Seconary School.
 */
class CUDDisplay : public ESPMegaDisplay { 
    public:
        CUDDisplay(HardwareSerial* adapter);
        void begin(std::function<rtctime_t()> getTime, DigitalInputCard* inputCard, DigitalOutputCard* outputCard, ClimateCard* climateCard);
        void handleTouch(uint8_t page, uint8_t component, uint8_t event);
        void handlePWMChange(uint8_t pin, uint8_t value);
        void handleACChange(uint8_t mode, uint8_t fan_speed, uint8_t temperature);
        void handlePayload(uint8_t payload_type, uint8_t* payload, uint8_t length);
        void sendClock();
        void setACControlEnabled(bool enabled);
        bool getACControlEnabled();
    private:
        bool ac_control_enabled = true;
        std::function<rtctime_t()> getTime;
        DigitalInputCard* inputCard;
        DigitalOutputCard* outputCard;
        uint8_t outputCallbackHandle;
        ClimateCard* climateCard;
        uint8_t climateCallbackHandle;
        bool calculateLightGroupState();
        bool calculateFanGroupState();
        void setLightGrouptState(bool state);
        void setFanGroupState(bool state);
        void toggleLightGroupState();
        void toggleFanGroupState();
        void updateLightGroupState();
        void updateFanGroupState();
        void updateAirPurifierState();
        void updateACState();
};