/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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 "accessibilityscenemanager.h"

AccessibilitySceneManager::AccessibilitySceneManager()
{
    m_window = 0;
    m_view = 0;
    m_scene = 0;
    m_rootItem = 0;
    m_optionsWidget = 0;
    m_selectedObject = 0;
}

void AccessibilitySceneManager::populateAccessibilityScene()
{
    m_scene->clear();
    m_graphicsItems.clear();

    QAccessibleInterface * rootInterface = m_window->accessibleRoot();
    if (!rootInterface)
        return;

    populateAccessibilityScene(rootInterface, m_scene);
}

void AccessibilitySceneManager::updateAccessibilitySceneItemFlags()
{
    qDebug() << "update";
    foreach (QObject *object, m_graphicsItems.keys()) {
        if (!object)
            continue;
        QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(object);
        if (!interface)
            continue;
        updateItemFlags(m_graphicsItems.value(object), interface);
    }
}

void AccessibilitySceneManager::populateAccessibilityTreeScene()
{
    m_treeScene->clear();
    QAccessibleInterface * rootInterface = m_window->accessibleRoot();
    if (!rootInterface) {
        qWarning("QWindow::accessibleRoot returned 0");
        return;
    }

    populateAccessibilityTreeScene(rootInterface);
}

void AccessibilitySceneManager::handleUpdate(QAccessibleEvent *event)
{
    QObject *object = event->object();
    QAccessible::Event type = event->type();

    QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(object);
    if (!interface)
        return;

    QString name = interface->text(QAccessible::Name);

    if (type == QAccessible::ObjectCreated) {
  //      qDebug() << "ObjectCreated" << object << name;
        populateAccessibilityScene(interface, m_scene);
    }

    QGraphicsRectItem *item = m_graphicsItems.value(object);

    if (!item) {
//        qDebug() << "populateAccessibilityScene failed for" << object;
        return;
    }

    if (type == QAccessible::LocationChanged) {

        //if (name.startsWith("List"))
            qDebug() << "locationChange" << object << name << interface->rect();

        updateItem(item, interface);
        for (int i = 0; i < interface->childCount(); ++i) {
           QAccessibleInterface *child = interface->child(i);
           if (child) {
               updateItem(m_graphicsItems.value(child->object()), child);
            }
        }

    } else if (type == QAccessible::ObjectDestroyed) {
//        qDebug() << "ObjectDestroyed" << object << name;
        delete m_graphicsItems.value(object);
        m_graphicsItems.remove(object);
        m_animatedObjects.remove(object);
        if (object == m_selectedObject) {
            m_selectedObject = 0;
        }
    } else if (type == QAccessible::ObjectHide) {
//        qDebug() << "ObjectCreated Hide" << object;
        updateItemFlags(item, interface);
    } else if (type == QAccessible::ObjectShow) {
//        qDebug() << "ObjectCreated Show" << object;
        updateItemFlags(item, interface);
    } else if (type == QAccessible::ScrollingStart) {
        qDebug() << "ObjectCreated ScrollingStart" << object;
        for (int i = 0; i < interface->childCount(); ++i) {
            QAccessibleInterface *child = interface->child(i);
            if (child) {
                m_animatedObjects.insert(child->object());
            }
        }
    } else if (type == QAccessible::ScrollingEnd) {
        // qDebug() << "ObjectCreated ScrollingEnd" << object;
        foreach (QObject *object, m_animatedObjects) {
            updateItem(m_graphicsItems.value(object), interface);
        }
        m_animatedObjects.clear();

    } else {
//        qDebug() << "other update" << object;
    }
}

void AccessibilitySceneManager::setSelected(QObject *object)
{
    m_scene->update(); // scedule update

    // clear existing selection
    if (m_selectedObject) {
        QObject *previousSelectedObject = m_selectedObject;
        m_selectedObject = 0;
        updateItem(previousSelectedObject);
    }

    m_selectedObject = object;
    updateItem(object);

    populateAccessibilityTreeScene();
}

void AccessibilitySceneManager::changeScale(int)
{
    // No QGraphicsView::setScale :(

    //m_view->scale(scale / 10.0, scale / 10.0);
    //if (m_rootItem)
    //    m_view->ensureVisible(m_rootItem);
}

void AccessibilitySceneManager::updateItems(QObject *root)
{
    QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(root);
    if (!interface)
        return;
    updateItem(m_graphicsItems.value(root), interface);

    for (int i = 0; i < interface->childCount(); ++i) {
        QAccessibleInterface *child = interface->child(i);
        updateItems(child->object());
    }
}

void AccessibilitySceneManager::updateItem(QObject *object)
{
    if (!object)
        return;

    QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(object);
    if (!interface)
        return;

    updateItem(m_graphicsItems.value(object), interface);
}

void AccessibilitySceneManager::updateItem(QGraphicsRectItem *item, QAccessibleInterface *interface)
{
    if (!item)
        return;

    QRect rect = interface->rect();
    item->setPos(rect.topLeft());
    item->setRect(QRect(QPoint(0,0), rect.size()));

    updateItemFlags(item, interface);
}

void AccessibilitySceneManager::updateItemFlags(QGraphicsRectItem *item, QAccessibleInterface *interface)
{
  //  qDebug() << "udpateItemFlags" << interface << interface->object();

    bool shouldShow = true;

    if (m_optionsWidget->hideInvisibleItems()) {
        if (isHidden(interface)) {
            shouldShow = false;
        }
    }

    if (m_optionsWidget->hideOffscreenItems()) {
        if (interface->state().offscreen) {
            shouldShow = false;
        }
    }

    if (m_optionsWidget->hidePaneItems()) {
        if (interface->role() & QAccessible::Pane) {
            shouldShow = false;
        }
    }

    if (m_optionsWidget->hideNullObjectItems()) {
        if (interface->object() == 0) {
            shouldShow = false;
        }
    }

    if (m_optionsWidget->hideNullRectItems()) {
        if (interface->rect().isNull()) {
            shouldShow = false;
        }
    }

    item->setVisible(shouldShow);

    if (interface->object() && interface->object() == m_selectedObject)
        item->setBrush(QColor(Qt::yellow));
    else
        item->setBrush(QColor(Qt::white));

    m_view->update();
}

QGraphicsRectItem * AccessibilitySceneManager::processInterface(QAccessibleInterface * interface, QGraphicsScene *scene)
{
    // Process this interface

    QGraphicsRectItem * item = new QGraphicsRectItem();
    scene->addItem(item);
    if (!m_rootItem)
        m_rootItem = item;

    QString name = interface->text(QAccessible::Name);
    QString description; // = interface->text(QAccessibleInterface::Description, child);
    QString role = translateRole(interface->role());
    int childCount = interface->childCount();

    /* qDebug() << "name:" << name << "local pos" <<
               interface->rect(0) << "description" << description << "childCount" << childCount;
*/

    updateItem(item, interface);

    QGraphicsSimpleTextItem * textItem = new QGraphicsSimpleTextItem();
    textItem->setParentItem(item);
    textItem->setPos(QPoint(5, 5));

    QString text;
    text.append("Name: " + name + " ");
    if (!description.isEmpty())
        text.append("Description: " + description + " ");
    text.append("Role: " + role + " ");
    if (childCount > 0)
        text.append("ChildCount: " + QString::number(childCount) + " ");
    textItem->setText(text);

    QFont font;
    font.setPointSize(10);
 //   font.setPointSize(14);
    textItem->setFont(font);

    return item;
}

void AccessibilitySceneManager::populateAccessibilityScene(QAccessibleInterface * interface, QGraphicsScene *scene)
{
    if (!interface)
        return;

    QGraphicsRectItem *item = processInterface(interface, scene);

    QObject *object = interface->object();
    if (object) {
        m_graphicsItems.insert(object, item);
    }

    for (int i = 0; i < interface->childCount(); ++i) {
        QAccessibleInterface *child = interface->child(i);
        updateItems(child->object());
        populateAccessibilityScene(child, scene);
    }
}

AccessibilitySceneManager::TreeItem AccessibilitySceneManager::computeLevels(QAccessibleInterface * interface, int level)
{
    if (interface == 0)
        return TreeItem();

    TreeItem currentLevel;

    int usedChildren = 0;
    for (int i = 0; i < interface->childCount(); ++i) {
        QAccessibleInterface *child = interface->child(i);
        if (child != 0) {
            ++usedChildren;
            TreeItem childLevel = computeLevels(child, level + 1);
            currentLevel.children.append(childLevel);
            currentLevel.width += childLevel.width + m_treeItemHorizontalPadding;
        }
    }

    // leaf node case
    if (usedChildren == 0) {
        currentLevel.width = m_treeItemWidth + m_treeItemHorizontalPadding;
    }

    // capture information:
    currentLevel.name = interface->text(QAccessible::Name);
    currentLevel.description += interface->text(QAccessible::DebugDescription);
    currentLevel.role = translateRole(interface->role());
    currentLevel.rect = interface->rect();
    currentLevel.state = interface->state();
    currentLevel.object = interface->object();

    return currentLevel;
}

void AccessibilitySceneManager::populateAccessibilityTreeScene(QAccessibleInterface * interface)
{
    if (!interface)
        return;

    // set some layout metrics:
    m_treeItemWidth = 90;
    m_treeItemHorizontalPadding = 10;
    m_treeItemHeight = 60;
    m_treeItemVerticalPadding = 30;

    // We want to draw the accessibility hiearchy as a vertical
    // tree, growing from the root node at the top.

    // First, figure out the number of levels and the width of each level:
    m_rootTreeItem = computeLevels(interface, 0);

    // create graphics items for each tree item
    addGraphicsItems(m_rootTreeItem, 0, 0);
}

void AccessibilitySceneManager::addGraphicsItems(AccessibilitySceneManager::TreeItem item, int row, int xPos)
{
    //qDebug() << "add graphics item" << row << item.name << item.role << xPos << item.width << item.children.count();

    int yPos = row * (m_treeItemHeight + m_treeItemVerticalPadding);

    // Process this interface
    QGraphicsRectItem * graphicsItem = new QGraphicsRectItem();
    graphicsItem->setPos(xPos, yPos);
    graphicsItem->setRect(0, 0, m_treeItemWidth, m_treeItemHeight);
    graphicsItem->setFlag(QGraphicsItem::ItemClipsChildrenToShape);

    if (item.object && item.object == m_selectedObject)
        graphicsItem->setBrush(QColor(Qt::yellow));
    else
        graphicsItem->setBrush(QColor(Qt::white));

    if (item.state.offscreen) {
        QPen linePen;
        linePen.setStyle(Qt::DashLine);
        graphicsItem->setPen(linePen);
    }

    m_treeScene->addItem(graphicsItem);

    QGraphicsTextItem * textItem = new QGraphicsTextItem();
    textItem->setParentItem(graphicsItem);
    textItem->setPos(QPoint(0, 0));

    QFont font;
    font.setPointSize(8);
    textItem->setFont(font);

    QString text;
    text += item.name + "\n";
    text += item.role + "\n";
    text += item.description.split(QLatin1Char(' '), Qt::SkipEmptyParts).join("\n") + "\n";
    text += "P:" + QString::number(item.rect.x()) + " " + QString::number(item.rect.y()) + " ";
    text += "S:" + QString::number(item.rect.width()) + " " + QString::number(item.rect.height()) + "\n";

    textItem->setPlainText(text);

    // recurse to children
    int childIndex = 0;
    int childCount = item.children.count();
    int segmentSize = item.width / qMax(1, childCount);
    int segmentCenterOffset = segmentSize / 2;
    int segmentsStart = xPos - (item.width / 2);
    foreach (TreeItem child, item.children) {
        // spread the children out, covering the width, centered on xPos
        int segmentPosition = segmentsStart + (segmentSize * childIndex) + segmentCenterOffset;
        addGraphicsItems(child, row + 1, segmentPosition);
        ++childIndex;
    }

    // add lines from parents to kids
    int boxBottom = yPos + m_treeItemHeight;
    int boxMiddleX = xPos + m_treeItemWidth / 2;
    int yBottomMiddle = boxBottom + m_treeItemVerticalPadding / 2;
    int boxTop = yPos;
    int yTopMiddle = boxTop - m_treeItemVerticalPadding / 2;

    if (row > 0) {
        QGraphicsLineItem *childVerticalStem = new QGraphicsLineItem();
        childVerticalStem->setLine(boxMiddleX, yTopMiddle, boxMiddleX, boxTop);
        m_treeScene->addItem(childVerticalStem);
    }

    if (childCount > 0) {
        QGraphicsLineItem *parentVerticalStem = new QGraphicsLineItem();
        parentVerticalStem->setLine(boxMiddleX, boxBottom, boxMiddleX, yBottomMiddle);
        m_treeScene->addItem(parentVerticalStem);
    }

    if (childCount > 1) {
        QGraphicsLineItem *horizontalStem = new QGraphicsLineItem();
        // match the end points with the horizontal lines
        int lineStartX = segmentsStart + segmentCenterOffset + m_treeItemWidth / 2;
        int lineStopX = segmentsStart + segmentSize * (childCount -1) + segmentCenterOffset + m_treeItemWidth / 2;
        horizontalStem->setLine(lineStartX, yBottomMiddle, lineStopX , yBottomMiddle);
        m_treeScene->addItem(horizontalStem);
    }
}

bool AccessibilitySceneManager::isHidden(QAccessibleInterface *interface)
{
    QAccessibleInterface *current = interface;
    while (current) {

        if (current->state().invisible) {
            return true;
        }

        current = current->parent();
    }

    return false;
}
