/****************************************************************************
**
** 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 "qdesktopwidget.h"
#include "qt_windows.h"
#include "qapplication_p.h"
#include <private/qsystemlibrary_p.h>
#include <qvector.h>
#include <limits.h>
#ifdef Q_WS_WINCE
#include <sipapi.h>
#endif
#include "qwidget_p.h"
#include "qdebug.h"

QT_BEGIN_NAMESPACE

class QDesktopWidgetPrivate : public QWidgetPrivate
{
public:
    QDesktopWidgetPrivate();
    ~QDesktopWidgetPrivate();

    static void init(QDesktopWidget *that);
    static void cleanup();
    static int screenCount;
    static int primaryScreen;

    static QVector<QRect> *rects;
    static QVector<QRect> *workrects;

    struct MONITORINFO
    {
        DWORD   cbSize;
        RECT    rcMonitor;
        RECT    rcWork;
        DWORD   dwFlags;
    };

    typedef BOOL (WINAPI *InfoFunc)(HMONITOR, MONITORINFO*);
    typedef BOOL (QT_WIN_CALLBACK *EnumProc)(HMONITOR, HDC, LPRECT, LPARAM);
    typedef BOOL (WINAPI *EnumFunc)(HDC, LPCRECT, EnumProc, LPARAM);

    static EnumFunc enumDisplayMonitors;
    static InfoFunc getMonitorInfo;
    static int refcount;
};

int QDesktopWidgetPrivate::screenCount = 1;
int QDesktopWidgetPrivate::primaryScreen = 0;
QDesktopWidgetPrivate::EnumFunc QDesktopWidgetPrivate::enumDisplayMonitors = 0;
QDesktopWidgetPrivate::InfoFunc QDesktopWidgetPrivate::getMonitorInfo = 0;
QVector<QRect> *QDesktopWidgetPrivate::rects = 0;
QVector<QRect> *QDesktopWidgetPrivate::workrects = 0;
static int screen_number = 0;
int QDesktopWidgetPrivate::refcount = 0;
#ifdef Q_WS_WINCE_WM
// Use SIP information, if available
// SipGetInfo is not supported by SSDK (no definition!). 
static inline void qt_get_sip_info(QRect &rect)
{
    SIPINFO sip;
    memset(&sip, 0, sizeof(SIPINFO));
    sip.cbSize = sizeof(SIPINFO);
    if (SipGetInfo(&sip))
        rect = QRect(QPoint(sip.rcVisibleDesktop.left, sip.rcVisibleDesktop.top),
        QPoint(sip.rcVisibleDesktop.right - 1, sip.rcVisibleDesktop.bottom - 1));
}
#endif


BOOL QT_WIN_CALLBACK enumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM)
{
    QDesktopWidgetPrivate::screenCount++;
    QDesktopWidgetPrivate::rects->resize(QDesktopWidgetPrivate::screenCount);
    QDesktopWidgetPrivate::workrects->resize(QDesktopWidgetPrivate::screenCount);
    // Get the MONITORINFO block
    QDesktopWidgetPrivate::MONITORINFO info;
    memset(&info, 0, sizeof(QDesktopWidgetPrivate::MONITORINFO));
    info.cbSize = sizeof(QDesktopWidgetPrivate::MONITORINFO);
    BOOL res = QDesktopWidgetPrivate::getMonitorInfo(hMonitor, &info);
    if (!res) {
        (*QDesktopWidgetPrivate::rects)[screen_number] = QRect();
        (*QDesktopWidgetPrivate::workrects)[screen_number] = QRect();
        return true;
    }

    // Fill list of rects
    RECT r = info.rcMonitor;
    QRect qr(QPoint(r.left, r.top), QPoint(r.right - 1, r.bottom - 1));
    (*QDesktopWidgetPrivate::rects)[screen_number] = qr;

    r = info.rcWork;
    qr = QRect(QPoint(r.left, r.top), QPoint(r.right - 1, r.bottom - 1));
    (*QDesktopWidgetPrivate::workrects)[screen_number] = qr;

    if (info.dwFlags & 0x00000001) //MONITORINFOF_PRIMARY
        QDesktopWidgetPrivate::primaryScreen = screen_number;

    ++screen_number;
    // Stop the enumeration if we have them all
    return true;
}

QDesktopWidgetPrivate::QDesktopWidgetPrivate()
{
    ++refcount;
}

void QDesktopWidgetPrivate::init(QDesktopWidget *that)
{
    if (rects)
        return;

    rects = new QVector<QRect>();
    workrects = new QVector<QRect>();
    screenCount = 0;

#ifndef Q_OS_WINCE
    QSystemLibrary user32Lib(QLatin1String("user32"));
    if (user32Lib.load()) {
        enumDisplayMonitors = (EnumFunc)user32Lib.resolve("EnumDisplayMonitors");
        getMonitorInfo = (InfoFunc)user32Lib.resolve("GetMonitorInfoW");
    }

    if (!enumDisplayMonitors || !getMonitorInfo) {
        screenCount = GetSystemMetrics(80);  // SM_CMONITORS
        rects->resize(screenCount);
        for (int i = 0; i < screenCount; ++i)
            rects->replace(i, that->rect());
        return;
    }
    // Calls enumCallback
    enumDisplayMonitors(0, 0, enumCallback, 0);
    enumDisplayMonitors = 0;
    getMonitorInfo = 0;
#else
    QSystemLibrary coreLib(QLatin1String("coredll"));
    if (coreLib.load()) {
        // CE >= 4.0 case
        enumDisplayMonitors = (EnumFunc)coreLib.resolve("EnumDisplayMonitors");
        getMonitorInfo = (InfoFunc)coreLib.resolve("GetMonitorInfo");
    }

    if ((!enumDisplayMonitors || !getMonitorInfo)) {
        screenCount = GetSystemMetrics(SM_CMONITORS);
        return;
    }

    if (!coreLib.isLoaded() || !enumDisplayMonitors || !getMonitorInfo) {
        rects->resize(screenCount);
        for (int i = 0; i < screenCount; ++i)
            (*rects)[i] = that->rect();

        RECT r;
        SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
        QRect qr = QRect(QPoint(r.left, r.top), QPoint(r.right - 1, r.bottom - 1));

#if defined(Q_WS_WINCE_WM)
        qt_get_sip_info(qr);
#endif

        workrects->resize(screenCount);
        for (int j = 0; j < screenCount; ++j)
            (*workrects)[j] = qr;
        return;
    }

    // Calls enumCallback
    enumDisplayMonitors(0, 0, enumCallback, 0);
    enumDisplayMonitors = 0;
    getMonitorInfo = 0;
#endif // Q_WS_WINCE
}

QDesktopWidgetPrivate::~QDesktopWidgetPrivate()
{
    if (!--refcount)
        cleanup();
}

void QDesktopWidgetPrivate::cleanup()
{
    screen_number = 0;
    screenCount = 1;
    primaryScreen = 0;
    enumDisplayMonitors = 0;
    getMonitorInfo = 0;
    delete rects;
    rects = 0;
    delete workrects;
    workrects = 0;
}

/*
    \omit
    Function is commented out in header
    \fn void *QDesktopWidget::handle(int screen) const

    Returns the window system handle of the display device with the
    index \a screen, for low-level access.  Using this function is not
    portable.

    The return type varies with platform; see qwindowdefs.h for details.

    \sa x11Display(), QPaintDevice::handle()
    \endomit
*/

QDesktopWidget::QDesktopWidget()
    : QWidget(*new QDesktopWidgetPrivate, 0, Qt::Desktop)
{
    setObjectName(QLatin1String("desktop"));
    QDesktopWidgetPrivate::init(this);
}

QDesktopWidget::~QDesktopWidget()
{
}

bool QDesktopWidget::isVirtualDesktop() const
{
    return true;
}

int QDesktopWidget::primaryScreen() const
{
    return d_func()->primaryScreen;
}

int QDesktopWidget::numScreens() const
{
    return d_func()->screenCount;
}

QWidget *QDesktopWidget::screen(int /* screen */)
{
    // It seems that a Qt::WType_Desktop cannot be moved?
    return this;
}

//
// MSVC 7.10 warns that d (the result of the expanded Q_D macro) as a local variable that is not referenced.
// Therefore, we ignore that warning with the following pragmas
// I've also tried to eliminate the macro, but to no use...
// We pop it further down
#ifdef Q_CC_MSVC
# pragma warning(push)
# pragma warning(disable : 4189)
#endif
const QRect QDesktopWidget::availableGeometry(int screen) const
{
    Q_D(const QDesktopWidget);
#ifdef Q_WS_WINCE_WM
    for(int i=0; i < d->workrects->size(); ++i)
        qt_get_sip_info((*d->workrects)[i]);
#endif
    if (screen < 0 || screen >= d->screenCount)
        screen = d->primaryScreen;

    return d->workrects->at(screen);
}

const QRect QDesktopWidget::screenGeometry(int screen) const
{
    const QDesktopWidgetPrivate *d = d_func();
    if (screen < 0 || screen >= d->screenCount)
        screen = d->primaryScreen;

    return d->rects->at(screen);
}

int QDesktopWidget::screenNumber(const QWidget *widget) const
{
    Q_D(const QDesktopWidget);
    if (!widget)
        return d->primaryScreen;

    QRect frame = widget->frameGeometry();
    if (!widget->isWindow())
        frame.moveTopLeft(widget->mapToGlobal(QPoint(0,0)));

    int maxSize = -1;
    int maxScreen = -1;

    for (int i = 0; i < d->screenCount; ++i) {
        QRect sect = d->rects->at(i).intersected(frame);
        int size = sect.width() * sect.height();
        if (size > maxSize && sect.width() > 0 && sect.height() > 0) {
            maxSize = size;
            maxScreen = i;
        }
    }

    return maxScreen;
}

int QDesktopWidget::screenNumber(const QPoint &point) const
{
    Q_D(const QDesktopWidget);

    int closestScreen = -1;
    int shortestDistance = INT_MAX;

    for (int i = 0; i < d->screenCount; ++i) {
        int thisDistance = d->pointToRect(point, d->rects->at(i));
        if (thisDistance < shortestDistance) {
            shortestDistance = thisDistance;
            closestScreen = i;
        }
    }

    return closestScreen;
}

void QDesktopWidget::resizeEvent(QResizeEvent *)
{
    Q_D(QDesktopWidget);
    const QVector<QRect> oldrects(*d->rects);
    const QVector<QRect> oldworkrects(*d->workrects);
    int oldscreencount = d->screenCount;

    QDesktopWidgetPrivate::cleanup();
    QDesktopWidgetPrivate::init(this);
#ifdef Q_WS_WINCE_WM
    for(int i=0; i < d->workrects->size(); ++i)
        qt_get_sip_info((*d->workrects)[i]);
#endif

    for (int i = 0; i < qMin(oldscreencount, d->screenCount); ++i) {
        const QRect oldrect = oldrects[i];
        const QRect newrect = d->rects->at(i);
        if (oldrect != newrect)
            emit resized(i);
    }

    for (int j = 0; j < qMin(oldscreencount, d->screenCount); ++j) {
        const QRect oldrect = oldworkrects[j];
        const QRect newrect = d->workrects->at(j);
        if (oldrect != newrect)
            emit workAreaResized(j);
    }

    if (oldscreencount != d->screenCount) {
        emit screenCountChanged(d->screenCount);
    }
}

#ifdef Q_CC_MSVC
# pragma warning(pop)
#endif

QT_END_NAMESPACE
