#pragma once
#include "ise_display_definitions.hpp"

#include <ESPMegaDisplay.hpp>
#include <ESPMegaIoT.hpp>
#include <TimeStructure.hpp>
#include <DigitalInputCard.hpp>
#include <DigitalOutputCard.hpp>
#include <ClimateCard.hpp>
#include <RemoteVariable.hpp>

/**
 * @brief A class for controlling the ESPMegaDisplay.
 * 
 * Made for ISE building 2 room 303/2.
 */



struct lightPosition {
    uint8_t row;
    uint8_t column;
};

class ISEDisplay : public ESPMegaDisplay { 
    public:
        ISEDisplay(HardwareSerial* adapter, const uint8_t *light_array, uint8_t row, uint8_t column);
        void begin(DigitalInputCard* inputCard, DigitalOutputCard* outputCard, ClimateCard* climateCard_daikin, ClimateCard* climateCard_york, RemoteVariable* pm_switch, RemoteVariable* pm_fan_speed, RemoteVariable* ac_lock, RemoteVariable* pm_lock, ESPMegaIoT *iot);
        void updateLightGroupStatePageDashboard();
        void updateLightGroupStatePageStandby();
        void updateAirPurifierState();
        void updateAirPurifierStateStandby();
        void updateSystemtoggle();
        void updateAllStandbyToggle();
        void updateDateTimeText(rtctime_t time);
        void updateWeather(char *weather_string);
        void updateTempOutside(float temp_outside);
        void updatePMoutside(u_int16_t pm25_outside);
        void updatePMinside(u_int16_t pm25_inside);
        void updateACState();
        void loop();

        

    private:
        
        void handleTouch(uint8_t page, uint8_t component, uint8_t touch_type);
        void handlePWMChange(uint8_t pin, bool state, uint16_t value);
        void handleACChange(uint8_t mode, uint8_t fan_speed, uint8_t temperature);
        void setPMstate(bool is_pm_on, uint8_t pm_fan_speed);
        void setACstate(uint8_t ac_fan_speed, uint8_t ac_mode, uint8_t ac_temperature);
        void setLightLevel(uint8_t row, uint8_t level);
        u_int8_t getLightLevel(uint8_t row);
        lightPosition getRowCol(uint8_t pin);
        
        DigitalInputCard* inputCard;
        DigitalOutputCard *outputCard;
        ClimateCard *climateCard_daikin;
        ClimateCard *climateCard_york;
        ESPMegaIoT *iot;

        const uint8_t *light_array;
        uint8_t row;
        uint8_t column;

        RemoteVariable *pm_switch;
        RemoteVariable *remote_pm_fan_speed;
        RemoteVariable *ac_lock;
        RemoteVariable *pm_lock;
        uint8_t outputCallbackHandle;
        uint8_t climateCallbackHandle;
        uint32_t time_since_last_ac_change;
        uint32_t time_since_ac_staggered_start_call;
        bool ac_staggered_start_call_pending;
        uint8_t user_mode;
        uint8_t ac_lock_state;
        uint8_t pm_lock_state;
        uint8_t ac_mode;
        uint8_t ac_fan_speed;
        uint8_t ac_temperature;
        bool ac_press_pending;
        uint8_t pm_fan_speed;
        uint8_t time_since_last_screen_update;
        u_int8_t lightLevelRow1;
        u_int8_t lightLevelRow2;
        u_int8_t lightLevelRow3;
        u_int8_t lightLevelRow4;
        

        void updateuserACmode();
        void updateACfanSpeed();
        void updateLightSwitch();
        bool calculateLightGroupState();
        bool calculateAllState();
        void toggleSystem();
        void sendACIRcode();
        void setPMlockstate(bool is_pm_lock_on);
        void setAClockstate(bool is_ac_lock_on);
        void toggleACLock();
        void togglePMLock();
        void allToggleStandby();
        void toggleLightGroupState();
        void toggleLightGroupStateStandby();
        void toggleLightIndividual(uint8_t row);
        void togglePM();
        void togglePMStandby();
        void toggleAC();
        void setLightGroupState(uint8_t level);
        void toggleACStandby();
        void changeUserACmode();
        void changePMfanspeed();
        
};
