/*
  QtCurve (C) Craig Drummond, 2007 - 2010 craig.p.drummond@gmail.com

  ----

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public
  License version 2 as published by the Free Software Foundation.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; see the file COPYING.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.
*/

#include "shortcuthandler.h"
#include <tqpopupmenu.h>
#include <tqapplication.h>
#include <tqobjectlist.h>
#include <tqmainwindow.h>
#include <tqdialog.h>
#include <tqstyle.h>

ShortcutHandler::ShortcutHandler(TQObject *parent)
               : TQObject(parent)
               , itsAltDown(false)
{
}

ShortcutHandler::~ShortcutHandler()
{
}

bool ShortcutHandler::hasSeenAlt(const TQWidget *widget) const
{
    if(widget && !widget->isEnabled())
        return false;

    if(::tqqt_cast<const TQPopupMenu *>(widget))
        return itsOpenMenus.count() && itsOpenMenus.last()==widget;
    else
        return itsOpenMenus.isEmpty() &&  itsSeenAlt.contains((TQWidget *)(widget->topLevelWidget()));
/*    return false;
    {
        const TQWidget *w=widget;

        while(w)
        {
            if(itsSeenAlt.contains((TQWidget *)w))
                return true;
            w=w->parentWidget();
        }
    }
    if(itsHandlePopupsOnly)
        return false;
    widget = widget->topLevelWidget();
    return itsSeenAlt.contains((TQWidget *)widget);*/
}

bool ShortcutHandler::showShortcut(const TQWidget *widget) const
{
    return itsAltDown && hasSeenAlt(widget);
}

void ShortcutHandler::widgetDestroyed(TQObject *o)
{
    itsUpdated.remove(static_cast<TQWidget *>(o));
    itsOpenMenus.remove(static_cast<TQWidget *>(o));
}

void ShortcutHandler::updateWidget(TQWidget *w)
{
    if(!itsUpdated.contains(w))
    {
        connect(w, SIGNAL(destroyed(TQObject *)), this, SLOT(widgetDestroyed(TQObject *)));
        itsUpdated.append(w);
        w->repaint(TRUE);
    }
}

void ShortcutHandler::setSeenAlt(TQWidget *w)
{
    if(!itsSeenAlt.contains(w))
        itsSeenAlt.append(w);
}

bool ShortcutHandler::eventFilter(TQObject *o, TQEvent *e)
{
    if (!o->isWidgetType())
        return TQObject::eventFilter(o, e);

    TQWidget *widget = ::tqqt_cast<TQWidget*>(o);
    switch(e->type())
    {
        case TQEvent::KeyPress:
            if (Key_Alt==((TQKeyEvent*)e)->key())
            {
                itsAltDown = true;

                if(::tqqt_cast<TQPopupMenu *>(widget))
                {
                    setSeenAlt(widget);
                    updateWidget(widget);
                    if(widget->parentWidget() && widget->parentWidget()->topLevelWidget())
                        itsSeenAlt.append(widget->parentWidget()->topLevelWidget());
                }
                else
                {
                    widget = widget->topLevelWidget();
                    setSeenAlt(widget);

                    // Alt has been pressed - find all widgets that care
                    TQObjectList *l = widget->queryList("TQWidget");
                    TQObjectListIt it( *l );
                    TQWidget *w;
                    while ((w = (TQWidget *)it.current()) != 0)
                    {
                        ++it;
                        if (!(w->isTopLevel() || !w->isVisible())) // || w->style().styleHint(QStyle::SH_UnderlineAccelerator, w)))
                            updateWidget(w);
                    }
                    delete l;
                }
            }
            break;
        case TQEvent::WindowDeactivate:
        case TQEvent::KeyRelease:
            if (TQEvent::WindowDeactivate==e->type() || Key_Alt==static_cast<TQKeyEvent*>(e)->key())
            {
                itsAltDown = false;
                TQValueList<TQWidget *>::const_iterator it(itsUpdated.begin()),
                                                      end(itsUpdated.end());

                for (; it!=end; ++it)
                    (*it)->repaint(TRUE);
                if(!itsUpdated.contains(widget))
                    widget->repaint(TRUE);
                itsSeenAlt.clear();
                itsUpdated.clear();
            }
            break;
        case TQEvent::Show:
            if(::tqqt_cast<TQPopupMenu *>(widget))
            {
                TQWidget *prev=itsOpenMenus.count() ? itsOpenMenus.last() : 0L;
                itsOpenMenus.append(widget);
                if(itsAltDown && prev)
                    prev->repaint(TRUE);
                connect(widget, SIGNAL(destroyed(TQObject *)), this, SLOT(widgetDestroyed(TQObject *)));
            }
            break;
        case TQEvent::Hide:
            if(::tqqt_cast<TQPopupMenu *>(widget))
            {
                itsSeenAlt.remove(widget);
                itsUpdated.remove(widget);
                itsOpenMenus.remove(widget);
                if(itsAltDown)
                {
                    if(itsOpenMenus.count())
                        itsOpenMenus.last()->repaint(TRUE);
                    else if(widget->parentWidget() && widget->parentWidget()->topLevelWidget())
                        widget->parentWidget()->topLevelWidget()->repaint(TRUE);
                }
            }
            break;
        case TQEvent::Close:
            // Reset widget when closing
            itsSeenAlt.remove(widget);
            itsUpdated.remove(widget);
            itsSeenAlt.remove(widget->topLevelWidget());
            itsOpenMenus.remove(widget);
            if(itsAltDown && itsOpenMenus.count())
                itsOpenMenus.last()->repaint(TRUE);
            break;
            break;
        default:
            break;
    }
    return TQObject::eventFilter(o, e);
}

#include "shortcuthandler.moc"