#include "pch.h"
#include "app.h"
#include "node_border.h"
#include "node_button_custom.h"
#include "node_icon.h"
#include "node_image.h"
#include "node_shorcuts.h"
#include "node_stroke_preview.h"
#include "node_text.h"
#include "app_core/app_status.h"

#include <vector>

namespace {

std::vector<std::shared_ptr<Layer>> saved_layers;

void capture_layout_reload_state(App& app)
{
    saved_layers = std::move(Canvas::I->m_layers);
    app.ui_save();
    NodeStrokePreview::empty_queue();
}

void apply_layout_loaded_state(App& app, bool reloaded)
{
    LOG("initializing layout updating after load %d x %d zoom %f", (int)app.width, (int)app.height, app.zoom);
    app.layout[app.main_id]->update(app.width, app.height, app.zoom);

    LOG("initializing layout components");
    app.init_sidebar();

    if (reloaded) {
        for (const auto& layer : saved_layers)
            app.layers->add_layer(layer->m_name.c_str(), false, true, layer);
    } else {
        app.layers->add_layer("Default", false, true);
        Canvas::I->m_unsaved = false;
    }

    app.init_toolbar_draw();
    app.init_toolbar_main();
    app.init_menu_file();
    app.init_menu_edit();
    app.init_menu_layer();
    app.init_menu_tools();
    app.init_menu_about();

    if (auto* version_label = app.layout[app.main_id]->find<NodeText>("version")) {
        version_label->set_text(g_version);
    }

    const auto renderer_features = ShaderManager::render_device_features();
    const auto renderer_diagnostics = pp::app::plan_renderer_diagnostics({
        .framebuffer_fetch = renderer_features.framebuffer_fetch,
        .float32_render_targets = renderer_features.float32_render_targets,
        .float32_linear_filtering = renderer_features.float32_linear_filtering,
        .float16_render_targets = renderer_features.float16_render_targets,
    });

    if (auto* indicator = app.layout[app.main_id]->find<NodeBorder>("ext-fbf")) {
        indicator->m_color = renderer_diagnostics.framebuffer_fetch.supported
            ? glm::vec4(0, 1, 0, 1)
            : glm::vec4(1, 0, 0, 1);
    }

    if (auto* indicator = app.layout[app.main_id]->find<NodeBorder>("ext-flt")) {
        if (renderer_diagnostics.floating_point_targets.supported) {
            if (auto* text = indicator->find<NodeText>("ext-flt-text"))
                text->set_text(std::string(renderer_diagnostics.floating_point_targets.label));
            indicator->m_color = glm::vec4(0, 1, 0, 1);
        } else {
            indicator->m_color = glm::vec4(1, 0, 0, 1);
        }
    }

    app.dialog_whatsnew(false);
    app.brush_update(true, true);

    if (auto* toolbar = app.layout[app.main_id]->find<Node>("toolbar"))
        toolbar->m_flood_events = true;

    auto* toggle_button = new NodeImage;
    toggle_button->m_path = "data/ui/p-black.png";
    toggle_button->m_tex_id = const_hash("data/ui/p-black.png");
    toggle_button->SetSize(30, 45);
    toggle_button->create();

    auto* button = new NodeButtonCustom;
    button->create();
    button->add_child(toggle_button);
    button->SetPositioning(YGPositionTypeAbsolute);
    button->set_color({ 0, 0, 0, 0 });
    YGNodeStyleSetPosition(button->y_node, YGEdgeBottom, 8);
    YGNodeStyleSetPosition(button->y_node, YGEdgeLeft, 10);
    app.layout[app.main_id]->add_child(button);

    button->on_click = [&app](Node*) {
        app.toggle_ui();
    };

    app.ui_restore();
    app.redraw = true;
}

void init_layout_designer(App& app)
{
    app.layout_designer.on_loaded = [&app](bool) {
        app.layout_designer.create();
        auto* shortcuts = app.layout_designer[app.main_id]->add_child<NodeShortcuts>();
        (void)shortcuts;
    };
}

} // namespace

namespace pp::panopainter {

void init_layout_bootstrap(App& app)
{
    LOG("initializing layout statics");
    NodeBorder::static_init();
    NodeImage::static_init();
    NodeIcon::static_init();
    NodeStrokePreview::static_init();

    app.layout.on_reloading = [&app] {
        capture_layout_reload_state(app);
    };

    app.layout.on_loaded = [&app](bool reloaded) {
        apply_layout_loaded_state(app, reloaded);
    };

    LOG("initializing layout xml");
    if (app.layout.m_loaded) {
        LOG("restore layout");
        app.layout.restore_context();
    } else {
        app.layout.load("data/layout.xml");
    }
    LOG("initializing layout completed");

    LOG("initializing layout designer xml");
    init_layout_designer(app);
}

} // namespace pp::panopainter
