#ifndef __WORKFLOW_EDITOR_HPP__
#define __WORKFLOW_EDITOR_HPP__

#include <vector>
#include <memory>
#include "imgui.h"
#include "imnodes.h"
#include "ID_Generator.hpp"
#include "Nodes_And_Connectors.hpp"

// 节点编辑器类
class Workflow_Editor
{
protected:
    // ID 分配器
    Independent_ID_Generator Connector_ID_Generator; // 连接点ID生成器
    Independent_ID_Generator Node_ID_Generator;      // 节点ID生成器
    Independent_ID_Generator Edge_ID_Generator;      // 边ID生成器

    // 边定义
    typedef struct
    {
        int id = -1;                  // 边ID
        int source_connector_id = -1; // 源连接点
        int target_connector_id = -1; // 目标连接点
    } Edge;

    // 数据池
    std::vector<std::shared_ptr<Abs_Node>> Node_Pool; // 节点池
    std::vector<Edge> Edge_Pool;                      // 边池

    /**
     * 顶层索引为起始工作流节点（N个元素即N个处理流程）
     * 次级索引为工作序列，表示完成一个处理流程的非冲突序列
     */
    std::vector<std::vector<std::shared_ptr<Abs_Node>>> Process_Route; // 工作层级路由

    // 删除节点 返回迭代器指定位置的下一个位置的迭代器，仅限内部使用
    std::vector<std::shared_ptr<Abs_Node>>::iterator Del_Node(std::vector<std::shared_ptr<Abs_Node>>::iterator iterator);

    // 删除边 返回迭代器指定位置的下一个位置的迭代器，仅限内部使用
    std::vector<Edge>::iterator Del_Link(std::vector<Edge>::iterator iterator);

public:
    // 绘制节点编辑器
    void Show(void);

    // 新增节点 true -> success / false -> failed
    bool Add_Node(Abs_Node::Node_Type_Enum type, ImVec2 initial_position = ImVec2(0, 0));

    // 删除节点 true -> success / false -> failed
    bool Del_Node(int target_node_id);

    // 新增连接 true -> success / false -> failed
    bool Add_Link(int source_connector_id, int target_connector_id);

    // 删除连接 true -> success / false -> failed
    bool Del_Link(int source_connector_id, int target_connector_id);

    // 创建工作路由 true -> success / false -> failed
    bool Build_Process_Route(void);

    // 清除工作路由 true -> success / false -> failed
    bool Clear_Process_Route(void);

    // 加载取配置文件 true -> success / false -> failed
    bool Load_Config(const char *file_path);

    // 存储配置文件 true -> success / false -> failed
    bool Store_Config(const char *file_path);
};

#endif