#pragma once

#ifndef MODELPOSE_H
#define MODELPOSE_H

#include <glm/glm.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <map>
#include <string>
#include <memory>

namespace Vivid2D::util {

    // ================== 内部类：部件姿态 PartPose ==================

    /**
     * 单个部件的姿态数据
     */
    class VIVID_2D_MYDLL_API PartPose {
    public:
        // 默认构造函数
        PartPose();

        // 完整构造函数
        PartPose(const glm::vec2& position, float rotation, const glm::vec2& scale,
            float opacity, bool visible, const glm::vec3& color);

        // 拷贝构造函数
        PartPose(const PartPose& other);

        // ================== 线性插值方法 ==================

        /**
         * 在两个部件姿态间进行线性插值（不处理旋转环绕）
         */
        static PartPose lerp(const PartPose& a, const PartPose& b, float alpha);

        /**
         * 带旋转正确插值的线性插值（处理360°边界）
         */
        static PartPose lerpWithRotation(const PartPose& a, const PartPose& b, float alpha);

        // ================== Getter和Setter ==================

        glm::vec2 getPosition() const { return m_position; }
        void setPosition(const glm::vec2& position) { m_position = position; }

        float getRotation() const { return m_rotation; }
        void setRotation(float rotation) { m_rotation = rotation; }

        glm::vec2 getScale() const { return m_scale; }
        void setScale(const glm::vec2& scale) { m_scale = scale; }

        float getOpacity() const { return m_opacity; }
        void setOpacity(float opacity) { m_opacity = opacity; }

        bool isVisible() const { return m_visible; }
        void setVisible(bool visible) { m_visible = visible; }

        glm::vec3 getColor() const { return m_color; }
        void setColor(const glm::vec3& color) { m_color = color; }

        // ================== 运算符重载和工具方法 ==================

        bool operator==(const PartPose& other) const;
        bool operator!=(const PartPose& other) const { return !(*this == other); }
        std::string toString() const;

    private:
        glm::vec2 m_position;
        float m_rotation;
        glm::vec2 m_scale;
        float m_opacity;
        bool m_visible;
        glm::vec3 m_color; // RGB颜色乘数
    };

    // ================== ModelPose 主体 ==================

    /**
     * 模型姿态类 - 用于存储和管理2D模型的部件变换状态
     */
    class VIVID_2D_MYDLL_API ModelPose {
    public:
        // C++ 11/14/17 风格的别名，更清晰地表示存储的 Map 类型
        using PoseMap = std::map<std::string, PartPose>;

        // ================== 构造函数 ==================

        ModelPose();
        explicit ModelPose(const std::string& name);

        // 拷贝构造函数（深拷贝）
        ModelPose(const ModelPose& other);

        // 赋值运算符（深拷贝）
        ModelPose& operator=(const ModelPose& other);

        // ================== 姿态管理方法 ==================

        /**
         * 设置指定部件的姿态（深拷贝）
         */
        void setPartPose(const std::string& partName, const PartPose& pose);

        /**
         * 获取指定部件的姿态（如果不存在则创建默认姿态并返回其引用）
         */
        PartPose& getPartPose(const std::string& partName);

        /**
         * 获取指定部件的姿态（const 版本）
         * @throws std::out_of_range 如果部件不存在
         */
        const PartPose& getPartPose(const std::string& partName) const;


        /**
         * 检查是否包含指定部件的姿态
         */
        bool hasPartPose(const std::string& partName) const;

        /**
         * 移除指定部件的姿态
         */
        bool removePartPose(const std::string& partName);

        /**
         * 获取所有部件名称
         */
        std::map<std::string, PartPose>::key_compare getPartNames() const;

        /**
         * 清空所有部件姿态
         */
        void clear();

        /**
         * 获取部件数量
         */
        size_t getPartCount() const { return m_partPoses.size(); }

        // ================== 姿态混合 ==================

        /**
         * 在两个姿态间进行线性插值
         */
        static ModelPose lerp(const ModelPose& a, const ModelPose& b, float alpha, const std::string& resultName);

        /**
         * 将当前姿态与另一个姿态混合 (原地修改)
         */
        void blendWith(const ModelPose& other, float alpha);

        // ================== 预设姿态工厂方法 ==================

        static ModelPose createDefaultPose();
        static ModelPose createHiddenPose();
        static ModelPose createScaledPose(float scaleX, float scaleY);

        // ================== Getter和Setter ==================

        const std::string& getName() const { return m_name; }
        void setName(const std::string& name) { m_name = name; }

        float getBlendTime() const { return m_blendTime; }
        void setBlendTime(float blendTime);

        bool isDefaultPose() const { return m_isDefaultPose; }
        void setDefaultPose(bool defaultPose) { m_isDefaultPose = defaultPose; }

        // 访问整个姿态 Map 的方法，用于遍历和动画系统
        const PoseMap& getPartPoses() const { return m_partPoses; }

        // ================== 工具方法 ==================

        bool isEmpty() const { return m_partPoses.empty(); }
        std::string getDescription() const;
        bool operator==(const ModelPose& other) const;
        bool operator!=(const ModelPose& other) const { return !(*this == other); }
        std::string toString() const { return getDescription(); }

    private:
        std::string m_name;
        PoseMap m_partPoses;
        float m_blendTime = 0.3f; // 默认混合时间（秒）
        bool m_isDefaultPose = false;
    };

} // namespace Vivid2D

#endif // MODELPOSE_H
