/***********************************************************************************
* Run Command: Simple plasmoid to run commands with support for runners.
* Copyright (C) 2008 - 2012 Michal Dutkiewicz aka Emdek <emdeck@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*
***********************************************************************************/

#include "RunCommandItem.h"

#include <QtGui/QHBoxLayout>
#include <QtGui/QVBoxLayout>

#include <KIcon>
#include <KMenu>
#include <KLocale>

#include <Plasma/Theme>
#include <Plasma/PaintUtils>

RunCommandItem::RunCommandItem(const Plasma::QueryMatch &match, QList<QAction*> actions, QWidget *parent) : QWidget(parent),
    m_match(match),
    m_actions(actions),
    m_optionsWidget(NULL),
    m_iconLabel(new QLabel(this)),
    m_optionsButton(NULL)
{
    QLabel *titleLabel = new QLabel(match.subtext().isEmpty()?match.text():QString("%1<br /><i>%2</i>").arg(match.text()).arg(match.subtext()), this);
    titleLabel->setTextInteractionFlags(Qt::NoTextInteraction);
    titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
    titleLabel->setAlignment(Qt::AlignTop);
    titleLabel->setToolTip(match.subtext().isEmpty()?QString("<b>%1</b>").arg(match.text()):QString("<b>%1</b><br /><i>%2</i>").arg(match.text()).arg(match.subtext()));

    m_iconLabel->setPixmap(match.icon().pixmap(32, 32));
    m_iconLabel->setEnabled(false);

    QHBoxLayout *horizontalLayout = new QHBoxLayout;
    horizontalLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    horizontalLayout->addWidget(m_iconLabel);
    horizontalLayout->addWidget(titleLabel);

    if (match.hasConfigurationInterface())
    {
        m_optionsButton = new QToolButton(this);
        m_optionsButton->setIcon(KIcon("configure"));
        m_optionsButton->setToolTip(i18n("Configure..."));
        m_optionsButton->setAutoRaise(true);
        m_optionsButton->hide();

        horizontalLayout->addWidget(m_optionsButton);
        horizontalLayout->setAlignment(m_optionsButton, (Qt::AlignRight | Qt::AlignBottom));

        connect(m_optionsButton, SIGNAL(clicked()), this, SLOT(toggleOptions()));
    }

    QVBoxLayout *verticalLayout = new QVBoxLayout(this);
    verticalLayout->addLayout(horizontalLayout);

    setFocusPolicy(Qt::StrongFocus);
}

void RunCommandItem::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing);
    painter.setClipRect(event->rect());

    if (hasFocus() || (m_optionsWidget && m_optionsWidget->isVisible()))
    {
        QPainterPath path = Plasma::PaintUtils::roundedRectangle(rect(), 5);

        painter.setOpacity((m_optionsWidget && m_optionsWidget->isVisible())?0.7:0.5);
        painter.setPen(Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor));
        painter.fillPath(path, Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor).lighter());
        painter.drawPath(path);

        m_iconLabel->setEnabled(true);
    }
    else
    {
        m_iconLabel->setEnabled(false);
    }
}

void RunCommandItem::focusInEvent(QFocusEvent *event)
{
    Q_UNUSED(event)

    if (m_optionsButton)
    {
        m_optionsButton->show();
    }

    update();
}

void RunCommandItem::focusOutEvent(QFocusEvent *event)
{
    Q_UNUSED(event)

    if (m_optionsButton)
    {
        m_optionsButton->hide();
    }

    update();
}

void RunCommandItem::enterEvent(QEvent *event)
{
    Q_UNUSED(event)

    if (m_optionsButton)
    {
        m_optionsButton->show();
    }

    setFocus();
}

void RunCommandItem::leaveEvent(QEvent *event)
{
    Q_UNUSED(event)

    if (m_optionsButton && !hasFocus())
    {
        m_optionsButton->hide();
    }
}

void RunCommandItem::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        emit run(m_match);
    }
}

void RunCommandItem::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)
    {
        if (m_match.hasConfigurationInterface() && event->modifiers() & Qt::ShiftModifier)
        {
            toggleOptions();
        }
        else
        {
            emit run(m_match);
        }

        event->accept();
    }
    else
    {
        event->ignore();
    }
}

void RunCommandItem::contextMenuEvent(QContextMenuEvent *event)
{
    Q_UNUSED(event)

    if (m_actions.count())
    {
        KMenu menu;
        menu.addActions(m_actions);
        menu.exec();

        event->accept();
    }
}

void RunCommandItem::toggleOptions()
{
    if (!m_optionsWidget)
    {
        m_optionsWidget = new QWidget(this);

        layout()->addWidget(m_optionsWidget);

        m_match.createConfigurationInterface(m_optionsWidget);

        m_optionsWidget->adjustSize();
        m_optionsWidget->hide();
    }

    m_optionsWidget->setVisible(!m_optionsWidget->isVisible());

    emit sizeChanged();
}
