#include "pch.h"
#include "Vertex.h"
#include <sstream>
#include <iomanip>

namespace Vivid2D::util {

    // --- 构造函数实现 ---

    Vertex::Vertex(float x, float y, float u, float v)
        : position(x, y), uv(u, v), originalPosition(x, y), // 初始时，原始位置=当前位置
        tag(VertexTag::DEFAULT), selected(false), IsDelete(false), index(-1) {
        // std::cout << "Vertex(x, y, u, v) created." << std::endl; // 调试信息
    }

    Vertex::Vertex(const glm::vec2& position, const glm::vec2& uv)
        : position(position), uv(uv), originalPosition(position),
        tag(VertexTag::DEFAULT), selected(false), IsDelete(false), index(-1) {
    }

    Vertex::Vertex(const glm::vec2& position, const glm::vec2& uv, VertexTag tag)
        : position(position), uv(uv), originalPosition(position),
        tag(tag), selected(false), IsDelete(false), index(-1) {
    }

    Vertex::Vertex(const glm::vec2& position, const glm::vec2& uv, const glm::vec2& originalPosition)
        : position(position), uv(uv), originalPosition(originalPosition),
        tag(VertexTag::DEFAULT), selected(false), IsDelete(false), index(-1) {
    }

    Vertex::Vertex(float x, float y)
        : position(x, y), uv(0.0f, 0.0f), originalPosition(x, y),
        tag(VertexTag::DEFAULT), selected(false), IsDelete(false), index(-1) {
    }

    // --- 拷贝/赋值实现 ---

    // 拷贝构造函数 (执行深拷贝)
    Vertex::Vertex(const Vertex& other)
        : position(other.position),
        uv(other.uv),
        originalPosition(other.originalPosition),
        controlledTriangles(other.controlledTriangles),
        tag(other.tag),
        selected(other.selected),
        name(other.name),
        IsDelete(other.IsDelete),
        index(other.index) {
    }

    // 拷贝赋值运算符
    Vertex& Vertex::operator=(const Vertex& other) {
        if (this != &other) {
            position = other.position;
            uv = other.uv;
            originalPosition = other.originalPosition;
            controlledTriangles = other.controlledTriangles;
            tag = other.tag;
            selected = other.selected;
            name = other.name;
            IsDelete = other.IsDelete;
            index = other.index;
        }
        return *this;
    }

    // --- 核心逻辑方法实现 ---

    void Vertex::resetToOriginal() {
        this->position = this->originalPosition; // glm::vec2 重载了赋值运算符
    }

    void Vertex::saveAsOriginal() {
        this->originalPosition = this->position;
    }

    Vertex Vertex::copy() const {
        // C++ 中推荐使用拷贝构造函数或赋值运算符
        Vertex newCopy = *this; // 使用拷贝构造函数进行深拷贝
        return newCopy;
    }

    void Vertex::setControlledTriangles(const std::vector<int>& controlledTriangles) {
        this->controlledTriangles = controlledTriangles;
    }

    // --- C++ 特性：重载运算符和输出流实现 ---

    // 重载相等运算符 (对应 Java 中的 equals())
    bool Vertex::operator==(const Vertex& other) const {
        return selected == other.selected &&
            IsDelete == other.IsDelete &&
            position == other.position &&
            uv == other.uv &&
            originalPosition == other.originalPosition &&
            tag == other.tag &&
            name == other.name;
    }

    // 重载输出流运算符 (对应 Java 中的 toString())
    std::ostream& operator<<(std::ostream& os, const Vertex& vertex) {
        std::string tagStr;
        switch (vertex.tag) {
        case VertexTag::DEFAULT: tagStr = "DEFAULT"; break;
            // 添加其他 case
        default: tagStr = "UNKNOWN"; break;
        }

        // 格式化输出 glm::vec2
        auto formatVec2 = [](const glm::vec2& v) -> std::string {
            std::stringstream ss;
            ss << std::fixed << std::setprecision(4) << "(" << v.x << ", " << v.y << ")";
            return ss.str();
            };

        os << "Vertex{"
            << "name='" << vertex.name << '\''
            << ", pos=" << formatVec2(vertex.position)
            << ", uv=" << formatVec2(vertex.uv)
            << ", orig=" << formatVec2(vertex.originalPosition)
            << ", tag=" << tagStr
            << ", selected=" << (vertex.selected ? "true" : "false")
            << ", isDelete=" << (vertex.IsDelete ? "true" : "false")
            << '}';
        return os;
    }

} // namespace util