#include "pch.h"
#include "legacy_ui_node_lifecycle.h"

#include "node.h"

namespace pp::panopainter
{
void legacy_ui_node_move_construct(Node& dest, Node&& src)
{
    dest.m_name = std::move(src.m_name);
    dest.m_nodeID_s = std::move(src.m_nodeID_s);
    dest.m_children = std::move(src.m_children);
    dest.m_nodeID = src.m_nodeID;
    dest.m_display = src.m_display;
    dest.m_parent = src.m_parent;
    dest.y_node = src.y_node;
    dest.m_pos = src.m_pos;
    dest.m_size = src.m_size;
    dest.m_clip = src.m_clip;
    dest.m_zoom = src.m_zoom;
    dest.m_mouse_ignore = src.m_mouse_ignore;
    src.y_node = nullptr;
    src.m_parent = nullptr;

    dest.set_manager(src.m_manager);
    for (auto& child : dest.m_children)
        child->m_parent = &dest;

    dest.current_mouse_capture = src.current_mouse_capture;
    dest.current_key_capture = src.current_key_capture;
    dest.m_mouse_captured = src.m_mouse_captured;
    dest.m_key_captured = src.m_key_captured;

    dest.m_proj = src.m_proj;
    dest.m_mvp = src.m_mvp;
    dest.m_mouse_inside = src.m_mouse_inside;
    dest.m_flood_events = src.m_flood_events;
    dest.m_force_mouse_capture = src.m_force_mouse_capture;
    dest.m_capture_children = src.m_capture_children;
    dest.m_destroyed = false; // src.m_destroyed

    dest.m_scale = src.m_scale;
    dest.m_pos_origin = src.m_pos_origin;
    dest.m_pos_offset = src.m_pos_offset;
    dest.m_pos_offset_childred = src.m_pos_offset_childred;
    dest.m_clip_uncut = src.m_clip_uncut;

    dest.auto_width = src.auto_width;
    dest.auto_height = src.auto_height;
}

void legacy_ui_node_destroy(Node& node)
{
    node.m_children.clear();
    if (node.y_node)
        YGNodeFree(node.y_node);
    if (node.y_placeholder)
        YGNodeFree(node.y_placeholder);
}

void legacy_ui_node_clone_copy(const Node& src, Node& dest)
{
    YGNodeCopyStyle(dest.y_node, src.y_node);
    dest.set_manager(src.m_manager);

    dest.m_name = src.m_name;
    dest.m_nodeID_s = src.m_nodeID_s;
    dest.m_nodeID = src.m_nodeID;
    dest.m_display = src.m_display;
    dest.m_pos = src.m_pos;
    dest.m_size = src.m_size;
    dest.m_clip = src.m_clip;
    dest.m_flood_events = src.m_flood_events;
    dest.m_force_mouse_capture = src.m_force_mouse_capture;

    dest.current_mouse_capture = src.current_mouse_capture;
    dest.current_key_capture = src.current_key_capture;
    dest.m_mouse_captured = src.m_mouse_captured;
    dest.m_key_captured = src.m_key_captured;
    dest.m_proj = src.m_proj;
    dest.m_mvp = src.m_mvp;
    dest.m_mouse_inside = src.m_mouse_inside;
    dest.m_capture_children = src.m_capture_children;
    dest.m_destroyed = false; // src.m_destroyed
    dest.m_scale = src.m_scale;
    dest.m_pos_origin = src.m_pos_origin;
    dest.m_pos_offset = src.m_pos_offset;
    dest.m_pos_offset_childred = src.m_pos_offset_childred;
    dest.m_clip_uncut = src.m_clip_uncut;

    dest.auto_width = src.auto_width;
    dest.auto_height = src.auto_height;
}

void legacy_ui_node_clone_children(const Node& src, Node& dest)
{
    for (auto& child : src.m_children)
    {
        std::shared_ptr<Node> clone = child->clone();
        dest.m_children.push_back(clone);
        clone->m_parent = &dest;
        clone->set_manager(dest.m_manager);
        clone->loaded();
        YGNodeInsertChild(dest.y_node, clone->y_node, YGNodeGetChildCount(dest.y_node));
    }
}
}

void Node::create()
{
}

void Node::init()
{
}

void Node::loaded()
{
}

void Node::added(Node* parent)
{
    for (auto& child : m_children)
        child->added(this);
}

void Node::removed(Node* parent)
{
    for (auto current = m_parent; current; current = current->m_parent)
        if (current->child_mouse_focus.get() == this)
            current->child_mouse_focus = nullptr;
}

Node&& Node::operator=(Node&& o)
{
    return std::forward<Node>(o);
}

Node::Node()
{
    y_node = YGNodeNew();
    YGNodeSetContext(y_node, this);
    y_placeholder = nullptr;
}

Node::Node(Node&& o)
{
    pp::panopainter::legacy_ui_node_move_construct(*this, std::move(o));
}

Node::~Node()
{
    pp::panopainter::legacy_ui_node_destroy(*this);
}

void Node::draw()
{
}

Node* Node::clone_instantiate() const
{
    return new Node();
}

void Node::clone_copy(Node* dest) const
{
    pp::panopainter::legacy_ui_node_clone_copy(*this, *dest);
}

void Node::clone_children(Node* dest) const
{
    pp::panopainter::legacy_ui_node_clone_children(*this, *dest);
}

void Node::clone_finalize(Node* dest) const
{
    /* find controllers and stuff */
}
