/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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, Digia gives you certain additional
** rights.  These rights are described in the Digia 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.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

/**
 * Copyright (C) 2023-2026 Linaro Limited (or its affiliates). All rights reserved.
 * Copyright (C) 2014-2023 Arm Limited (or its affiliates).
 * All rights reserved.
 */

#include <QStylePainter>
#include <QStyleOptionToolButton>

#include "flatcommandlinkbutton.h"

FlatCommandLinkButton::FlatCommandLinkButton(QWidget *parent) :
    WiderCommandLinkButton(parent)
{
}

void FlatCommandLinkButton::setSunkenColour(const QColor& sunkenColour)
{
    mSunkenColour = sunkenColour;
}

QColor FlatCommandLinkButton::sunkenColour() const
{
    return mSunkenColour;
}

void FlatCommandLinkButton::setRaisedColour(const QColor& raisedColour)
{
    mRaisedColour = raisedColour;
}

QColor FlatCommandLinkButton::raisedColour() const
{
    return mRaisedColour;
}

void FlatCommandLinkButton::setHoverColour(const QColor& hoverColour)
{
    mHoverColour = hoverColour;
}

QColor FlatCommandLinkButton::hoverColour() const
{
    return mHoverColour;
}

void FlatCommandLinkButton::setPressedColour(const QColor& pressedColour)
{
    mPressedColour = pressedColour;
}

QColor FlatCommandLinkButton::pressedColour() const
{
    return mPressedColour;
}

void FlatCommandLinkButton::setDisabledColour(const QColor& disabledColour)
{
    mDisabledColour = disabledColour;
}

QColor FlatCommandLinkButton::disabledColour() const
{
    return mDisabledColour;
}

void FlatCommandLinkButton::setLineColour(const QColor& lineColour)
{
    mLineColour = lineColour;
}

QColor FlatCommandLinkButton::lineColour() const
{
    return mLineColour;
}

void FlatCommandLinkButton::setTitleColour(const QColor& titleColour)
{
    mTitleColour = titleColour;
}

QColor FlatCommandLinkButton::titleColour() const
{
    return mTitleColour;
}

void FlatCommandLinkButton::setDescriptionColour(const QColor& descriptionColour)
{
    mDescriptionColour = descriptionColour;
}

QColor FlatCommandLinkButton::descriptionColour() const
{
    return mDescriptionColour;
}

/*! \reimp */
QSize FlatCommandLinkButton::sizeHint() const
{
#ifdef Q_OS_MACOS
    return WiderCommandLinkButton::sizeHint();
#else
    const QSize size(QCommandLinkButton::sizeHint());
    if (description().isEmpty())
        return size;
    QFontMetrics fm(descriptionFont());
    const int textWidth = fm.horizontalAdvance(description());
    const int textOffset = icon().actualSize(iconSize()).width() + leftMargin() + 7;
    const int descriptionWidth = textWidth + textOffset + rightMargin();
    return QSize(qMax(descriptionWidth, size.width()), size.height());
#endif
}

void FlatCommandLinkButton::paintEvent(QPaintEvent * event)
{
    QWidget::paintEvent(event);
    
    QStylePainter p(this);
    QStyleOptionButton option;
    initStyleOption(&option);
    
    p.save();
    
    QStyle::State bflags = option.state;

    QColor colour = mRaisedColour;
    bool drawLine = false;
    if ((bflags & QStyle::State_Sunken) &&
        (bflags & QStyle::State_MouseOver) &&
        !(bflags & QStyle::State_On) &&
        mPressedColour.isValid()) {
        colour = mPressedColour;
        drawLine = true;
    } else  if (bflags & (QStyle::State_Sunken | QStyle::State_On)) {
        colour = mSunkenColour;
        drawLine = true;
    } else if (!(bflags & QStyle::State_Enabled)) {
        if (mDisabledColour.isValid())
            colour = mDisabledColour;
    } else if ((bflags & QStyle::State_MouseOver)) {
        if (mHoverColour.isValid())
            colour = mHoverColour;
        drawLine = true;
    }

    if (colour.isValid())
        p.fillRect(QRect(0, 0, width(), height()), colour);
    if (drawLine && mLineColour.isValid()) {
        p.setPen(mLineColour);
        p.drawLine(0, height() - 1, width(), height() - 1);
    }

    //Enable command link appearance on Vista
    option.features |= QStyleOptionButton::CommandLinkButton;
    option.text = QString();
    option.icon = QIcon(); //we draw this ourselves
    QSize pixmapSize = icon().actualSize(iconSize());

    int vOffset = isDown() ? qMax(1, style()->pixelMetric(QStyle::PM_ButtonShiftVertical)) : 0;
    int hOffset = isDown() ? qMax(1, style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal)) : 0;

    //Draw icon
    //p.drawControl(QStyle::CE_PushButton, option);
    if (!icon().isNull())
        p.drawPixmap(leftMargin() + hOffset, topMargin() + vOffset,
        icon().pixmap(pixmapSize, isEnabled() ? QIcon::Normal : QIcon::Disabled,
                                  isChecked() ? QIcon::On : QIcon::Off));

    //Draw title
    if (mTitleColour.isValid())
        option.palette.setColor(QPalette::ButtonText, mTitleColour);

    int textflags = Qt::TextShowMnemonic;
    if (!style()->styleHint(QStyle::SH_UnderlineShortcut, &option, this))
        textflags |= Qt::TextHideMnemonic;

    p.setFont(titleFont());
    p.drawItemText(titleRect().translated(hOffset, vOffset),
                    textflags, option.palette, isEnabled(), text(), QPalette::ButtonText);

    //Draw description
    textflags |= Qt::TextWordWrap | Qt::ElideRight;
    if (mDescriptionColour.isValid())
        option.palette.setColor(QPalette::ButtonText, mDescriptionColour);
    p.setFont(descriptionFont());
    p.drawItemText(descriptionRect().translated(hOffset, vOffset), textflags,
                    option.palette, isEnabled(), description(), QPalette::ButtonText);
    p.restore();
}

void FlatCommandLinkButton::nextCheckState()
{
    // do nothing - these buttons are not togglable, except programatically
}

QFont FlatCommandLinkButton::titleFont() const
{
    QFont font = this->font();
    font.setBold(true);
    font.setPointSizeF(9.0);
    return font;
}

QFont FlatCommandLinkButton::descriptionFont() const
{
    QFont font = this->font();
    font.setPointSizeF(9.0);
    return font;
}

QRect FlatCommandLinkButton::titleRect() const
{
    QRect r = rect().adjusted(textOffset(), topMargin(), -rightMargin(), 0);
    if (description().isEmpty())
    {
        QFontMetrics fm(titleFont());
        r.setTop(r.top() + qMax(0, (icon().actualSize(iconSize()).height()
                 - fm.height()) / 2));
    }

    return r;
}

QRect FlatCommandLinkButton::descriptionRect() const
{
    return rect().adjusted(textOffset(), descriptionOffset(),
                           -rightMargin(), 0);
}

int FlatCommandLinkButton::textOffset() const
{
    return icon().actualSize(iconSize()).width() + leftMargin() + 6;
}

int FlatCommandLinkButton::descriptionOffset() const
{
    QFontMetrics fm(titleFont());
    return topMargin() + fm.height();
}
