/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qaccessiblemenu.h"

#include <qmenu.h>
#include <qmenubar.h>
#include <QtGui/QAction>
#include <qstyle.h>

#ifndef QT_NO_ACCESSIBILITY

QT_BEGIN_NAMESPACE

#ifndef QT_NO_MENU

QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
QString Q_GUI_EXPORT qt_accHotKey(const QString &text);

QAccessibleMenu::QAccessibleMenu(QWidget *w)
: QAccessibleWidgetEx(w)
{
    Q_ASSERT(menu());
}

QMenu *QAccessibleMenu::menu() const
{
    return qobject_cast<QMenu*>(object());
}

int QAccessibleMenu::childCount() const
{
    return menu()->actions().count();
}

QRect QAccessibleMenu::rect(int child) const
{
    if (!child || child > childCount())
        return QAccessibleWidgetEx::rect(child);

    QRect r = menu()->actionGeometry(menu()->actions()[child - 1]);
    QPoint tlp = menu()->mapToGlobal(QPoint(0,0));

    return QRect(tlp.x() + r.x(), tlp.y() + r.y(), r.width(), r.height());
}

int QAccessibleMenu::childAt(int x, int y) const
{
    QAction *act = menu()->actionAt(menu()->mapFromGlobal(QPoint(x,y)));
    if(act && act->isSeparator())
        act = 0;
    return menu()->actions().indexOf(act) + 1;
}

QString QAccessibleMenu::text(Text t, int child) const
{
    QString tx = QAccessibleWidgetEx::text(t, child);
    if (tx.size())
        return tx;

    switch (t) {
    case Name:
        if (!child)
            return menu()->windowTitle();
        return qt_accStripAmp(menu()->actions().at(child-1)->text());
    case Help:
        return child ? menu()->actions().at(child-1)->whatsThis() : tx;
#ifndef QT_NO_SHORTCUT
    case Accelerator:
        return child ? static_cast<QString>(menu()->actions().at(child-1)->shortcut()) : tx;
#endif
    default:
        break;
    }
    return tx;
}

QAccessible::Role QAccessibleMenu::role(int child) const
{
    if (!child)
        return PopupMenu;

    QAction *action = menu()->actions()[child-1];
    if (action && action->isSeparator())
        return Separator;
    return MenuItem;
}

QAccessible::State QAccessibleMenu::state(int child) const
{
    State s = QAccessibleWidgetEx::state(child);
    if (!child)
        return s;

    QAction *action = menu()->actions()[child-1];
    if (!action)
        return s;

    if (menu()->style()->styleHint(QStyle::SH_Menu_MouseTracking))
        s |= HotTracked;
    if (action->isSeparator() || !action->isEnabled())
        s |= Unavailable;
    if (action->isChecked())
        s |= Checked;
    if (menu()->activeAction() == action)
        s |= Focused;

    return s;
}

QString QAccessibleMenu::actionText(int action, QAccessible::Text text, int child) const
{
    if (action == QAccessible::DefaultAction && child && text == QAccessible::Name) {
        QAction *a = menu()->actions().value(child-1, 0);
        if (!a || a->isSeparator())
            return QString();
        if (a->menu()) {
            if (a->menu()->isVisible())
                return QMenu::tr("Close");
            return QMenu::tr("Open");
        }
        return QMenu::tr("Execute");
     }

    return QAccessibleWidgetEx::actionText(action, text, child);
}

bool QAccessibleMenu::doAction(int act, int child, const QVariantList &)
{
    if (!child || act != QAccessible::DefaultAction)
        return false;

    QAction *action = menu()->actions().value(child-1, 0);
    if (!action || !action->isEnabled())
        return false;

    if (action->menu() && action->menu()->isVisible())
        action->menu()->hide();
    else
        menu()->setActiveAction(action);
    return true;
}

int QAccessibleMenu::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
{
    int ret = -1;
    if (entry < 0) {
        *target = 0;
        return ret;
    }

    if (relation == Self || entry == 0) {
        *target = new QAccessibleMenu(menu());
        return 0;
    }

    switch (relation) {
    case Child:
        if (entry <= childCount()) {
            *target = new QAccessibleMenuItem(menu(), menu()->actions().at( entry - 1 ));
            ret = 0;
        }
        break;
    case Ancestor: {
        QAccessibleInterface *iface;
        QWidget *parent = menu()->parentWidget();
        if (qobject_cast<QMenu*>(parent) || qobject_cast<QMenuBar*>(parent)) {
            iface = new QAccessibleMenuItem(parent, menu()->menuAction());
            if (entry == 1) {
                *target = iface;
                ret = 0;
            } else {
                ret = iface->navigate(Ancestor, entry - 1, target);
                delete iface;
            }
        } else {
            return QAccessibleWidgetEx::navigate(relation, entry, target); 
        }
        break;}
    default:
        return QAccessibleWidgetEx::navigate(relation, entry, target);
    }


    if (ret == -1)
        *target = 0;

    return ret;

}

int QAccessibleMenu::indexOfChild( const QAccessibleInterface *child ) const
{
    int index = -1;
    Role r = child->role(0);
    if ((r == MenuItem || r == Separator) && menu()) {
        index = menu()->actions().indexOf(qobject_cast<QAction*>(child->object()));
        if (index != -1)
            ++index;
    }
    return index;
}

#ifndef QT_NO_MENUBAR
QAccessibleMenuBar::QAccessibleMenuBar(QWidget *w)
: QAccessibleWidgetEx(w)
{
    Q_ASSERT(menuBar());
}

QMenuBar *QAccessibleMenuBar::menuBar() const
{
    return qobject_cast<QMenuBar*>(object());
}

int QAccessibleMenuBar::childCount() const
{
    return menuBar()->actions().count();
}

QRect QAccessibleMenuBar::rect(int child) const
{
    if (!child)
        return QAccessibleWidgetEx::rect(child);

    QRect r = menuBar()->actionGeometry(menuBar()->actions()[child - 1]);
    QPoint tlp = menuBar()->mapToGlobal(QPoint(0,0));
    return QRect(tlp.x() + r.x(), tlp.y() + r.y(), r.width(), r.height());
}

int QAccessibleMenuBar::childAt(int x, int y) const
{
    for (int i = childCount(); i >= 0; --i) {
        if (rect(i).contains(x,y))
            return i;
    }
    return -1;
}

int QAccessibleMenuBar::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
{
    int ret = -1;
    if (entry < 0) {
        *target = 0;
        return ret;
    }

    if (relation == Self || entry == 0) {
        *target = new QAccessibleMenuBar(menuBar());
        return 0;
    }

    switch (relation) {
    case Child:
        if (entry <= childCount()) {
            *target = new QAccessibleMenuItem(menuBar(), menuBar()->actions().at( entry - 1 ));
            ret = 0;
        }
        break;
    default:
        return QAccessibleWidgetEx::navigate(relation, entry, target);
    }


    if (ret == -1)
        *target = 0;

    return ret;
}

int QAccessibleMenuBar::indexOfChild( const QAccessibleInterface *child ) const
{
    int index = -1;
    Role r = child->role(0);
    if ((r == MenuItem || r == Separator) && menuBar()) {
        index = menuBar()->actions().indexOf(qobject_cast<QAction*>(child->object()));
        if (index != -1)
            ++index;
    }
    return index;
}

QString QAccessibleMenuBar::text(Text t, int child) const
{
    QString str;

    if (child) {
        if (QAction *action = menuBar()->actions().value(child - 1, 0)) {
            switch (t) {
            case Name:
                return qt_accStripAmp(action->text());
            case Accelerator:
                str = qt_accHotKey(action->text());
                break;
            default:
                break;
            }
        }
    }
    if (str.isEmpty())
        str = QAccessibleWidgetEx::text(t, child);
    return str;
}

QAccessible::Role QAccessibleMenuBar::role(int child) const
{
    if (!child)
        return MenuBar;

    QAction *action = menuBar()->actions()[child-1];
    if (action && action->isSeparator())
        return Separator;
    return MenuItem;
}

QAccessible::State QAccessibleMenuBar::state(int child) const
{
    State s = QAccessibleWidgetEx::state(child);
    if (!child)
        return s;

    QAction *action = menuBar()->actions().value(child-1, 0);
    if (!action)
        return s;

    if (menuBar()->style()->styleHint(QStyle::SH_Menu_MouseTracking))
        s |= HotTracked;
    if (action->isSeparator() || !action->isEnabled())
        s |= Unavailable;
    if (menuBar()->activeAction() == action)
        s |= Focused;

    return s;
}

QString QAccessibleMenuBar::actionText(int action, QAccessible::Text text, int child) const
{
    if (action == QAccessible::DefaultAction && child && text == QAccessible::Name) {
        QAction *a = menuBar()->actions().value(child-1, 0);
        if (!a || a->isSeparator())
            return QString();
        if (a->menu()) {
            if (a->menu()->isVisible())
                return QMenu::tr("Close");
            return QMenu::tr("Open");
        }
        return QMenu::tr("Execute");
    }

    return QAccessibleWidgetEx::actionText(action, text, child);
}

bool QAccessibleMenuBar::doAction(int act, int child, const QVariantList &)
{
    if (act != !child)
        return false;

    QAction *action = menuBar()->actions().value(child-1, 0);
    if (!action || !action->isEnabled())
        return false;
    if (action->menu() && action->menu()->isVisible())
        action->menu()->hide();
    else
        menuBar()->setActiveAction(action);
    return true;
}

#endif // QT_NO_MENUBAR

QAccessibleMenuItem::QAccessibleMenuItem(QWidget *owner, QAction *action) : m_action(action), m_owner(owner)
{
}


QAccessibleMenuItem::~QAccessibleMenuItem()
{}

int QAccessibleMenuItem::childAt(int x, int y ) const
{
    for (int i = childCount(); i >= 0; --i) {
        if (rect(i).contains(x,y))
            return i;
    }
    return -1;
}

int QAccessibleMenuItem::childCount() const
{
    return m_action->menu() ? 1 : 0;
}

QString QAccessibleMenuItem::actionText(int action, Text text, int child ) const
{
    if (text == Name && child == 0) {
        switch (action) {
        case Press:
        case DefaultAction:
            return QMenu::tr("Execute");
            break;
        default:
            break;
        }
    }
    return QString();
}

bool QAccessibleMenuItem::doAction(int action, int child, const QVariantList & /*params = QVariantList()*/ )
{
    if ((action == Press || action == DefaultAction) && child == 0) {
        m_action->trigger();
        return true;
    }
    return false;
}

int QAccessibleMenuItem::indexOfChild( const QAccessibleInterface * child ) const
{
    if (child->role(0) == PopupMenu && child->object() == m_action->menu())
        return 1;

    return -1;
}

bool QAccessibleMenuItem::isValid() const
{
    return m_action ? true : false;
}

int QAccessibleMenuItem::navigate(RelationFlag relation, int entry, QAccessibleInterface ** target ) const
{
    int ret = -1;
    if (entry < 0) {
        *target = 0;
        return ret;
    }

    if (relation == Self || entry == 0) {
        *target = new QAccessibleMenuItem(owner(), action());
        return 0;
    }

    switch (relation) {
    case Child:
        if (entry <= childCount()) {
            *target = new QAccessibleMenu(action()->menu());
            ret = 0;
        }
        break;

    case Ancestor:{
        QWidget *parent = owner();
        QAccessibleInterface *ancestor = parent ? QAccessible::queryAccessibleInterface(parent) : 0;
        if (ancestor) {
            if (entry == 1) {
                *target = ancestor;
                ret = 0;
            } else {
                ret = ancestor->navigate(Ancestor, entry - 1, target);
                delete ancestor;
            }
        }
        break;}
    case Up:
    case Down:{
        QAccessibleInterface *parent = 0;
        int ent = navigate(Ancestor, 1, &parent);
        if (ent == 0) {
            int index = parent->indexOfChild(this);
            if (index != -1) {
                index += (relation == Down ? +1 : -1);
                ret = parent->navigate(Child, index, target);
            }
        }
        delete parent;
        break;}
    case Sibling: {
        QAccessibleInterface *parent = 0;
        int ent = navigate(Ancestor, 1, &parent);
        if (ent == 0) {
            ret = parent->navigate(Child, entry, target);
        }
        delete parent;
        break;}
    default:
        break;

    }
    if (ret == -1)
        *target = 0;
    return ret;
}

QObject *QAccessibleMenuItem::object() const
{
    return m_action;
}

QRect QAccessibleMenuItem::rect (int child ) const
{
    QRect rect;
    if (child == 0) {
        QWidget *own = owner();
#ifndef QT_NO_MENUBAR
        if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
            rect = menuBar->actionGeometry(m_action);
            QPoint globalPos = menuBar->mapToGlobal(QPoint(0,0));
            rect = rect.translated(globalPos);
        } else
#endif // QT_NO_MENUBAR
        if (QMenu *menu = qobject_cast<QMenu*>(own)) {
            rect = menu->actionGeometry(m_action);
            QPoint globalPos = menu->mapToGlobal(QPoint(0,0));
            rect = rect.translated(globalPos);
        }
    } else if (child == 1) {
        QMenu *menu = m_action->menu();
        if (menu) {
            rect = menu->rect();
            QPoint globalPos = menu->mapToGlobal(QPoint(0,0));
            rect = rect.translated(globalPos);
        }
    }
    return rect;
}

QAccessible::Relation QAccessibleMenuItem::relationTo ( int child, const QAccessibleInterface * other, int otherChild ) const
{
    if (other->object() == owner()) {
        return Child;
    }
    Q_UNUSED(child)
    Q_UNUSED(other)
    Q_UNUSED(otherChild)
    // ###
    return Unrelated;
}

QAccessible::Role QAccessibleMenuItem::role(int /*child*/ ) const
{
    return m_action->isSeparator() ? Separator :MenuItem;
}

void QAccessibleMenuItem::setText ( Text /*t*/, int /*child*/, const QString & /*text */)
{

}

QAccessible::State QAccessibleMenuItem::state(int child ) const
{
    QAccessible::State s = Unavailable;

    if (child == 0) {
        s = Normal;
        QWidget *own = owner();

        if (own->testAttribute(Qt::WA_WState_Visible) == false || m_action->isVisible() == false) {
            s |= Invisible;
        }

        if (QMenu *menu = qobject_cast<QMenu*>(own)) {
            if (menu->activeAction() == m_action)
                s |= Focused;
#ifndef QT_NO_MENUBAR
        } else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
            if (menuBar->activeAction() == m_action)
                s |= Focused;
#endif
        }
        if (own->style()->styleHint(QStyle::SH_Menu_MouseTracking))
            s |= HotTracked;
        if (m_action->isSeparator() || !m_action->isEnabled())
            s |= Unavailable;
        if (m_action->isChecked())
            s |= Checked;
    } else if (child == 1) {
        QMenu *menu = m_action->menu();
        if (menu) {
            QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(menu);
            s = iface->state(0);
            delete iface;
        }
    }
    return s;
}

QString QAccessibleMenuItem::text ( Text t, int child ) const
{
    QString str;
    switch (t) {
    case Name:
        if (child == 0) {
            str = m_action->text();
        } else if (child == 1) {
            QMenu *m = m_action->menu();
            if (m)
                str = m->title();
        }
        str = qt_accStripAmp(str);
        break;
    case Accelerator:
        if (child == 0) {
#ifndef QT_NO_SHORTCUT
            QKeySequence key = m_action->shortcut();
            if (!key.isEmpty()) {
                str = key.toString();
            } else
#endif
            {
                str = qt_accHotKey(m_action->text());
            }
        }
        break;
    default:
        break;
    }
    return str;
}

int QAccessibleMenuItem::userActionCount ( int /*child*/ ) const
{
    return 0;
}


QAction *QAccessibleMenuItem::action() const
{
    return m_action;
}

QWidget *QAccessibleMenuItem::owner() const
{
    return m_owner;
}

#endif // QT_NO_MENU

QT_END_NAMESPACE

#endif // QT_NO_ACCESSIBILITY

