#include "pch.h"
#include "log.h"
#include "node_dialog_open.h"
#include "canvas.h"
#include "node_image_texture.h"
#include "asset.h"
#include "node_message_box.h"
#include "app.h"
#include "legacy_ui_overlay_services.h"

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

void NodeDialogOpen::clone_finalize(Node* dest) const
{
    NodeDialogOpen* n = static_cast<NodeDialogOpen*>(dest);
    n->init_controls();
}

void NodeDialogOpen::init()
{
    auto tpl = static_cast<const NodeBorder*>(init_template("dialog-open"));
    m_color = tpl->m_color;
    m_border_color = tpl->m_border_color;;
    m_thinkness = tpl->m_thinkness;;
    init_controls();
}

void NodeDialogOpen::init_controls()
{
    btn_ok = find<NodeButton>("btn-ok");
    btn_cancel = find<NodeButton>("btn-cancel");
    btn_delete = find<NodeButton>("btn-delete");
    btn_delete->on_click = [this](Node*) {
        if (!current)
            return;
        
        auto msgbox = pp::panopainter::make_legacy_overlay_node<NodeMessageBox>(*App::I);
        msgbox->m_title->set_text("Delete Project");
        msgbox->m_message->set_text(("Are you sure you want to delete " + current->m_file_name + "?").c_str());
        const auto overlay = pp::panopainter::open_legacy_overlay_node_with_handle(*this, msgbox);
        if (!overlay)
        {
            return;
        }
        const auto overlay_handle = overlay.value();
        const auto on_confirm = [this, overlay_handle](Node*){
            auto path = current->m_path;
            int idx = container->get_child_index(current);
            container->remove_child(current);
            if (!container->m_children.empty())
            {
                int newidx = std::min<int>(idx, (int)container->m_children.size() - 1);
                auto next = (NodeDialogOpenItem*)container->get_child_at(newidx);
                current = nullptr;
                next->on_selected(next);
                next->m_selected = true;
            }
            else
            {
                current = nullptr;
                auto image_tex = find<NodeImageTexture>("thumb-tex");
                image_tex->tex.reset();
            }
            Asset::delete_file(path);
            const auto close_status =
                pp::panopainter::close_legacy_overlay_node(*this, overlay_handle);
            (void)close_status;
        };
        msgbox->btn_ok->on_click = on_confirm;
        msgbox->on_submit = on_confirm;
        msgbox->btn_cancel->on_click = [this, overlay_handle](Node*) {
            const auto close_status =
                pp::panopainter::close_legacy_overlay_node(*this, overlay_handle);
            (void)close_status;
        };
        root()->update();
    };
    container = find<Node>("files-list");
    auto names = Asset::list_files(App::I->work_path, ".*\\.ppi");
    for (const auto& n : names)
    {
        auto node = new NodeDialogOpenItem;
        node->set_manager(m_manager);
        node->init();
        node->m_text->set_text(n.c_str());
        node->m_path = App::I->work_path + "/" + n;
        node->m_file_name = n;
        node->on_selected = [&](NodeDialogOpenItem* target) {
            if (target == current)
                return;
            Image thumb = Canvas::I->thumbnail_read(target->m_path);
            auto image_tex = find<NodeImageTexture>("thumb-tex");
            image_tex->tex = std::make_shared<Texture2D>();
            image_tex->tex->create(thumb);
            selected_path = target->m_path;
            selected_file = target->m_file_name;
            selected_name = selected_file.substr(0, selected_file.length() - strlen(".ppi"));
            if (current)
                current->m_selected = false;
            current = target;
        };
        container->add_child(node);
    }
    container->update();
    if (auto* first = (NodeDialogOpenItem*)container->get_child_at(0))
    {
        first->on_selected(first);
        first->m_selected = true;
    }
}

void NodeDialogOpen::loaded()
{
}

//////////////////////////////////////////////////////////////////

Node* NodeDialogOpenItem::clone_instantiate() const
{
    return new NodeDialogOpenItem;
}
void NodeDialogOpenItem::clone_finalize(Node* dest) const
{
    NodeDialogOpenItem* n = static_cast<NodeDialogOpenItem*>(dest);
    n->init_controls();
}
void NodeDialogOpenItem::init()
{
    init_template_file("data/dialogs/doc-open.xml", "dialog-open-item");
    init_controls();
}
void NodeDialogOpenItem::init_controls()
{
    m_text = find<NodeText>("title");
}
void NodeDialogOpenItem::loaded()
{

}
void NodeDialogOpenItem::draw()
{
    auto c = m_selected ? m_color_selected : m_color_normal;
    m_thinkness = m_selected ? 1.f : 0.f;
    m_color = m_mouse_inside ? m_color_hover : c;
    NodeBorder::draw();
}
kEventResult NodeDialogOpenItem::handle_event(Event* e)
{
    NodeBorder::handle_event(e);
    switch (e->m_type)
    {
    case kEventType::MouseEnter:
        break;
    case kEventType::MouseLeave:
        break;
    case kEventType::MouseDownL:
        m_selected = true;
        if (on_selected)
            on_selected(this);
        break;
    case kEventType::MouseUpL:
        break;
    default:
        return kEventResult::Available;
        break;
    }
    return kEventResult::Consumed;
}

//////////////////////////////////////////////////////////////////

Node* NodeDialogSave::clone_instantiate() const
{
    return new NodeDialogSave;
}
void NodeDialogSave::clone_finalize(Node* dest) const
{
    NodeDialogSave* n = static_cast<NodeDialogSave*>(dest);
    n->init_controls();
}
void NodeDialogSave::init()
{
    init_template_file("data/dialogs/doc-save.xml", "dialog-save");
    init_controls();
}
void NodeDialogSave::init_controls()
{
    btn_ok = find<NodeButton>("btn-ok");
    btn_cancel = find<NodeButton>("btn-cancel");
    input = find<NodeTextInput>("txt-input");
    input->on_return = [&](NodeTextInput* target){
        if (btn_ok->on_click)
            btn_ok->on_click(btn_ok);
    };
    if (App::I->supports_working_directory_picker())
    {
        btn_path = find<NodeButton>("btn-path");
        btn_path->on_click = [this](Node*) {
            App::I->pick_dir([this](std::string path) {
                LOG("change working path to %s", path.c_str());
                App::I->work_path = path;
                const auto display_path = App::I->format_working_directory_path(path);
                working_path->set_text_format(
                    "Working dir: %s",
                    display_path.c_str());
            });
        };
        working_path = find<NodeText>("path");
        const auto display_path = App::I->format_working_directory_path(App::I->work_path);
        working_path->set_text_format(
            "Working dir: %s",
            display_path.c_str());
    }
}
void NodeDialogSave::loaded()
{

}

void NodeDialogSave::added(Node* parent)
{
    Node::added(parent);
    if (added_to_root())
        input->key_capture();
}

//////////////////////////////////////////////////////////////////

Node* NodeDialogNewDoc::clone_instantiate() const
{
    return new NodeDialogNewDoc;
}
void NodeDialogNewDoc::clone_finalize(Node* dest) const
{
    NodeDialogNewDoc* n = static_cast<NodeDialogNewDoc*>(dest);
    n->init_controls();
}
void NodeDialogNewDoc::init()
{
    init_template_file("data/dialogs/doc-new.xml", "dialog-newdoc");
    init_controls();
}
void NodeDialogNewDoc::init_controls()
{
    btn_ok = find<NodeButton>("btn-ok");
    m_resolution = find<NodeComboBox>("resolution");
    btn_cancel = find<NodeButton>("btn-cancel");
    input = find<NodeTextInput>("txt-input");
    input->on_return = [&](NodeTextInput* target){
        if (btn_ok->on_click)
            btn_ok->on_click(btn_ok);
    };
    if (App::I->supports_working_directory_picker())
    {
        btn_path = find<NodeButton>("btn-path");
        btn_path->on_click = [this](Node*) {
            App::I->pick_dir([this](std::string path) {
                LOG("change working path to %s", path.c_str());
                App::I->work_path = path;
                const auto display_path = App::I->format_working_directory_path(path);
                working_path->set_text_format(
                    "Working dir: %s",
                    display_path.c_str());
            });
        };
        working_path = find<NodeText>("path");
        const auto display_path = App::I->format_working_directory_path(App::I->work_path);
        working_path->set_text_format(
            "Working dir: %s",
            display_path.c_str());
    }
}
void NodeDialogNewDoc::loaded()
{

}

void NodeDialogNewDoc::added(Node* parent)
{
    Node::added(parent);
    if (added_to_root())
        input->key_capture();
}
