﻿/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QLoggingCategory>
#include <QTime>
#include <QGuiApplication>
#include <QMutableVectorIterator>

#include "handleatspievents.h"
#include "vkbhidetimer.h"
#include "atspi/atspi.h"

namespace  {
const QString KAtspiBusLauncher = "at-spi-bus-launcher";
const QString KAtspiRegistryd = "at-spi2-registryd";
const int KProsessIsRunning = 0;
}

Q_LOGGING_CATEGORY(lcHandleAtspiEvents, "qt.virtualkeyboard.tests.manual.x11vkbwrapper.handleatspievents")

/**
 * @brief focusEventFromInput Called when a widget is focused.
 * @param event
 * @param user_data
 */
 void focusEventFromInput(AtspiEvent *event, void *user_data)
{
    qCDebug(lcHandleAtspiEvents) << Q_FUNC_INFO;
    auto *handleATSPIEvents = static_cast<HandleATSPIEvents *>(user_data);
    handleATSPIEvents->gotFocusEventFromInput(event);
}

/**
 * @brief HandleATSPIEvents::HandleATSPIEvents
 * @param parent
 */
HandleATSPIEvents::HandleATSPIEvents(QObject *parent)
    : QObject(parent),
    m_keyboardVisible(false),
    m_focuses(0)
{

}

/**
 * @brief HandleATSPIEvents::~HandleATSPIEvents
 */
HandleATSPIEvents::~HandleATSPIEvents()
{
    qCDebug(lcHandleAtspiEvents) << Q_FUNC_INFO;

    m_focuses.clear();

    if (!atspi_event_listener_deregister_from_callback(focusEventFromInput, static_cast<void*>(this), "object:state-changed:focused", nullptr)) {
            qWarning() << "Error occurred: Problem deregistering focus listener";
     }
}

/**
 * @brief HandleATSPIEvents::init
 * @return false if at-spi is not running or callback regitering fail
 */

bool HandleATSPIEvents::init()
{
    qCDebug(lcHandleAtspiEvents) << Q_FUNC_INFO;
    /** Check that At-spi is running */
    if (KProsessIsRunning != system(QString("pidof -x %1 > /dev/null").arg(KAtspiBusLauncher).toLatin1().data()) ||
            KProsessIsRunning != system(QString("pidof -x %1 > /dev/null").arg(KAtspiRegistryd).toLatin1().data())) {
        qWarning() << "One or both of the At-Spi related processes are not running.";
        return false;
    }

    GError *error = nullptr;
    /** Registered the spi events to monitor focus and show on editable widgets. */
    if (!atspi_event_listener_register_from_callback(focusEventFromInput,
                                                     static_cast<void*>(this),
                                                     nullptr,
                                                     "object:state-changed:focused",
                                                     &error)){
        qWarning() << Q_FUNC_INFO << "Error occurred: ATSPI listener register failed. Error message:" << error->message;
        return false;
    }

    QObject::connect(QGuiApplication::inputMethod(), &QInputMethod::visibleChanged, [this] {
        this->setKeyboardVisible(QGuiApplication::inputMethod()->isVisible());
    });

    return true;
}

/**
 * @brief handleATSPIEvents::setKeyboardVisible
 * @param visible
 */
void HandleATSPIEvents::setKeyboardVisible(const bool visible)
{
    if (m_keyboardVisible != visible) {
        m_keyboardVisible = visible;
        qCDebug(lcHandleAtspiEvents) << "SET VKB visible " << visible;
        if (m_keyboardVisible && !QGuiApplication::inputMethod()->isVisible()) {
            QGuiApplication::inputMethod()->show();
        } else {
            QGuiApplication::inputMethod()->hide();
        }
    }
}

/**
 * @brief handleATSPIEvents::storeFocusElement
 * @param role
 * @param focus
 */
void HandleATSPIEvents::storeFocusElement(const qint8 role)
{
    m_focuses.append(role);
    qCDebug(lcHandleAtspiEvents) << "*****INSERTED FOCUS ELEMENT*****" << role << "TOTAL:"  << m_focuses.length();
}

/**
 * @brief handleATSPIEvents::isThereFocus
 * AT-SPI focus in/out events are received in random order and for some
 * objects AT-SPI doesn't send any focus OUT event at all.
 * This function keeps track if there's an accepted type of object in focus and
 * knows to release/ignore the objects that do not receive focus OUT event.
 * @param role
 */
bool HandleATSPIEvents::isThereFocus(const qint8 role)
{
    qCDebug(lcHandleAtspiEvents) << " FOCUS ELEMENT to EXAMINE: " << role;
    qint8 roleValue = ATSPI_ROLE_INVALID;
    for (auto iter = m_focuses.begin() ; iter != m_focuses.end() ; iter++) {
        roleValue = *iter;
        if (roleValue == role ||
            roleValue == ATSPI_ROLE_DOCUMENT_WEB ||
            roleValue == ATSPI_ROLE_ENTRY ||
            roleValue == ATSPI_ROLE_LINK) {
            qCDebug(lcHandleAtspiEvents) << "*****REMOVING FOCUS ELEMENT*****: " << *iter;
            m_focuses.erase(iter--);
        }
    }
    m_focuses.squeeze();
    return !m_focuses.isEmpty();
}

/**
 * @brief handleATSPIEvents::gotFocusEventFromInput
 * @param event
 */
void HandleATSPIEvents::gotFocusEventFromInput(const AtspiEvent *event)
{
    qCDebug(lcHandleAtspiEvents) << Q_FUNC_INFO << event->type << event->detail1 << event->detail2 << QTime::currentTime().toString();

    GError *error = nullptr;
    AtspiStateSet *state_set = atspi_accessible_get_state_set(event->source);
    AtspiRole role = atspi_accessible_get_role(event->source, &error);

    if (error) {
        qCDebug(lcHandleAtspiEvents) << Q_FUNC_INFO << "Event error message:" << error->message;
    }
    qCDebug(lcHandleAtspiEvents) << "ATSPI focus event received. Object role=" << role;

    if ((((role == ATSPI_ROLE_TERMINAL) || (role == ATSPI_ROLE_PANEL)  ||
          (role == ATSPI_ROLE_TABLE_CELL) ||
          (((role == ATSPI_ROLE_TEXT) ||
            (role == ATSPI_ROLE_PASSWORD_TEXT) ||
            (role == ATSPI_ROLE_SECTION) ||
            (role == ATSPI_ROLE_PARAGRAPH) ||
            (role = ATSPI_ROLE_ENTRY)) &&
           state_set &&
           atspi_state_set_contains(state_set, ATSPI_STATE_EDITABLE))))) {

        if (event->detail1) {
            qCDebug(lcHandleAtspiEvents) << "ACCEPTED FOCUS IN";
            VkbHideTimer::getInstance()->startTimer();
            this->storeFocusElement(role);
            if (!m_keyboardVisible) {
                setKeyboardVisible(true);
            }
        } else if (m_keyboardVisible && !isThereFocus(role)) {
            setKeyboardVisible(false);
        }

    } else {
        qCDebug(lcHandleAtspiEvents) << " ELSE: SET VKB visible FALSE";
        setKeyboardVisible(false);
        m_focuses.clear();
        m_focuses.squeeze();
    }
}

