#ifndef __BASE_H__
#define __BASE_H__
#if defined(QT_VERSION)	// 如果是 QT 平台
//!!! use qt......
#include <cstdio>
#include <string>
#include <ctime>
#include <cmath>
#include <cstdint>

#include <atomic>

#else
#include <stdint.h>
#endif


/* 1. 根据编译器定义对齐宏 */
#if defined(_MSC_VER)
	/* MSVC 风格 */
#define PACKED_STRUCT_START __pragma(pack(push, 1))
#define PACKED_STRUCT_END   __pragma(pack(pop))
#define PACKED_ATTRIBUTE
#elif defined(__GNUC__) || defined(__clang__)
	/* GCC/Clang 风格 */
#define PACKED_STRUCT_START
#define PACKED_STRUCT_END
#define PACKED_ATTRIBUTE __attribute__((packed))
#else
	/* 其他编译器默认处理 */
#define PACKED_STRUCT_START
#define PACKED_STRUCT_END
#define PACKED_ATTRIBUTE
#endif


typedef uint64_t	EUI64;
typedef int64_t rtc_datetime;		// Custom time types, sometimes use uint32_t, int64, uint64_t. Define as a type for easy modification

// uint64 大小端转换
#define EndianSwap64(v)	\
						(((v & 0x00000000000000FF) << 56) |	/* 0xFF************FF */	\
						 ((v & 0x000000000000FF00) << 40) |	/* 0x00FF********FF00 */	\
						 ((v & 0x0000000000FF0000) << 24) |	/* 0x0000FF****FF0000 */	\
						 ((v & 0x00000000FF000000) <<  8) |	/* 0x000000FFFF000000 */	\
						 ((v & 0x000000FF00000000) >>  8) |	/* 0x000000FFFF000000 */	\
						 ((v & 0x0000FF0000000000) >> 24) |	/* 0x0000FF****FF0000 */	\
						 ((v & 0x00FF000000000000) >> 40) |	/* 0x00FF********FF00 */	\
						 ((v & 0xFF00000000000000) >> 56) )	/* 0xFF************FF */

#if defined(ESP_PLATFORM)						// ESP32 平台

#define WS2812_GPIO_NUM					(GPIO_NUM_48)		// CONFIG_EXAMPLE_WS2812_GPIO_NUM
#define WS2812_STRIPS_NUM				1 				// CONFIG_EXAMPLE_WS2812_STRIPS_NUM

#endif

#define ALIVE_LED_PIN					(GPIO_NUM_6)		// 心跳灯GPIO
// 定义系统工作状态, ALIVE LED 以不同的方式显示
#define SYSTEM_STATUS_INITIALIZING		(0)
#define SYSTEM_STATUS_WORKING			(1)
#define SYSTEM_STATUS_WIFI_CONNECTING	(2)

#define SYSTEM_STATUS_INITIALIZING_ALIVE_LED_ON_TIME		(1000*100)	// 初始化急速闪烁
#define SYSTEM_STATUS_INITIALIZING_ALIVE_LED_OFF_TIME		(1000*100)
#define SYSTEM_STATUS_WORKING_ALIVE_LED_ON_TIME				(1000*10)		// 工作正常闪烁, 亮 10ms, 灭 1500ms
#define SYSTEM_STATUS_WORKING_ALIVE_LED_OFF_TIME			(1000*1500)
#define SYSTEM_STATUS_WIFI_CONNECTING_ALIVE_LED_ON_TIME		(1000*1000)		// 连接 WiFi, 亮 500ms, 灭 100ms
#define SYSTEM_STATUS_WIFI_CONNECTING_ALIVE_LED_OFF_TIME	(1000*20)

#define CONFIG_BUTTON_GPIO				(GPIO_NUM_45)					// 配置按钮GPIO
#define BUTTON_LONG_PUSH_US   1000000  						// push for 1 seconds to reconfigure


void bsp_init(void);

static inline EUI64 arrayToEUI64(uint8_t* array)
{
	return ((uint64_t)array[7] << 0)
		+ ((uint64_t)array[6] << 8)
		+ ((uint64_t)array[5] << 16)
		+ ((uint64_t)array[4] << 24)
		+ ((uint64_t)array[3] << 32)
		+ ((uint64_t)array[2] << 40)
		+ ((uint64_t)array[1] << 48)
		+ ((uint64_t)array[0] << 56);
}
static inline void EUI64ToArray(EUI64 eui64, uint8_t* array)
{
	array[7] = (uint8_t)(eui64 & 0xFF);
	array[6] = (uint8_t)((eui64 >> 8) & 0xFF);
	array[5] = (uint8_t)((eui64 >> 16) & 0xFF);
	array[4] = (uint8_t)((eui64 >> 24) & 0xFF);
	array[3] = (uint8_t)((eui64 >> 32) & 0xFF);
	array[2] = (uint8_t)((eui64 >> 40) & 0xFF);
	array[1] = (uint8_t)((eui64 >> 48) & 0xFF);
	array[0] = (uint8_t)((eui64 >> 56) & 0xFF);
}

static inline uint16_t arrayToUint16(uint8_t* array)
{
	return ((uint16_t)array[0] << 0)
		+ ((uint16_t)array[1] << 8);
}
static inline void Uint16ToArray(uint16_t n, uint8_t* array)
{
	array[0] = (uint8_t)(n & 0xFF);
	array[1] = (uint8_t)((n >> 8) & 0xFF);
}


#endif // __BASE_H__
