/****************************************************************************
**
** 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 Qt Designer 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 "zoomwidget_p.h"

#include <QtGui/QGraphicsScene>
#include <QtGui/QGraphicsProxyWidget>
#include <QtGui/QMenu>
#include <QtGui/QAction>
#include <QtGui/QActionGroup>
#include <QtGui/QContextMenuEvent>
#include <QtGui/QScrollBar>

#include <QtCore/QTextStream>
#include <QtCore/qmath.h>
#include <QtCore/QDebug>
#include <QtCore/QList>

QT_BEGIN_NAMESPACE

typedef QList<QAction*> ActionList;
typedef QList<QGraphicsItem *> GraphicsItemList;

enum { debugZoomWidget = 0 };

static const int menuZoomList[] = { 100, 25, 50, 75, 125, 150 , 175, 200 };

static inline QSize qCeiling(const QSizeF &s)
{
    return QSize(qCeil(s.width()), qCeil(s.height()));
}

namespace qdesigner_internal {

// ---------- ZoomMenu

ZoomMenu::ZoomMenu(QObject *parent) :
   QObject(parent),
   m_menuActions(new QActionGroup(this))
{
    connect(m_menuActions, SIGNAL(triggered(QAction*)), this, SLOT(slotZoomMenu(QAction*)));
    const int nz = sizeof(menuZoomList)/sizeof(int);
    for (int i = 0; i < nz; i++) {
        const int zoom = menuZoomList[i];
        //: Zoom factor
        QAction *a = m_menuActions->addAction(tr("%1 %").arg(zoom));
        a->setCheckable(true);
        a->setData(QVariant(zoom));
        if (zoom == 100)
            a->setChecked(true);
        m_menuActions->addAction(a);
    }
}

int ZoomMenu::zoomOf(const QAction *a)
{
    return a->data().toInt();
}

void ZoomMenu::addActions(QMenu *m)
{
    const ActionList za = m_menuActions->actions();
    const ActionList::const_iterator cend = za.constEnd();
    for (ActionList::const_iterator it =  za.constBegin(); it != cend; ++it) {
        m->addAction(*it);
        if (zoomOf(*it)  == 100)
            m->addSeparator();
    }
}

int ZoomMenu::zoom() const
{
    return m_menuActions->checkedAction()->data().toInt();
}

void ZoomMenu::setZoom(int percent)
{
    const ActionList za = m_menuActions->actions();
    const ActionList::const_iterator cend = za.constEnd();
    for (ActionList::const_iterator it =  za.constBegin(); it != cend; ++it)
        if (zoomOf(*it) == percent) {
            (*it)->setChecked(true);
            return;
        }
}

void ZoomMenu::slotZoomMenu(QAction *a)
{
    emit zoomChanged(zoomOf(a));
}

QList<int> ZoomMenu::zoomValues()
{
    QList<int> rc;
    const int nz = sizeof(menuZoomList)/sizeof(int);
    for (int i = 0; i < nz; i++)
        rc.push_back(menuZoomList[i]);
    return rc;
}

// --------- ZoomView
ZoomView::ZoomView(QWidget *parent) :
    QGraphicsView(parent),
    m_scene(new QGraphicsScene(this)),
    m_zoom(100),
    m_zoomFactor(1.0),
    m_zoomContextMenuEnabled(false),
    m_zoomMenu(0)
{
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setFrameShape(QFrame::NoFrame);
    setScene(m_scene);
    if (debugZoomWidget)
        qDebug() << "scene" << m_scene->sceneRect();

}

int ZoomView::zoom() const
{
    return m_zoom;
}

void ZoomView::scrollToOrigin()
{
    const QPoint origin(0 ,0);
    const QPoint current = scrollPosition();
    if (current != origin) {
        if (debugZoomWidget)
            qDebug() << "ZoomView::scrollToOrigin from " << current;
        setScrollPosition(origin);
    }
}

void ZoomView::setZoom(int percent)
{
    if (debugZoomWidget)
        qDebug() << "ZoomView::setZoom" << percent;

    if (m_zoom == percent)
        return;

    m_zoom = percent;
    const qreal hundred = 100.0;
    m_zoomFactor = static_cast<qreal>(m_zoom) / hundred;

    applyZoom();
    if (m_zoomMenu) // Do not force them into existence
        m_zoomMenu->setZoom(m_zoom);

    resetTransform();
    scale(m_zoomFactor, m_zoomFactor);
}

void ZoomView::applyZoom()
{
}

qreal ZoomView::zoomFactor() const
{
    return m_zoomFactor;
}

bool ZoomView::isZoomContextMenuEnabled() const
{
    return m_zoomContextMenuEnabled;
}

void ZoomView::setZoomContextMenuEnabled(bool e)
{
    m_zoomContextMenuEnabled = e;
}

ZoomMenu *ZoomView::zoomMenu()
{
    if (!m_zoomMenu) {
        m_zoomMenu = new ZoomMenu(this);
        m_zoomMenu->setZoom(m_zoom);
        connect(m_zoomMenu, SIGNAL(zoomChanged(int)), this, SLOT(setZoom(int)));
    }
    return m_zoomMenu;
}

void ZoomView::contextMenuEvent(QContextMenuEvent *event)
{
    if (debugZoomWidget > 1)
        qDebug() << "ZoomView::contextMenuEvent" << event->pos() << event->globalPos() << zoom() << '%';

    if (m_zoomContextMenuEnabled) {
        showContextMenu(event->globalPos());
    } else {
        QGraphicsView::contextMenuEvent(event);
    }
}

void ZoomView::showContextMenu(const QPoint &globalPos)
{
    QMenu menu;
    zoomMenu()->addActions(&menu);
    if (debugZoomWidget) {
        menu.addSeparator();
        QAction *da = menu.addAction(QLatin1String("Dump"));
        connect(da, SIGNAL(triggered()), this, SLOT(dump()));
    }
    menu.exec(globalPos);
}

QPoint ZoomView::scrollPosition() const
{
    return QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value());
}

void ZoomView::setScrollPosition(const QPoint& pos)
{
    horizontalScrollBar()->setValue(pos.x());
    verticalScrollBar()->setValue(pos.y());
}

// -------------- ZoomProxyWidget
ZoomProxyWidget::ZoomProxyWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags) :
    QGraphicsProxyWidget(parent, wFlags)
{
}

QVariant ZoomProxyWidget::itemChange(GraphicsItemChange change, const QVariant &value)
{
    switch (change) {
    case ItemPositionChange: {
        const QPointF newPos = value.toPointF();
        const QPointF desiredPos = QPointF(0, 0);
        if (newPos != desiredPos && debugZoomWidget)
            qDebug() << "ZoomProxyWidget::itemChange: refusing " << newPos;
        return desiredPos;
    }
    default:
        break;
    }
    return QGraphicsProxyWidget::itemChange(change, value);
}

/* ZoomedEventFilterRedirector: Event filter for the zoomed widget.
 * It redirects the events to another handler of ZoomWidget as its
 * base class QScrollArea also implements eventFilter() for its viewport. */

static const char *zoomedEventFilterRedirectorNameC = "__qt_ZoomedEventFilterRedirector";

class ZoomedEventFilterRedirector : public QObject {
    Q_DISABLE_COPY(ZoomedEventFilterRedirector)

public:
    explicit ZoomedEventFilterRedirector(ZoomWidget *zw, QObject *parent);
    virtual bool eventFilter(QObject *watched, QEvent *event);

private:
    ZoomWidget *m_zw;
};

ZoomedEventFilterRedirector::ZoomedEventFilterRedirector(ZoomWidget *zw, QObject *parent) :
    QObject(parent),
    m_zw(zw)
{
    setObjectName(QLatin1String(zoomedEventFilterRedirectorNameC));
}

bool ZoomedEventFilterRedirector::eventFilter(QObject *watched, QEvent *event)
{
    return m_zw->zoomedEventFilter(watched, event);
}


// --------- ZoomWidget

ZoomWidget::ZoomWidget(QWidget *parent) :
    ZoomView(parent),
    m_proxy(0),
    m_viewResizeBlocked(false),
    m_widgetResizeBlocked(false),
    m_widgetZoomContextMenuEnabled(false)
{
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}

void ZoomWidget::setWidget(QWidget *w, Qt::WindowFlags wFlags)
{
    if (debugZoomWidget)
        qDebug() << "ZoomWidget::setWidget" << w << bin << wFlags;

    if (m_proxy) {
        scene().removeItem(m_proxy);
        if (QWidget *w = m_proxy->widget()) {
            // remove the event filter
            if (QObject *evf =  qFindChild<QObject*>(w, QLatin1String(zoomedEventFilterRedirectorNameC)))
                w->removeEventFilter(evf);
        }
        m_proxy->deleteLater();
    }
    // Set window flags on the outer proxy for them to take effect
    m_proxy = createProxyWidget(0, Qt::Window);
    m_proxy->setWidget(w);

    m_proxy->setWindowFlags(wFlags);
    scene().addItem(m_proxy);
    w->installEventFilter(new ZoomedEventFilterRedirector(this, w));
    resizeToWidgetSize(); // Do manually for new widget
    m_proxy->show();
}

bool ZoomWidget::isWidgetZoomContextMenuEnabled() const
{
    return m_widgetZoomContextMenuEnabled;
}
void ZoomWidget::setWidgetZoomContextMenuEnabled(bool e)
{
    m_widgetZoomContextMenuEnabled = e;
}

QSize ZoomWidget::viewPortMargin() const
{
    return QSize(0, 0);
}

QSizeF ZoomWidget::widgetDecorationSizeF() const
{
    qreal left, top, right, bottom;
    m_proxy->getWindowFrameMargins (&left, &top, &right, &bottom);
    const QSizeF rc = QSizeF(left + right, top + bottom);
    return rc;
}

QSize ZoomWidget::widgetSize() const
{
    if (m_proxy)
        return m_proxy->widget()->size();
    return QSize(0, 0);
}

/* Convert widget size to QGraphicsView size.
 * Watch out for limits (0, QWIDGETSIZE_MAX); just pass them on */

QSize ZoomWidget::widgetSizeToViewSize(const QSize &s, bool *ptrToValid) const
{
    const QSize vpMargin = viewPortMargin();
    const QSizeF deco = widgetDecorationSizeF();
    const int width = s.width();

    QSize rc = s;
    bool valid = false;
    if (width != 0 && width != QWIDGETSIZE_MAX) {
        valid = true;
        rc.setWidth(vpMargin.width() + qCeil(deco.width() + zoomFactor() * static_cast<qreal>(width)));
    }

    const int height = s.height();
    if (height != 0 && height != QWIDGETSIZE_MAX) {
        valid = true;
        rc.setHeight(vpMargin.height() + qCeil(deco.height() + zoomFactor() * static_cast<qreal>(height)));
    }

    if (ptrToValid)
        *ptrToValid = valid;

    return rc;
}

// On changing zoom: Make QGraphicsView big enough to hold the widget
void ZoomWidget::resizeToWidgetSize()
{
    if (!m_proxy)
        return;

    m_viewResizeBlocked = true;
    // Convert size, apply transformed min/max size if applicable
    const QSize wsize = widgetSize();
    const QSize viewSize = widgetSizeToViewSize(wsize);

    bool hasMinimumSize = false;
    const QSize minimumSize = m_proxy->widget()->minimumSize();
    const QSize viewMinimumSize = widgetSizeToViewSize(minimumSize, &hasMinimumSize);

    bool hasMaximumSize = false;
    const QSize maximumSize = m_proxy->widget()->maximumSize();
    const QSize viewMaximumSize = widgetSizeToViewSize(maximumSize, &hasMaximumSize);

  if (debugZoomWidget) {
        qDebug()
            << "ZoomWidget::resizeToWidgetSize()\n"
            << "Widget: " <<  wsize << "(scaled)"  << (wsize * zoomFactor()) << " Min/Max" << minimumSize  <<  maximumSize << '\n'
            << "  View: " << viewSize <<  hasMinimumSize << viewMinimumSize << hasMaximumSize << viewMaximumSize;
    }
    // Apply
    if (hasMinimumSize)
        setMinimumSize(viewMinimumSize);
    if (hasMaximumSize)
        setMaximumSize(viewMaximumSize);
    // now resize
    doResize(viewSize);
    if (debugZoomWidget)
        qDebug() << "ZoomWidget::resizeToWidgetSize(): resulting view size" << size();
    m_viewResizeBlocked = false;
}

void ZoomWidget::applyZoom()
{
    resizeToWidgetSize();
}

/* virtual */ void  ZoomWidget::doResize(const QSize &s)
{
    if (debugZoomWidget > 1)
        qDebug() << ">ZoomWidget::doResize() " << s;
    resize(s);
}

void ZoomWidget::resizeEvent(QResizeEvent *event)
{
    /* QGraphicsView Resized from outside: Adapt widget. For some reason,
     * the size passed in the event is not to be trusted. This might be due
     * to some QScrollArea event fiddling. Have QScrollArea resize first
     * and the use the size ZoomView::resizeEvent(event); */
    if (m_proxy && !m_viewResizeBlocked) {
        if (debugZoomWidget > 1)
            qDebug() << '>' << Q_FUNC_INFO << size() << ")::resizeEvent from " << event->oldSize() << " to " << event->size();
        const QSizeF newViewPortSize = size() - viewPortMargin();
        const QSizeF widgetSizeF = newViewPortSize / zoomFactor() - widgetDecorationSizeF();
        m_widgetResizeBlocked = true;
        m_proxy->widget()->resize(widgetSizeF.toSize());
        setSceneRect(QRectF(QPointF(0, 0), widgetSizeF));
        scrollToOrigin();
        m_widgetResizeBlocked = false;
        if (debugZoomWidget > 1)
            qDebug() << '<' << Q_FUNC_INFO << widgetSizeF << m_proxy->widget()->size() << m_proxy->size();
    }
}

QSize ZoomWidget::minimumSizeHint() const
{
    if (!m_proxy)
        return QGraphicsView::minimumSizeHint();

    const QSizeF wmsh = m_proxy->widget()->minimumSizeHint();
    const QSize rc = viewPortMargin() + (wmsh * zoomFactor()).toSize();
    if (debugZoomWidget > 1)
        qDebug() << "minimumSizeHint()" << rc;
    return rc;
}

QSize ZoomWidget::sizeHint() const
{
    if (!m_proxy)
        return QGraphicsView::sizeHint();

    const QSizeF wsh = m_proxy->widget()->sizeHint();
    const QSize rc = viewPortMargin() + (wsh * zoomFactor()).toSize();
    if (debugZoomWidget > 1)
        qDebug() << "sizeHint()" << rc;
    return rc;
}

bool ZoomWidget::zoomedEventFilter(QObject * /*watched*/, QEvent *event)
{
    switch (event->type()) {
    case QEvent::KeyPress:
        if (debugZoomWidget) { // Debug helper: Press 'D' on the zoomed widget
            const QKeyEvent *kevent = static_cast<QKeyEvent*>(event);
            if (kevent->key() == Qt::Key_D)
                dump();
        }
        break;
    case QEvent::Resize:
        if (debugZoomWidget > 1) {
            const QResizeEvent *re = static_cast<const QResizeEvent *>(event);
            qDebug() << "ZoomWidget::zoomedEventFilter" << re->oldSize() << re->size() << " at " << m_proxy->widget()->geometry();
        }
        if (!m_widgetResizeBlocked)
            resizeToWidgetSize();

        break;
    case QEvent::ContextMenu:
        if (m_widgetZoomContextMenuEnabled) {
            // Calculate global position from scaled
            QContextMenuEvent *ce = static_cast<QContextMenuEvent*>(event);
            const QPointF origin = mapToGlobal(QPoint(0, 0)) - scrollPosition();
            const QPointF pos = QPointF(origin + (QPointF(ce->pos()) * zoomFactor()));
            showContextMenu(pos.toPoint());
            ce->accept();
            return true;
        }
        break;
    default:
        break;
    }
    return false;
}

void ZoomWidget::setItemAcceptDrops(bool)
{
    if (m_proxy)
        m_proxy->setAcceptDrops(true);
}

bool ZoomWidget::itemAcceptDrops() const
{
    return m_proxy ? m_proxy->acceptDrops() : false;
}

       // Factory function for QGraphicsProxyWidgets which can be overwritten. Default creates a ZoomProxyWidget
QGraphicsProxyWidget *ZoomWidget::createProxyWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags) const
{
    return new ZoomProxyWidget(parent, wFlags);
}

void ZoomWidget::dump() const
{

    qDebug() << "ZoomWidget::dump " << geometry() << " Viewport " << viewport()->geometry()
        << "Scroll: " << scrollPosition() << "Matrix: " << matrix() << " SceneRect: " << sceneRect();
    if (m_proxy) {
        qDebug() << "Proxy Pos: " << m_proxy->pos() << "Proxy " << m_proxy->size()
            << "\nProxy size hint"
            <<  m_proxy->effectiveSizeHint(Qt::MinimumSize)
            <<  m_proxy->effectiveSizeHint(Qt::PreferredSize)
            << m_proxy->effectiveSizeHint(Qt::MaximumSize)
            << "\nMatrix: " << m_proxy->matrix()
            << "\nWidget: " <<  m_proxy->widget()->geometry()
            << "scaled" << (zoomFactor() * m_proxy->widget()->size());
    }
}

} // namespace qdesigner_internal

QT_END_NAMESPACE
