/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "deviceskin.h"

#include <QtCore/qnamespace.h>
#include <QtWidgets/QApplication>
#include <QtGui/QBitmap>
#include <QtGui/QPixmap>
#include <QtGui/QPainter>
#include <QtCore/QTextStream>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtGui/QImage>
#include <QtCore/QTimer>
#include <QtCore/QDir>
#include <QtCore/QRegularExpression>
#include <QtGui/QMouseEvent>
#include <QtCore/QDebug>

#ifdef TEST_SKIN
#  include <QtGui/QMainWindow>
#  include <QtGui/QDialog>
#  include <QtGui/QDialogButtonBox>
#  include <QtGui/QHBoxLayout>
#endif

QT_BEGIN_NAMESPACE

namespace {
    enum { joydistance = 10, key_repeat_period = 50, key_repeat_delay = 500 };
    enum { debugDeviceSkin = 0 };
}

static void parseRect(const QString &value, QRect *rect) {
    const auto l = value.splitRef(QLatin1Char(' '));
    rect->setRect(l[0].toInt(), l[1].toInt(), l[2].toInt(), l[3].toInt());
}

static QString msgImageNotLoaded(const QString &f)        {
    return DeviceSkin::tr("The image file '%1' could not be loaded.").arg(f);
}

// ------------ DeviceSkinButtonArea
QDebug &operator<<(QDebug &str, const DeviceSkinButtonArea &a)
{

    str << "Area: " <<  a.name << " keyCode=" << a.keyCode << " area=" <<  a.area
        << " text=" << a.text << " activeWhenClosed=" << a.activeWhenClosed;
    return str;
}

// ------------  DeviceSkinParameters

QDebug operator<<(QDebug str, const DeviceSkinParameters &p)
{
    str << "Images " << p.skinImageUpFileName << ','
        << p.skinImageDownFileName<< ',' << p.skinImageClosedFileName
        <<  ',' <<  p.skinCursorFileName <<"\nScreen: " << p.screenRect
        << " back: " << p.backScreenRect << " closed: " << p.closedScreenRect
        << " cursor: " << p.cursorHot << " Prefix: " <<  p.prefix
        << " Joystick: " << p.joystick << " MouseHover" << p.hasMouseHover;
    const int numAreas = p.buttonAreas.size();
    for (int i = 0; i < numAreas; i++)
        str <<  p.buttonAreas[i];
    return str;
}

QSize DeviceSkinParameters::secondaryScreenSize() const
{
    return backScreenRect.isNull() ?  closedScreenRect .size(): backScreenRect.size();
}

bool DeviceSkinParameters::hasSecondaryScreen() const
{
    return secondaryScreenSize() != QSize(0, 0);
}

bool DeviceSkinParameters::read(const QString &skinDirectory,  ReadMode rm,  QString *errorMessage)
{
    // Figure out the name. remove ending '/' if present
    QString skinFile = skinDirectory;
    if (skinFile.endsWith(QLatin1Char('/')))
        skinFile.truncate(skinFile.length() - 1);

    QFileInfo fi(skinFile);
    QString fn;
    if ( fi.isDir() ) {
        prefix = skinFile;
        prefix += QLatin1Char('/');
        fn = prefix;
        fn += fi.baseName();
        fn += QLatin1String(".skin");
    } else if (fi.isFile()){
        fn = skinFile;
        prefix = fi.path();
        prefix += QLatin1Char('/');
    } else {
        *errorMessage =  DeviceSkin::tr("The skin directory '%1' does not contain a configuration file.").arg(skinDirectory);
        return false;
    }
    QFile f(fn);
    if (!f.open(QIODevice::ReadOnly )) {
        *errorMessage =  DeviceSkin::tr("The skin configuration file '%1' could not be opened.").arg(fn);
        return false;
    }
    QTextStream ts(&f);
    const bool rc = read(ts, rm, errorMessage);
    if (!rc)
        *errorMessage =  DeviceSkin::tr("The skin configuration file '%1' could not be read: %2").arg(fn).arg(*errorMessage);
    return rc;
}
bool DeviceSkinParameters::read(QTextStream &ts, ReadMode rm, QString *errorMessage)
{
    QStringList closedAreas;
    QStringList toggleAreas;
    QStringList toggleActiveAreas;
    int nareas = 0;
    screenDepth = 0;
    QString mark;
    ts >> mark;
    hasMouseHover = true; // historical default
    if ( mark == QLatin1String("[SkinFile]") ) {
        const QString UpKey = QLatin1String("Up");
        const QString DownKey = QLatin1String("Down");
        const QString ClosedKey = QLatin1String("Closed");
        const QString ClosedAreasKey = QLatin1String("ClosedAreas");
        const QString ScreenKey = QLatin1String("Screen");
        const QString ScreenDepthKey = QLatin1String("ScreenDepth");
        const QString BackScreenKey = QLatin1String("BackScreen");
        const QString ClosedScreenKey = QLatin1String("ClosedScreen");
        const QString CursorKey = QLatin1String("Cursor");
        const QString AreasKey = QLatin1String("Areas");
        const QString ToggleAreasKey = QLatin1String("ToggleAreas");
        const QString ToggleActiveAreasKey = QLatin1String("ToggleActiveAreas");
        const QString HasMouseHoverKey = QLatin1String("HasMouseHover");
        // New
        while (!nareas) {
            QString line = ts.readLine();
            if ( line.isNull() )
                break;
            if ( line[0] != QLatin1Char('#') && !line.isEmpty() ) {
                int eq = line.indexOf(QLatin1Char('='));
                if ( eq >= 0 ) {
                    const QString key = line.left(eq);
                    eq++;
                    while (eq<line.length()-1 && line[eq].isSpace())
                        eq++;
                    const QString value = line.mid(eq);
                    if ( key == UpKey ) {
                        skinImageUpFileName = value;
                    } else if ( key == DownKey ) {
                        skinImageDownFileName = value;
                    } else if ( key ==  ClosedKey ) {
                        skinImageClosedFileName = value;
                    } else if ( key == ClosedAreasKey ) {
                        closedAreas = value.split(QLatin1Char(' '));
                    } else if ( key == ScreenKey ) {
                        parseRect( value, &screenRect);
                    } else if ( key == ScreenDepthKey ) {
                        screenDepth = value.toInt();
                    } else if ( key == BackScreenKey ) {
                        parseRect(value, &backScreenRect);
                    } else if ( key == ClosedScreenKey ) {
                        parseRect( value, &closedScreenRect );
                    } else if ( key == CursorKey ) {
                        QStringList l = value.split(QLatin1Char(' '));
                        skinCursorFileName = l[0];
                        cursorHot = QPoint(l[1].toInt(),l[2].toInt());
                    } else if ( key == AreasKey ) {
                        nareas = value.toInt();
                    } else if ( key == ToggleAreasKey ) {
                        toggleAreas = value.split(QLatin1Char(' '));
                    } else if ( key == ToggleActiveAreasKey ) {
                        toggleActiveAreas = value.split(QLatin1Char(' '));
                    } else if ( key == HasMouseHoverKey ) {
                        hasMouseHover = value == QLatin1String("true") || value == QLatin1String("1");
                    }
                } else {
                    *errorMessage =  DeviceSkin::tr("Syntax error: %1").arg(line);
                    return false;
                }
            }
        }
    } else {
        // Old
        skinImageUpFileName = mark;
        QString s;
        int x,y,w,h,na;
        ts >> s >> x >> y >> w >> h >> na;
        skinImageDownFileName = s;
        screenRect.setRect(x, y, w, h);
        nareas = na;
    }
    // Done for short mode
    if (rm ==  ReadSizeOnly)
        return true;
    //  verify skin files exist
    skinImageUpFileName.insert(0, prefix);
    if (!QFile(skinImageUpFileName).exists()) {
        *errorMessage =  DeviceSkin::tr("The skin \"up\" image file '%1' does not exist.").arg(skinImageUpFileName);
        return false;
    }
    if (!skinImageUp.load(skinImageUpFileName)) {
        *errorMessage = msgImageNotLoaded(skinImageUpFileName);
        return false;
    }

    skinImageDownFileName.insert(0, prefix);
    if (!QFile(skinImageDownFileName).exists()) {
        *errorMessage =  DeviceSkin::tr("The skin \"down\" image file '%1' does not exist.").arg(skinImageDownFileName);
        return false;
    }
    if (!skinImageDown.load(skinImageDownFileName)) {
        *errorMessage = msgImageNotLoaded(skinImageDownFileName);
        return false;
    }

    if (!skinImageClosedFileName.isEmpty()) {
        skinImageClosedFileName.insert(0, prefix);
        if (!QFile(skinImageClosedFileName).exists()) {
            *errorMessage =  DeviceSkin::tr("The skin \"closed\" image file '%1' does not exist.").arg(skinImageClosedFileName);
            return false;
        }
        if (!skinImageClosed.load(skinImageClosedFileName)) {
            *errorMessage = msgImageNotLoaded(skinImageClosedFileName);
            return false;
        }
    }

    if (!skinCursorFileName.isEmpty()) {
        skinCursorFileName.insert(0, prefix);
        if (!QFile(skinCursorFileName).exists()) {
            *errorMessage =  DeviceSkin::tr("The skin cursor image file '%1' does not exist.").arg(skinCursorFileName);
            return false;
        }
        if (!skinCursor.load(skinCursorFileName)) {
            *errorMessage = msgImageNotLoaded(skinCursorFileName);
            return false;
        }
    }

    // read areas
    if (!nareas)
        return true;
    buttonAreas.reserve(nareas);

    int i = 0;
    ts.readLine(); // eol
    joystick = -1;
    const QString Joystick = QLatin1String("Joystick");
    const QRegularExpression splitRe(QLatin1String("[ \t][ \t]*"));
    Q_ASSERT(splitRe.isValid());
    while (i < nareas && !ts.atEnd() ) {
        buttonAreas.push_back(DeviceSkinButtonArea());
        DeviceSkinButtonArea &area = buttonAreas.back();
        const QString line = ts.readLine();
        if ( !line.isEmpty() && line[0] != QLatin1Char('#') ) {
            const QStringList tok = line.split(splitRe);
            if ( tok.count()<6 ) {
                *errorMessage =  DeviceSkin::tr("Syntax error in area definition: %1").arg(line);
                return false;
            } else {
                area.name = tok[0];
                QString k = tok[1];
                if ( k.left(2).toLower() == QLatin1String("0x")) {
                    area.keyCode = k.mid(2).toInt(0,16);
                } else {
                    area.keyCode = k.toInt();
                }

                int p=0;
                for (int j=2; j < tok.count() - 1; ) {
                    const int x = tok[j++].toInt();
                    const int y = tok[j++].toInt();
                    area.area.putPoints(p++,1,x,y);
                }

                const QChar doubleQuote = QLatin1Char('"');
                if ( area.name[0] == doubleQuote && area.name.endsWith(doubleQuote)) {
                    area.name.truncate(area.name.size() - 1);
                    area.name.remove(0, 1);
                }
                if ( area.name.length() == 1 )
                    area.text = area.name;
                if ( area.name == Joystick)
                    joystick = i;
                area.activeWhenClosed = closedAreas.contains(area.name)
                    || area.keyCode == Qt::Key_Flip; // must be to work
                area.toggleArea = toggleAreas.contains(area.name);
                area.toggleActiveArea = toggleActiveAreas.contains(area.name);
                if (area.toggleArea)
                    toggleAreaList += i;
                i++;
            }
        }
    }
    if (i != nareas) {
        qWarning() << DeviceSkin::tr("Mismatch in number of areas, expected %1, got %2.")
                      .arg(nareas).arg(i);
    }
    if (debugDeviceSkin)
        qDebug() << *this;
    return true;
}

// --------- CursorWindow declaration

namespace qvfb_internal {

class CursorWindow : public QWidget
{
public:
    explicit CursorWindow(const QImage &cursor, QPoint hot, QWidget *sk);

    void setView(QWidget*);
    void setPos(QPoint);
    bool handleMouseEvent(QEvent *ev);

protected:
    bool event( QEvent *);
    bool eventFilter( QObject*, QEvent *);

private:
    QWidget *mouseRecipient;
    QWidget *m_view;
    QWidget *skin;
    QPoint hotspot;
};
}

// --------- Skin

DeviceSkin::DeviceSkin(const DeviceSkinParameters &parameters,  QWidget *p ) :
    QWidget(p),
    m_parameters(parameters),
    buttonRegions(parameters.buttonAreas.size(), QRegion()),
    parent(p),
    m_view(0),
    m_secondaryView(0),
    buttonPressed(false),
    buttonIndex(0),
    cursorw(0),
    joydown(0),
    t_skinkey(new QTimer(this)),
    t_parentmove(new QTimer(this)),
    flipped_open(true)
{
    Q_ASSERT(p);
    setMouseTracking(true);
    setAttribute(Qt::WA_NoSystemBackground);

    setZoom(1.0);
    connect(t_skinkey, &QTimer::timeout, this, &DeviceSkin::skinKeyRepeat );
    t_parentmove->setSingleShot( true );
    connect(t_parentmove, &QTimer::timeout, this, &DeviceSkin::moveParent );
}

void DeviceSkin::skinKeyRepeat()
{
    if ( m_view ) {
        const DeviceSkinButtonArea &area = m_parameters.buttonAreas[buttonIndex];
        emit skinKeyReleaseEvent(area.keyCode,area.text, true);
        emit skinKeyPressEvent(area.keyCode, area.text, true);
        t_skinkey->start(key_repeat_period);
    }
}

void DeviceSkin::calcRegions()
{
    const int numAreas = m_parameters.buttonAreas.size();
    for (int i=0; i<numAreas; i++) {
        QPolygon xa(m_parameters.buttonAreas[i].area.count());
        int n = m_parameters.buttonAreas[i].area.count();
        for (int p = 0; p < n; p++) {
            xa.setPoint(p,transform.map(m_parameters.buttonAreas[i].area[p]));
        }
        if (n == 2) {
            buttonRegions[i] = QRegion(xa.boundingRect());
        } else {
            buttonRegions[i] = QRegion(xa);
        }
    }
}

void DeviceSkin::loadImages()
{
    QImage iup = m_parameters.skinImageUp;
    QImage idown = m_parameters.skinImageDown;

    QImage iclosed;
    const bool hasClosedImage = !m_parameters.skinImageClosed.isNull();

    if (hasClosedImage)
        iclosed =  m_parameters.skinImageClosed;
    QImage icurs;
    const bool hasCursorImage = !m_parameters.skinCursor.isNull();
    if (hasCursorImage)
        icurs =  m_parameters.skinCursor;

    if (!transform.isIdentity()) {
        iup = iup.transformed(transform, Qt::SmoothTransformation);
        idown = idown.transformed(transform, Qt::SmoothTransformation);
        if (hasClosedImage)
            iclosed = iclosed.transformed(transform, Qt::SmoothTransformation);
        if (hasCursorImage)
            icurs = icurs.transformed(transform, Qt::SmoothTransformation);
    }
    const Qt::ImageConversionFlags conv = Qt::ThresholdAlphaDither|Qt::AvoidDither;
    skinImageUp = QPixmap::fromImage(iup);
    skinImageDown = QPixmap::fromImage(idown, conv);
    if (hasClosedImage)
        skinImageClosed = QPixmap::fromImage(iclosed, conv);
    if (hasCursorImage)
        skinCursor = QPixmap::fromImage(icurs, conv);

    setFixedSize( skinImageUp.size() );
    if (!skinImageUp.mask())
        skinImageUp.setMask(skinImageUp.createHeuristicMask());
    if (!skinImageClosed.mask())
        skinImageClosed.setMask(skinImageClosed.createHeuristicMask());

    QWidget* parent = parentWidget();
    parent->setMask( skinImageUp.mask() );
    parent->setFixedSize( skinImageUp.size() );

    delete cursorw;
    cursorw = 0;
    if (hasCursorImage) {
        cursorw = new qvfb_internal::CursorWindow(m_parameters.skinCursor, m_parameters.cursorHot, this);
        if (m_view)
            cursorw->setView(m_view);
    }
}

DeviceSkin::~DeviceSkin( )
{
    delete cursorw;
}

void DeviceSkin::setTransform(const QTransform &wm)
{
    transform = QImage::trueMatrix(wm,m_parameters.skinImageUp.width(),m_parameters.skinImageUp.height());
    calcRegions();
    loadImages();
    if ( m_view ) {
        QPoint p = transform.map(QPolygon(m_parameters.screenRect)).boundingRect().topLeft();
        m_view->move(p);
    }
    updateSecondaryScreen();
}

void DeviceSkin::setZoom( double z )
{
    setTransform(QTransform().scale(z,z));
}

void DeviceSkin::updateSecondaryScreen()
{
    if (!m_secondaryView)
        return;
    if (flipped_open) {
        if (m_parameters.backScreenRect.isNull()) {
            m_secondaryView->hide();
        } else {
            m_secondaryView->move(transform.map(QPolygon(m_parameters.backScreenRect)).boundingRect().topLeft());
            m_secondaryView->show();
        }
    } else {
        if (m_parameters.closedScreenRect.isNull()) {
            m_secondaryView->hide();
        } else {
            m_secondaryView->move(transform.map(QPolygon(m_parameters.closedScreenRect)).boundingRect().topLeft());
            m_secondaryView->show();
        }
    }
}

void DeviceSkin::setView( QWidget *v )
{
    m_view = v;
    m_view->setFocus();
    m_view->move(transform.map(QPolygon(m_parameters.screenRect)).boundingRect().topLeft());
    if ( cursorw )
        cursorw->setView(v);
}

void DeviceSkin::setSecondaryView( QWidget *v )
{
    m_secondaryView = v;
    updateSecondaryScreen();
}

void DeviceSkin::paintEvent( QPaintEvent *)
{
    QPainter p( this );
    if ( flipped_open ) {
        p.drawPixmap(0, 0, skinImageUp);
    } else {
        p.drawPixmap(0, 0, skinImageClosed);
    }
    QVector<int> toDraw;
    if ( buttonPressed == true ) {
        toDraw += buttonIndex;
    }
    for (int toggle : qAsConst(m_parameters.toggleAreaList)) {
        const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[toggle];
        if (flipped_open || ba.activeWhenClosed) {
            if (ba.toggleArea && ba.toggleActiveArea)
                toDraw += toggle;
        }
    }
    for (int button : qAsConst(toDraw)) {
        const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[button];
        const QRect r = buttonRegions[button].boundingRect();
        if ( ba.area.count() > 2 )
            p.setClipRegion(buttonRegions[button]);
        p.drawPixmap( r.topLeft(), skinImageDown, r);
    }
}

void DeviceSkin::mousePressEvent( QMouseEvent *e )
{
    if (e->button() == Qt::RightButton) {
        emit popupMenu();
    } else {
        buttonPressed = false;

        onjoyrelease = -1;
        const int numAreas = m_parameters.buttonAreas.size();
        for (int i = 0; i < numAreas ; i++) {
            const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[i];
            if (  buttonRegions[i].contains( e->pos() ) ) {
                if ( flipped_open || ba.activeWhenClosed ) {
                    if ( m_parameters.joystick == i ) {
                        joydown = true;
                    } else {
                        if ( joydown )
                            onjoyrelease = i;
                        else
                            startPress(i);
                        break;
                        if (debugDeviceSkin)// Debug message to be sure we are clicking the right areas
                            qDebug()<< m_parameters.buttonAreas[i].name << " clicked";
                    }
                }
            }
        }
        clickPos = e->pos();
//      This is handy for finding the areas to define rectangles for new skins
        if (debugDeviceSkin)
            qDebug()<< "Clicked in " <<  e->pos().x() << ',' <<  e->pos().y();
        clickPos = e->pos();
    }
}

void DeviceSkin::flip(bool open)
{
    if ( flipped_open == open )
        return;
    if ( open ) {
        parent->setMask(skinImageUp.mask());
        emit skinKeyReleaseEvent(Qt::Key(Qt::Key_Flip), QString(), false);
    } else {
        parent->setMask(skinImageClosed.mask());
        emit skinKeyPressEvent(Qt::Key(Qt::Key_Flip), QString(), false);
    }
    flipped_open = open;
    updateSecondaryScreen();
    repaint();
}

void DeviceSkin::startPress(int i)
{
    buttonPressed = true;
    buttonIndex = i;
    if (m_view) {
        const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[buttonIndex];
        if (ba.keyCode == Qt::Key_Flip) {
            flip(!flipped_open);
        } else if (ba.toggleArea) {
            bool active = !ba.toggleActiveArea;
            const_cast<DeviceSkinButtonArea &>(ba).toggleActiveArea = active;
            if (active)
                emit skinKeyPressEvent(ba.keyCode, ba.text, false);
            else
                emit skinKeyReleaseEvent(ba.keyCode, ba.text, false);
        } else {
            emit skinKeyPressEvent(ba.keyCode, ba.text, false);
            t_skinkey->start(key_repeat_delay);
        }
        repaint(buttonRegions[buttonIndex].boundingRect());
    }
}

void DeviceSkin::endPress()
{
    const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[buttonIndex];
    if (m_view && ba.keyCode != Qt::Key_Flip && !ba.toggleArea )
        emit skinKeyReleaseEvent(ba.keyCode, ba.text, false);
    t_skinkey->stop();
    buttonPressed = false;
    repaint( buttonRegions[buttonIndex].boundingRect() );
}

void DeviceSkin::mouseMoveEvent( QMouseEvent *e )
{
    if ( e->buttons() & Qt::LeftButton ) {
        const int joystick = m_parameters.joystick;
        QPoint newpos =  e->globalPos() - clickPos;
        if (joydown) {
            int k1=0, k2=0;
            if (newpos.x() < -joydistance) {
                k1 = joystick+1;
            } else if (newpos.x() > +joydistance) {
                k1 = joystick+3;
            }
            if (newpos.y() < -joydistance) {
                k2 = joystick+2;
            } else if (newpos.y() > +joydistance) {
                k2 = joystick+4;
            }
            if (k1 || k2) {
                if (!buttonPressed) {
                    onjoyrelease = -1;
                    if (k1 && k2) {
                        startPress(k2);
                        endPress();
                    }
                    startPress(k1 ? k1 : k2);
                }
            } else if (buttonPressed) {
                endPress();
            }
        } else if (buttonPressed == false) {
            parentpos = newpos;
            if (!t_parentmove->isActive())
                t_parentmove->start(50);
        }
    }
    if ( cursorw )
        cursorw->setPos(e->globalPos());
}

void DeviceSkin::moveParent()
{
    parent->move( parentpos );
}

void DeviceSkin::mouseReleaseEvent( QMouseEvent * )
{
    if ( buttonPressed )
        endPress();
    if ( joydown ) {
        joydown = false;
        if (onjoyrelease >= 0) {
            startPress(onjoyrelease);
            endPress();
        }
    }
}

bool DeviceSkin::hasCursor() const
{
    return !skinCursor.isNull();
}

// ------------------ CursorWindow implementation

namespace qvfb_internal {

bool CursorWindow::eventFilter( QObject *, QEvent *ev)
{
    handleMouseEvent(ev);
    return false;
}

bool CursorWindow::event( QEvent *ev )
{
    if (handleMouseEvent(ev))
        return true;
    return QWidget::event(ev);
}

bool CursorWindow::handleMouseEvent(QEvent *ev)
{
    bool handledEvent = false;
    static int inhere=0;
    if ( !inhere ) {
        inhere++;
        if (m_view) {
            if (ev->type() >= QEvent::MouseButtonPress && ev->type() <= QEvent::MouseMove) {
                QMouseEvent *e = (QMouseEvent*)ev;
                QPoint gp = e->globalPos();
                QPoint vp = m_view->mapFromGlobal(gp);
                QPoint sp = skin->mapFromGlobal(gp);
                if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonDblClick) {
                    if (m_view->rect().contains(vp))
                        mouseRecipient = m_view;
                    else if (skin->parentWidget()->geometry().contains(gp))
                        mouseRecipient = skin;
                    else
                        mouseRecipient = 0;
                }
                if (mouseRecipient) {
                    setPos(gp);
                    QMouseEvent me(e->type(),mouseRecipient==skin ? sp : vp,gp,e->button(),e->buttons(),e->modifiers());
                    QApplication::sendEvent(mouseRecipient, &me);
                } else if (!skin->parentWidget()->geometry().contains(gp)) {
                    hide();
                } else {
                    setPos(gp);
                }
                if (e->type() == QEvent::MouseButtonRelease)
                    mouseRecipient = 0;
                handledEvent = true;
            }
        }
        inhere--;
    }
    return handledEvent;
}

void CursorWindow::setView(QWidget* v)
{
    if ( m_view ) {
        m_view->removeEventFilter(this);
        m_view->removeEventFilter(this);
    }
    m_view = v;
    m_view->installEventFilter(this);
    m_view->installEventFilter(this);
    mouseRecipient = 0;
}

CursorWindow::CursorWindow(const QImage &img, QPoint hot, QWidget* sk)
    : QWidget(0),
      m_view(0),
      skin(sk),
      hotspot(hot)
{
    setWindowFlags( Qt::FramelessWindowHint );
    mouseRecipient = 0;
    setMouseTracking(true);
#ifndef QT_NO_CURSOR
    setCursor(Qt::BlankCursor);
#endif
    QPixmap p;
    p = QPixmap::fromImage(img);
    if (!p.mask()) {
        if (img.hasAlphaChannel()) {
            QBitmap bm;
            bm = QPixmap::fromImage(img.createAlphaMask());
            p.setMask(bm);
        } else {
            QBitmap bm;
            bm = QPixmap::fromImage(img.createHeuristicMask());
            p.setMask(bm);
        }
    }
    QPalette palette;
    palette.setBrush(backgroundRole(), QBrush(p));
    setPalette(palette);
    setFixedSize( p.size() );
    if ( !p.mask().isNull() )
        setMask(p.mask());
}

void CursorWindow::setPos(QPoint p)
{
    move(p-hotspot);
    show();
    raise();
}
}

#ifdef TEST_SKIN

int main(int argc,char *argv[])
{
    if (argc < 1)
        return 1;
    const QString skinFile = QString::fromUtf8(argv[1]);
    QApplication app(argc,argv);
    QMainWindow mw;

    DeviceSkinParameters params;
    QString errorMessage;
    if (!params.read(skinFile, DeviceSkinParameters::ReadAll, &errorMessage)) {
        qWarning() << errorMessage;
        return 1;
    }
    DeviceSkin ds(params, &mw);
    // View Dialog
    QDialog *dialog = new QDialog();
    QHBoxLayout *dialogLayout = new QHBoxLayout();
    dialog->setLayout(dialogLayout);
    QDialogButtonBox *dialogButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
    QObject::connect(dialogButtonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
    QObject::connect(dialogButtonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
    dialogLayout->addWidget(dialogButtonBox);
    dialog->setFixedSize(params.screenSize());
    dialog->setParent(&ds, Qt::SubWindow);
    dialog->setAutoFillBackground(true);
    ds.setView(dialog);

    QObject::connect(&ds, SIGNAL(popupMenu()), &mw, SLOT(close()));
    QObject::connect(&ds, SIGNAL(skinKeyPressEvent(int,QString,bool)), &mw, SLOT(close()));
    mw.show();
    return app.exec();
}

#endif

QT_END_NAMESPACE

