/*
    Copyright (c) 2026 Christian Schoenebeck

    This file is part of "gigedit" and released under the terms of the
    GNU General Public License version 2.
*/

#include "GETreeView.h"

// Only used as fallback if double-click time setting could not be retrieved.
#define DEFAULT_FAST_DBLCLICK_MAX_TIME 400

// Hard coded for now, as there doesn't seem to be a matching Gtk setting.
#define SLOW_DBLCLICK_MAX_TIME 1000

// retrieve system's double-click time
static int _fastDblClickMaxTime() {
    GtkSettings* settings = gtk_settings_get_default();
    if (settings) {
        int time = 0;
        g_object_get(settings, "gtk-double-click-time", &time, NULL);
        if (time) return time;
    }
    return DEFAULT_FAST_DBLCLICK_MAX_TIME;
}

int GETreeView::getColumnIndex(Gtk::TreeViewColumn* pColumn) {
    if (!pColumn) return -1;
    std::vector<Gtk::TreeViewColumn*> columns = get_columns();
    for (size_t i = 0; i < columns.size(); ++i)
        if (columns[i] == pColumn) return (int) i;
    return -1;
}

bool GETreeView::on_button_press_event(GdkEventButton* event) {
    Gtk::TreeModel::Path path;
    Gtk::TreeViewColumn* pColumn = NULL;
    int cellX = 0;
    int cellY = 0;
    int iColumn = -1;

    if (!get_path_at_pos(event->x, event->y, path, pColumn, cellX, cellY))
        goto super_class_handler;

    if (!pColumn)
        goto super_class_handler;

    iColumn = getColumnIndex(pColumn);

    if (event->type != GDK_BUTTON_PRESS || event->button != 1) {
        goto reset_and_forward_click_event;
    } else {
        if (m_latestColumn == -1 || m_latestColumn != iColumn ||
            !m_latestPath || m_latestPath != path ||
            !m_latestClickTime)
        {
            goto store_and_forward_click_event;
        }

        const guint32 timeDiff = event->time - m_latestClickTime;

        if (timeDiff > SLOW_DBLCLICK_MAX_TIME)
            goto store_and_consume_click_event;

        if (timeDiff > _fastDblClickMaxTime())
            goto store_and_forward_click_event;

        // trigger any custom signal_row_activated() handler (but no edit)
        row_activated(path, *pColumn);

        // reset click time
        m_latestClickTime = 0;
        return true; // consume event
    }

    store_and_consume_click_event:

    m_latestClickTime = event->time;
    m_latestPath = path;
    m_latestColumn = iColumn;
    return false; // consume event

    store_and_forward_click_event:

    m_latestClickTime = event->time;
    m_latestPath = path;
    m_latestColumn = iColumn;
    goto super_class_handler;

    reset_and_forward_click_event:

    m_latestClickTime = 0;
    m_latestColumn = -1;
    m_latestPath = Gtk::TreeModel::Path();
    goto super_class_handler;

    super_class_handler:

    return Super::on_button_press_event(event);
}

bool GETreeView::on_key_press_event(GdkEventKey* event) {
    if (event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) {
        Gtk::TreeModel::Path path;
        Gtk::TreeViewColumn* pColumn = NULL;

        get_cursor(path, pColumn);

        if (!pColumn || !path)
            goto super_class_handler;

        // trigger any custom signal_row_activated() handler (but no edit)
        row_activated(path, *pColumn);
        return true; // consume event
    }

    super_class_handler:

    return Super::on_key_press_event(event);
}
