#pragma once
#include <ESPMegaPRO.h>
#include <Nextion.h>
#include <PubSubClient.h>
#include <PubSubClientTools.h>
#include "espmega_iot_timer.hpp"
#include "espmega_iot_external_lcd.hpp"

// Bus Overclocking Configuration
// Do not enable if you are using external I/O cards as it will cause signal integrity issues.
// Choose only one mode
//#define OVERCLOCK_FM
//#define OVERCLOCK_FM2

// I/O Configuration
#define VIRTUAL_INTERRUPT_PRELOAD // Preload Virtual Interrupts buffer

// Enable Software Module(s)
// Deprecated. Use Build Flags instead.
// #define ENABLE_INTERNAL_LCD
// #define ENABLE_IR_MODULE
// #define ENABLE_CLIMATE_MODULE // Require IR Module
// #define ENABLE_ANALOG_MODULE
// #define ENABLE_WEBUI

// IR Kit Configuration
#define IR_RECIEVE_PIN 35
#define IR_SEND_PIN 17
#define MARK_EXCESS_MICROS 20
#define IR_RAW_BUFFER_LENGTH 750
#define AC_MAX_TEMPERATURE 30
#define AC_MIN_TEMPERATURE 15
#define DHT22_PIN 32

// External LCD Configuration
#define ENABLE_EXTERNAL_LCD
#define TXD2 4
#define RXD2 17

#ifdef ENABLE_EXTERNAL_LCD
#define ESPMega_EXTLCD Serial2
#endif

// Analog Module Configuration
#define ANALOG_REPORTING_INTERVAL 500

// User Defined Functions
void timer1_callback();
void bt0PopCallback(void *ptr);

// User Defined IoT Core Callback Functions (Required)
void user_mqtt_callback(char* topic, uint8_t topic_length, char* payload, unsigned int payload_length);
void user_state_request_callback();
void mqtt_connected_user_callback();
void user_pre_init();
void user_init();
void user_loop();
void pwm_changed_user_callback(int pin);
void ac_changed_user_callback(int mode, int temperature, int fan_speed);
void timer_tick_callback();
void virtual_interrupt_user_callback(int pin, int state);

// ESPMega IoT Core Build-in Functions
extern void pwm_set_state(int id, int state);
extern void pwm_set_value(int id, int value);
extern void pwm_toggle(int id);
extern void pwm_toggle(int id1, int id2);
extern void pwm_cycle_value(int id);
extern bool pwm_get_state(int id);
extern uint16_t pwm_get_value(int id);
extern boolean pwm_group_state(int id1, int id2);
extern bool input_get_state(int id);
extern bool standalone;
extern PubSubClient mqtt;

// IR Kit Build-in Functions
#ifdef ENABLE_IR_MODULE
extern void ac_set_state(int mode, int temperature, int fan_speed);
extern uint8_t ac_get_temperature();
extern uint8_t ac_get_mode();
extern uint8_t ac_get_fan_speed();
#endif

//Analog Expansion Card Build-in Functions
#ifdef ENABLE_ANALOG_MODULE
extern void dac_set_value(int id, int value);
extern void dac_set_state(int id, bool state);
extern void enable_adc(int id);
extern void disable_adc(int id);
extern void enable_dac(int id);
extern uint16_t adc_get_value(int id);
extern bool adc_get_state(int id);
extern uint16_t dac_get_value(int id);
extern bool dac_get_state(int id);
#endif