/****************************************************************************
**
** 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 QtGui module 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 <qapplication.h>
#include <qwidget.h>
#include <qpainter.h>
#include <qdrawutil.h>
#include "qdecorationstyled_qws.h"
#include "qstyle.h"
#include "qstyleoption.h"
#include "qpaintengine.h"

QT_BEGIN_NAMESPACE

#if !defined(QT_NO_QWS_DECORATION_STYLED) || defined(QT_PLUGIN)

QDecorationStyled::QDecorationStyled()
    : QDecorationDefault()
{
}

QDecorationStyled::~QDecorationStyled()
{
}

int QDecorationStyled::titleBarHeight(const QWidget *widget)
{
    QStyleOptionTitleBar opt;
    opt.subControls = QStyle::SC_TitleBarLabel
                      | QStyle::SC_TitleBarSysMenu
                      | QStyle::SC_TitleBarNormalButton
                      | QStyle::SC_TitleBarContextHelpButton
                      | QStyle::SC_TitleBarMinButton
                      | QStyle::SC_TitleBarMaxButton
                      | QStyle::SC_TitleBarCloseButton;
    opt.titleBarFlags = widget->windowFlags();
    opt.direction = QApplication::layoutDirection();
    opt.text = windowTitleFor(widget);
    opt.icon = widget->windowIcon();
    opt.rect = widget->rect();

    QStyle *style = QApplication::style();
    if (!style)
        return 18;

    return style->pixelMetric(QStyle::PM_TitleBarHeight, &opt, 0);
}

bool QDecorationStyled::paint(QPainter *painter, const QWidget *widget, int decorationRegion,
                            DecorationState state)
{
    if (decorationRegion == None)
        return false;

    bool isActive = (widget == qApp->activeWindow());
    QPalette pal = qApp->palette();
    //ideally, the difference between Active and Inactive should be enough, so we shouldn't need to test this
    if (!isActive) {
        //pal.setCurrentColorGroup(QPalette::Disabled); //Can't do this either, because of palette limitations
        //copied from Q3TitleBar:
	pal.setColor(QPalette::Inactive, QPalette::Highlight,
		     pal.color(QPalette::Inactive, QPalette::Dark));
        pal.setColor(QPalette::Inactive, QPalette::Base,
                      pal.color(QPalette::Inactive, QPalette::Dark));
        pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
                      pal.color(QPalette::Inactive, QPalette::Window));
    }

    Qt::WindowFlags flags = widget->windowFlags();
    bool hasBorder = !widget->isMaximized();
    bool hasTitle = flags & Qt::WindowTitleHint;
    bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
    bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
    bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
    bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;

    bool paintAll = (DecorationRegion(decorationRegion) == All);
    bool handled = false;

    QStyle *style = QApplication::style();

    // In the case of a borderless title bar, the title bar must be expanded one
    // borderWidth to the left, right and up.
    bool noTitleBorder = style->styleHint(QStyle::SH_TitleBar_NoBorder, 0, widget);
    int borderWidth = style->pixelMetric(QStyle::PM_MDIFrameWidth, 0, 0);
    int titleHeight = titleBarHeight(widget) + (noTitleBorder ? borderWidth : 0);
    int titleExtra = noTitleBorder ? borderWidth : 0;

    if ((paintAll || decorationRegion & Borders) && state == Normal && hasBorder) {
        QRegion newClip = painter->clipRegion();
        if (hasTitle) { // reduce flicker
            QRect rect(widget->rect());
            QRect r(rect.left() - titleExtra, rect.top() - titleHeight,
                    rect.width() + 2 * titleExtra, titleHeight);
            newClip -= r;
        }
        if (!newClip.isEmpty()) {
            QRect br = QDecoration::region(widget).boundingRect();
            painter->save();
            painter->setClipRegion(newClip);

            QStyleOptionFrame opt;
            opt.palette = pal;
            opt.rect = br;
            opt.lineWidth = borderWidth;

            if (isActive)
                opt.state |= QStyle::State_Active;
            bool porterDuff = painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff);
            if (porterDuff)
                painter->setCompositionMode(QPainter::CompositionMode_Source);
            painter->fillRect(br, pal.window());
            if (porterDuff)
                painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
            style->drawPrimitive(QStyle::PE_FrameWindow, &opt, painter, 0);
            painter->restore();

            decorationRegion &= (~Borders);
            handled |= true;
        }
    }

    if (hasTitle) {
        painter->save();

        QStyleOptionTitleBar opt;
        opt.subControls = (decorationRegion & Title
                              ? QStyle::SC_TitleBarLabel : QStyle::SubControl(0))
                          | (decorationRegion & Menu
                              ? QStyle::SC_TitleBarSysMenu : QStyle::SubControl(0))
                          | (decorationRegion & Help
                              ? QStyle::SC_TitleBarContextHelpButton : QStyle::SubControl(0))
                          | (decorationRegion & Minimize
                              ? QStyle::SC_TitleBarMinButton : QStyle::SubControl(0))
                          | (decorationRegion & Maximize
                              ? QStyle::SC_TitleBarMaxButton : QStyle::SubControl(0))
                          | (decorationRegion & (Minimize | Maximize)
                              ? QStyle::SC_TitleBarNormalButton : QStyle::SubControl(0))
                          | (decorationRegion & Close
                              ? QStyle::SC_TitleBarCloseButton : QStyle::SubControl(0));
        opt.titleBarFlags = widget->windowFlags();
        opt.titleBarState = widget->windowState();
        if (isActive)
            opt.titleBarState |= QStyle::State_Active;
        opt.text = windowTitleFor(widget);
        opt.icon = widget->windowIcon();
        opt.palette = pal;
        opt.rect = QRect(widget->rect().x() - titleExtra, -titleHeight,
                         widget->rect().width() + 2 * titleExtra, titleHeight);

        if (paintAll) {
            painter->setClipRegion(opt.rect);
        } else {
            const QRect widgetRect = widget->rect();
            QRegion newClip = opt.rect;
            if (!(decorationRegion & Menu) && hasSysMenu)
                newClip -= region(widget, widgetRect, Menu);
            if (!(decorationRegion & Title) && hasTitle)
                newClip -= region(widget, widgetRect, Title);
            if (!(decorationRegion & Help) && hasContextHelp)
                newClip -= region(widget, widgetRect, Help);
            if (!(decorationRegion & Minimize) && hasMinimize)
                newClip -= region(widget, widgetRect, Minimize);
            if (!(decorationRegion & Maximize) && hasMaximize)
                newClip -= region(widget, widgetRect, Maximize);
            if (!(decorationRegion & (Minimize | Maximize)) && (hasMaximize | hasMinimize))
                newClip -= region(widget, widgetRect, Normal);
            if (!(decorationRegion & Close))
                newClip -= region(widget, widgetRect, Close);
            painter->setClipRegion(newClip);
        }

        if (state == Pressed)
            opt.activeSubControls = opt.subControls;

        style->drawComplexControl(QStyle::CC_TitleBar, &opt, painter, 0);
        painter->restore();

        decorationRegion &= ~(Title | Menu | Help | Normalize | Minimize | Maximize | Close);
        handled |= true;
    }

    return handled;
}

QRegion QDecorationStyled::region(const QWidget *widget, const QRect &rect, int decorationRegion)
{
    QStyle *style = QApplication::style();

    // In the case of a borderless title bar, the title bar must be expanded one
    // borderWidth to the left, right and up.
    bool noTitleBorder = style->styleHint(QStyle::SH_TitleBar_NoBorder, 0, widget);
    int borderWidth = style->pixelMetric(QStyle::PM_MDIFrameWidth, 0, 0);
    int titleHeight = titleBarHeight(widget) + (noTitleBorder ? borderWidth : 0);
    int titleExtra = noTitleBorder ? borderWidth : 0;

    QRect inside = QRect(rect.x() - titleExtra, rect.top() - titleHeight,
                         rect.width() + 2 * titleExtra, titleHeight);

    Qt::WindowFlags flags = widget->windowFlags();
    bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
    bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
    bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
    bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;

    QStyleOptionTitleBar opt;
    opt.subControls = QStyle::SC_TitleBarLabel
                      | QStyle::SC_TitleBarSysMenu
                      | QStyle::SC_TitleBarNormalButton
                      | QStyle::SC_TitleBarMinButton
                      | QStyle::SC_TitleBarMaxButton
                      | QStyle::SC_TitleBarCloseButton;
    opt.titleBarFlags = widget->windowFlags();
    opt.direction = QApplication::layoutDirection();
    opt.text = windowTitleFor(widget);
    opt.icon = widget->windowIcon();
    opt.rect = inside;

    QRegion region;
    switch (decorationRegion) {
    case Title:
        region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                       QStyle::SC_TitleBarLabel, 0);
        break;
    case Menu:
        if (hasSysMenu)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarSysMenu, 0);
        break;
    case Help:
        if (hasContextHelp)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarContextHelpButton,
                                           0);
        break;
    case Normalize:
        if (hasMaximize | hasMinimize)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarNormalButton,
                                           0);
        break;
    case Minimize:
        if (hasMinimize)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarMinButton,
                                           0);
        break;
    case Maximize:
        if (hasMaximize)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarMaxButton,
                                           0);
        break;
    case Close:
        region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                       QStyle::SC_TitleBarCloseButton, 0);
        break;

    default:
        region = QDecorationDefault::region(widget, rect, decorationRegion);
    }

    opt.rect = QRect(rect.x() - titleExtra, rect.top() - titleHeight,
                         rect.width() + 2 * titleExtra,
                         rect.height() + titleHeight + titleExtra);

    QStyleHintReturnMask mask;
    style->styleHint(QStyle::SH_WindowFrame_Mask, &opt, 0, &mask);

    return (mask.region.isEmpty() ? region : (region & mask.region));
}

#endif // QT_NO_QWS_DECORATION_STYLED

QT_END_NAMESPACE
