#pragma once

#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <cstddef>
#include <SDL.h>
#ifdef __SWITCH__
#include <switch/types.h>
#else
#include <cmath>
#endif

/// \~chinese
/// @brief 不可拷贝对象
class Noncopyable
{
protected:
    Noncopyable() = default;

private:
    Noncopyable(const Noncopyable &) = delete;

    Noncopyable &operator=(const Noncopyable &) = delete;
};

// 整数坐标向量
typedef struct VecPos
{
    int x;
    int y;

    // 构造函数，方便初始化
    VecPos(int x_ = 0, int y_ = 0) : x(x_), y(y_) {}

    // 定义到 SDL_Point 的转换运算符
    operator SDL_Point() const
    {
        return {x, y}; // 直接返回包含 x、y 的 SDL_Point
    }
    // 转换为SDL_Point指针的运算符（用于指针场景）
    operator const SDL_Point *() const
    {
        // 注意：这里返回的是指向当前对象的指针，需确保对象生命周期有效
        return reinterpret_cast<const SDL_Point *>(this);
    }

    // 加法运算符重载：两个 VecPos 相加
    VecPos operator+(const VecPos &other) const
    {
        return VecPos(x + other.x, y + other.y);
    }

    // 减法运算符重载：两个 VecPos 相减
    VecPos operator-(const VecPos &other) const
    {
        return VecPos(x - other.x, y - other.y);
    }

    // 等于运算符重载：判断两个 VecPos 是否相等
    bool operator==(const VecPos &other) const
    {
        return x == other.x && y == other.y;
    }

    // 复合赋值加法：当前对象加上另一个 VecPos
    VecPos &operator+=(const VecPos &other)
    {
        x += other.x;
        y += other.y;
        return *this;
    }

    // 复合赋值减法：当前对象减去另一个 VecPos
    VecPos &operator-=(const VecPos &other)
    {
        x -= other.x;
        y -= other.y;
        return *this;
    }
} VecPos;

// 浮点数坐标向量
typedef struct VecFPos
{
    float x;
    float y;

    // 构造函数，方便初始化
    VecFPos(float x_ = 0.0f, float y_ = 0.0f) : x(x_), y(y_) {}
    VecFPos(int x_, int y_ = 0) : x(static_cast<float>(x_)), y(static_cast<float>(y_)) {}

    // 定义到 SDL_FPoint 的转换运算符
    operator SDL_FPoint() const
    {
        return {x, y}; // 直接返回包含 x、y 的 SDL_Point
    }

    // 加法运算符重载：两个 VecFPos 相加
    VecFPos operator+(const VecFPos &other) const
    {
        return VecFPos(x + other.x, y + other.y);
    }

    // 减法运算符重载：两个 VecFPos 相减
    VecFPos operator-(const VecFPos &other) const
    {
        return VecFPos(x - other.x, y - other.y);
    }

    // 乘法运算符重载：两个 VecFPos 相乘
    VecFPos operator*(const VecFPos &other) const
    {
        return VecFPos(x * other.x, y * other.y);
    }

    // 等于运算符重载：判断两个 VecFPos 是否相等
    // 注意：浮点数比较需要考虑精度问题
    bool operator==(const VecFPos &other) const
    {
        // 使用一个小的epsilon值来比较浮点数
        const float epsilon = 0.0001f;
        return (fabs(x - other.x) < epsilon) && (fabs(y - other.y) < epsilon);
    }

    // 复合赋值加法：当前对象加上另一个 VecFPos
    VecFPos &operator+=(const VecFPos &other)
    {
        x += other.x;
        y += other.y;
        return *this;
    }

    // 复合赋值减法：当前对象减去另一个 VecFPos
    VecFPos &operator-=(const VecFPos &other)
    {
        x -= other.x;
        y -= other.y;
        return *this;
    }
} VecFPos;

// 尺寸向量
typedef struct VecSize
{
    int width;
    int height;

    // 构造函数，方便初始化
    VecSize(int width_ = 0, int height_ = 0) : width(width_), height(height_) {}

    // 加法运算符重载：两个 VecSize 相加
    VecSize operator+(const VecSize &other) const
    {
        return VecSize(width + other.width, height + other.height);
    }

    // 减法运算符重载：两个 VecSize 相减
    VecSize operator-(const VecSize &other) const
    {
        return VecSize(width - other.width, height - other.height);
    }

    // 等于运算符重载：判断两个 VecSize 是否相等
    bool operator==(const VecSize &other) const
    {
        return width == other.width && height == other.height;
    }

    // 复合赋值加法：当前对象加上另一个 VecSize
    VecSize &operator+=(const VecSize &other)
    {
        width += other.width;
        height += other.height;
        return *this;
    }

    // 复合赋值减法：当前对象减去另一个 VecSize
    VecSize &operator-=(const VecSize &other)
    {
        width -= other.width;
        height -= other.height;
        return *this;
    }
} VecSize;

typedef struct VecPos3
{
    int x;
    int y;
    int z;
    VecPos3(int x_ = 0, int y_ = 0, int z_ = 0) : x(x_), y(y_), z(z_) {}

    VecPos3 operator+(const VecPos3 &other) const
    {
        return VecPos3(x + other.x, y + other.y, z + other.z);
    }

    VecPos3 operator-(const VecPos3 &other) const
    {
        return VecPos3(x - other.x, y - other.y, z - other.z);
    }

    bool operator==(const VecPos3 &other) const
    {
        return x == other.x && y == other.y && z == other.z;
    }

} VecPos3;

typedef struct VecFPos3
{
    float x;
    float y;
    float z;
    VecFPos3(float x_ = 0, float y_ = 0, float z_ = 0) : x(x_), y(y_), z(z_) {}

    VecFPos3 operator+(const VecFPos3 &other) const
    {
        return VecFPos3(x + other.x, y + other.y, z + other.z);
    }

    VecFPos3 operator-(const VecFPos3 &other) const
    {
        return VecFPos3(x - other.x, y - other.y, z - other.z);
    }

    bool operator==(const VecFPos3 &other) const
    {
        return x == other.x && y == other.y && z == other.z;
    }

} VecFPos3;

typedef struct VecSpeed3
{
    float x;
    float y;
    float z;
    VecSpeed3(float x_ = 0, float y_ = 0, float z_ = 0) : x(x_), y(y_), z(z_) {}

    VecSpeed3 operator+(const VecSpeed3 &other) const
    {
        return VecSpeed3(x + other.x, y + other.y, z + other.z);
    }

    VecSpeed3 operator-(const VecSpeed3 &other) const
    {
        return VecSpeed3(x - other.x, y - other.y, z - other.z);
    }

    bool operator==(const VecSpeed3 &other) const
    {
        return x == other.x && y == other.y && z == other.z;
    }
} VecSpeed3;