/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "cloud.h"
#include "bearercloud.h"

#include <qnetworksession.h>

#include <QGraphicsTextItem>
#include <QGraphicsSvgItem>
#include <QGraphicsSceneMouseEvent>
#include <QSvgRenderer>
#include <QPainter>

#include <QDebug>

#include <math.h>

static QMap<QNetworkConfiguration::BearerType, QSvgRenderer *> svgCache;

//! [0]
Cloud::Cloud(const QNetworkConfiguration &config, QGraphicsItem *parent)
:   QGraphicsItem(parent), configuration(config), deleteAfterAnimation(false)
{
    session = new QNetworkSession(configuration, this);
    connect(session, SIGNAL(newConfigurationActivated()),
            this, SLOT(newConfigurationActivated()));
    connect(session, SIGNAL(stateChanged(QNetworkSession::State)),
            this, SLOT(stateChanged(QNetworkSession::State)));

    setFlag(ItemIsMovable);
    setFlag(ItemSendsGeometryChanges);
    setZValue(1);

    icon = new QGraphicsSvgItem(this);
    text = new QGraphicsTextItem(this);

    currentScale = 0;
    finalScale = 1;
    setTransform(QTransform::fromScale(currentScale, currentScale), false);
    setOpacity(0);

    newConfigurationActivated();
}
//! [0]

Cloud::~Cloud()
{
}

void Cloud::setFinalScale(qreal factor)
{
    finalScale = factor;
}

void Cloud::setDeleteAfterAnimation(bool deleteAfter)
{
    deleteAfterAnimation = deleteAfter;
}

void Cloud::calculateForces()
{
    if (!scene() || scene()->mouseGrabberItem() == this) {
        newPos = pos();
        return;
    }

    // sum up all the forces push this item away
    qreal xvel = 0;
    qreal yvel = 0;
    QLineF orbitForce;
    const auto graphicsItems = scene()->items();
    for (QGraphicsItem *item : graphicsItems) {
        // other clouds
        Cloud *cloud = qgraphicsitem_cast<Cloud *>(item);
        if (!cloud && item->data(0) != QLatin1String("This Device"))
            continue;

        qreal factor = 1.0;

        QLineF line(cloud ? item->mapToScene(0, 0) : QPointF(0, 0), mapToScene(0, 0));
        if (item->data(0) == QLatin1String("This Device"))
            orbitForce = line;

        if (cloud)
            factor = cloud->currentScale;

        qreal dx = line.dx();
        qreal dy = line.dy();
        double l = 2.0 * (dx * dx + dy * dy);
        if (l > 0) {
            xvel += factor * dx * 200.0 / l;
            yvel += factor * dy * 200.0 / l;
        }
    }

    // tendency to stay at a fixed orbit
    qreal orbit = getRadiusForState(configuration.state());
    qreal distance = orbitForce.length();

    QLineF unit = orbitForce.unitVector();

    orbitForce.setLength(xvel * unit.dx() + yvel * unit.dy());

    qreal w = 2 - exp(-pow(distance-orbit, 2)/(2 * 50));

    if (distance < orbit) {
        xvel += orbitForce.dx() * w;
        yvel += orbitForce.dy() * w;
    } else {
        xvel -= orbitForce.dx() * w;
        yvel -= orbitForce.dy() * w;
    }

    if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1)
        xvel = yvel = 0;

    QRectF sceneRect = scene()->sceneRect();
    newPos = pos() + QPointF(xvel, yvel);
    newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10));
    newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10));
}

bool Cloud::advanceAnimation()
{
    static const qreal scaleDelta = 0.01;

    bool animated = false;

    if (currentScale < finalScale) {
        animated = true;
        currentScale = qMin<qreal>(currentScale + scaleDelta, finalScale);
        setTransform(QTransform::fromScale(currentScale, currentScale), false);
    } else if (currentScale > finalScale) {
        animated = true;
        currentScale = qMax<qreal>(currentScale - scaleDelta, finalScale);
        setTransform(QTransform::fromScale(currentScale, currentScale), false);
    }

    if (newPos != pos()) {
        setPos(newPos);
        animated = true;
    }

    if (opacity() != finalOpacity) {
        animated = true;
        if (qAbs(finalScale - currentScale) > 0.0) {
            // use scale as reference
            setOpacity(opacity() + scaleDelta * (finalOpacity - opacity()) /
                       qAbs(finalScale - currentScale));
        } else {
            setOpacity(finalOpacity);
        }
    }

    if (!animated && deleteAfterAnimation)
        deleteLater();

    return animated;
}

QRectF Cloud::boundingRect() const
{
    return childrenBoundingRect();
}

void Cloud::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
{
}

//! [4]
QVariant Cloud::itemChange(GraphicsItemChange change, const QVariant &value)
{
    switch (change) {
    case ItemPositionHasChanged:
        if (BearerCloud *bearercloud = qobject_cast<BearerCloud *>(scene()))
            bearercloud->cloudMoved();
    default:
        ;
    };

    return QGraphicsItem::itemChange(change, value);
}
//! [4]

//! [3]
void Cloud::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        if (session->isOpen())
            session->close();
        else
            session->open();

        event->accept();
    }
}
//! [3]

//! [2]
void Cloud::stateChanged(QNetworkSession::State state)
{
    if (configuration.name().isEmpty())
        finalOpacity = qreal(0.1);
    else if (session->state() == QNetworkSession::NotAvailable)
        finalOpacity = 0.5;
    else
        finalOpacity = 1.0;

    QString tooltip;

    if (configuration.name().isEmpty())
        tooltip += tr("<b>HIDDEN NETWORK</b><br>");
    else
        tooltip += tr("<b>%1</b><br>").arg(configuration.name());

#ifndef QT_NO_NETWORKINTERFACE
    const QNetworkInterface interface = session->interface();
    if (interface.isValid())
        tooltip += tr("<br>Interface: %1").arg(interface.humanReadableName());
    tooltip += tr("<br>Id: %1").arg(configuration.identifier());
#endif

    const QString bearerTypeName = configuration.bearerTypeName();
    if (!bearerTypeName.isEmpty())
        tooltip += tr("<br>Bearer: %1").arg(bearerTypeName);

    QString s = tr("<br>State: %1 (%2)");
    switch (state) {
    case QNetworkSession::Invalid:
        s = s.arg(tr("Invalid"));
        break;
    case QNetworkSession::NotAvailable:
        s = s.arg(tr("Not Available"));
        break;
    case QNetworkSession::Connecting:
        s = s.arg(tr("Connecting"));
        break;
    case QNetworkSession::Connected:
        s = s.arg(tr("Connected"));
        break;
    case QNetworkSession::Closing:
        s = s.arg(tr("Closing"));
        break;
    case QNetworkSession::Disconnected:
        s = s.arg(tr("Disconnected"));
        break;
    case QNetworkSession::Roaming:
        s = s.arg(tr("Roaming"));
        break;
    default:
        s = s.arg(tr("Unknown"));
    }

    if (session->isOpen())
        s = s.arg(tr("Open"));
    else
        s = s.arg(tr("Closed"));

    tooltip += s;

    tooltip += tr("<br><br>Active time: %1 seconds").arg(session->activeTime());
    tooltip += tr("<br>Received data: %1 bytes").arg(session->bytesReceived());
    tooltip += tr("<br>Sent data: %1 bytes").arg(session->bytesWritten());

    setToolTip(tooltip);
}
//! [2]

//! [1]
void Cloud::newConfigurationActivated()
{
    QNetworkConfiguration::BearerType bearerType = configuration.bearerType();
    if (!svgCache.contains(bearerType)) {
        QSvgRenderer *renderer = 0;
        switch (bearerType) {
        case QNetworkConfiguration::BearerWLAN:
            renderer = new QSvgRenderer(QLatin1String(":wlan.svg"));
            break;
        case QNetworkConfiguration::BearerEthernet:
            renderer = new QSvgRenderer(QLatin1String(":lan.svg"));
            break;
        case QNetworkConfiguration::Bearer2G:
            renderer = new QSvgRenderer(QLatin1String(":cell.svg"));
            break;
        case QNetworkConfiguration::BearerBluetooth:
            renderer = new QSvgRenderer(QLatin1String(":bluetooth.svg"));
            break;
        case QNetworkConfiguration::BearerCDMA2000:
        case QNetworkConfiguration::BearerWCDMA:
        case QNetworkConfiguration::BearerHSPA:
            renderer = new QSvgRenderer(QLatin1String(":umts.svg"));
            break;
        default:
            renderer = new QSvgRenderer(QLatin1String(":unknown.svg"));
        }

        if (renderer)
            svgCache.insert(bearerType, renderer);
    }

    icon->setSharedRenderer(svgCache[bearerType]);

    if (configuration.name().isEmpty()) {
        text->setPlainText(tr("HIDDEN NETWORK"));
    } else {
        if (configuration.type() == QNetworkConfiguration::ServiceNetwork)
            text->setHtml("<b>" + configuration.name() + "</b>");
        else
            text->setPlainText(configuration.name());
    }

    const qreal height = icon->boundingRect().height() + text->boundingRect().height();

    icon->setPos(icon->boundingRect().width() / -2, height / -2);

    text->setPos(text->boundingRect().width() / -2,
                 height / 2 - text->boundingRect().height());

    stateChanged(session->state());
}
//! [1]

qreal Cloud::getRadiusForState(QNetworkConfiguration::StateFlags state)
{
    switch (state) {
    case QNetworkConfiguration::Active:
        return 100;
        break;
    case QNetworkConfiguration::Discovered:
        return 150;
        break;
    case QNetworkConfiguration::Defined:
        return 200;
        break;
    case QNetworkConfiguration::Undefined:
        return 250;
        break;
    default:
        return 300;
    }
}

