/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtLocation module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later 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 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qgeotiledmap_p.h"
#include "qgeotiledmap_p_p.h"
#include <QtPositioning/private/qwebmercator_p.h>
#include "qgeotiledmappingmanagerengine_p.h"
#include "qabstractgeotilecache_p.h"
#include "qgeotilespec_p.h"
#include "qgeoprojection_p.h"

#include "qgeocameratiles_p.h"
#include "qgeotilerequestmanager_p.h"
#include "qgeotiledmapscene_p.h"
#include "qgeocameracapabilities_p.h"
#include <cmath>

QT_BEGIN_NAMESPACE
#define PREFETCH_FRUSTUM_SCALE 2.0

static const double invLog2 = 1.0 / std::log(2.0);

static double zoomLevelFrom256(double zoomLevelFor256, double tileSize)
{
    return std::log( std::pow(2.0, zoomLevelFor256) * 256.0 / tileSize ) * invLog2;
}

QGeoTiledMap::QGeoTiledMap(QGeoTiledMappingManagerEngine *engine, QObject *parent)
    : QGeoMap(*new QGeoTiledMapPrivate(engine), parent)
{
    Q_D(QGeoTiledMap);

    d->m_tileRequests = new QGeoTileRequestManager(this, engine);

    QObject::connect(engine,&QGeoTiledMappingManagerEngine::tileVersionChanged,
                     this,&QGeoTiledMap::handleTileVersionChanged);
    QObject::connect(this, &QGeoMap::cameraCapabilitiesChanged,
                     [d](const QGeoCameraCapabilities &oldCameraCapabilities) {
                       d->onCameraCapabilitiesChanged(oldCameraCapabilities);
                     });
}

QGeoTiledMap::QGeoTiledMap(QGeoTiledMapPrivate &dd, QGeoTiledMappingManagerEngine *engine, QObject *parent)
    : QGeoMap(dd, parent)
{
    Q_D(QGeoTiledMap);

    d->m_tileRequests = new QGeoTileRequestManager(this, engine);

    QObject::connect(engine,&QGeoTiledMappingManagerEngine::tileVersionChanged,
                     this,&QGeoTiledMap::handleTileVersionChanged);
    QObject::connect(this, &QGeoMap::cameraCapabilitiesChanged,
                     [d](const QGeoCameraCapabilities &oldCameraCapabilities) {
                       d->onCameraCapabilitiesChanged(oldCameraCapabilities);
                     });
}

QGeoTiledMap::~QGeoTiledMap()
{
    Q_D(QGeoTiledMap);
    delete d->m_tileRequests;
    d->m_tileRequests = 0;

    if (!d->m_engine.isNull()) {
        QGeoTiledMappingManagerEngine *engine = qobject_cast<QGeoTiledMappingManagerEngine*>(d->m_engine);
        Q_ASSERT(engine);
        engine->releaseMap(this);
    }
}

QGeoTileRequestManager *QGeoTiledMap::requestManager()
{
    Q_D(QGeoTiledMap);
    return d->m_tileRequests;
}

void QGeoTiledMap::updateTile(const QGeoTileSpec &spec)
{
    Q_D(QGeoTiledMap);
    d->updateTile(spec);
}

void QGeoTiledMap::setPrefetchStyle(QGeoTiledMap::PrefetchStyle style)
{
    Q_D(QGeoTiledMap);
    d->m_prefetchStyle = style;
}

QAbstractGeoTileCache *QGeoTiledMap::tileCache()
{
    Q_D(QGeoTiledMap);
    return d->m_cache;
}

QSGNode *QGeoTiledMap::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window)
{
    Q_D(QGeoTiledMap);
    return d->updateSceneGraph(oldNode, window);
}

void QGeoTiledMap::prefetchData()
{
    Q_D(QGeoTiledMap);
    d->prefetchTiles();
}

void QGeoTiledMap::clearData()
{
    Q_D(QGeoTiledMap);
    d->m_cache->clearAll();
    d->m_mapScene->clearTexturedTiles();
    d->updateScene();
    sgNodeChanged();
}

QGeoMap::Capabilities QGeoTiledMap::capabilities() const
{
    return Capabilities(SupportsVisibleRegion
                        | SupportsSetBearing
                        | SupportsAnchoringCoordinate
                        | SupportsVisibleArea);
}

void QGeoTiledMap::setCopyrightVisible(bool visible)
{
    Q_D(QGeoTiledMap);
    if (visible == d->m_copyrightVisible)
        return;

    QGeoMap::setCopyrightVisible(visible);
    if (visible)
        evaluateCopyrights(d->m_mapScene->visibleTiles());
}

void QGeoTiledMap::clearScene(int mapId)
{
    Q_D(QGeoTiledMap);
    if (activeMapType().mapId() == mapId)
        d->clearScene();
}

void QGeoTiledMap::handleTileVersionChanged()
{
    Q_D(QGeoTiledMap);
    if (!d->m_engine.isNull()) {
        QGeoTiledMappingManagerEngine* engine = qobject_cast<QGeoTiledMappingManagerEngine*>(d->m_engine);
        Q_ASSERT(engine);
        d->changeTileVersion(engine->tileVersion());
    }
}

void QGeoTiledMap::evaluateCopyrights(const QSet<QGeoTileSpec> &visibleTiles)
{
    Q_UNUSED(visibleTiles);
}

QGeoTiledMapPrivate::QGeoTiledMapPrivate(QGeoTiledMappingManagerEngine *engine)
    : QGeoMapPrivate(engine, new QGeoProjectionWebMercator),
      m_cache(engine->tileCache()),
      m_visibleTiles(new QGeoCameraTiles()),
      m_prefetchTiles(new QGeoCameraTiles()),
      m_mapScene(new QGeoTiledMapScene()),
      m_tileRequests(0),
      m_maxZoomLevel(static_cast<int>(std::ceil(m_cameraCapabilities.maximumZoomLevel()))),
      m_minZoomLevel(static_cast<int>(std::ceil(m_cameraCapabilities.minimumZoomLevel()))),
      m_prefetchStyle(QGeoTiledMap::PrefetchTwoNeighbourLayers)
{
    int tileSize = m_cameraCapabilities.tileSize();
    QString pluginString(engine->managerName() + QLatin1Char('_') + QString::number(engine->managerVersion()));
    m_visibleTiles->setTileSize(tileSize);
    m_prefetchTiles->setTileSize(tileSize);
    m_visibleTiles->setPluginString(pluginString);
    m_prefetchTiles->setPluginString(pluginString);
    m_mapScene->setTileSize(tileSize);
}

QGeoTiledMapPrivate::~QGeoTiledMapPrivate()
{
    // controller_ is a child of map_, don't need to delete it here

    delete m_mapScene;
    delete m_visibleTiles;
    delete m_prefetchTiles;

    // TODO map items are not deallocated!
    // However: how to ensure this is done in rendering thread?
}

void QGeoTiledMapPrivate::prefetchTiles()
{
    if (m_tileRequests && m_prefetchStyle != QGeoTiledMap::NoPrefetching) {

        QSet<QGeoTileSpec> tiles;
        QGeoCameraData camera = m_visibleTiles->cameraData();
        int currentIntZoom = static_cast<int>(std::floor(camera.zoomLevel()));

        m_prefetchTiles->setCameraData(camera);
        m_prefetchTiles->setViewExpansion(PREFETCH_FRUSTUM_SCALE);
        tiles = m_prefetchTiles->createTiles();

        switch (m_prefetchStyle) {

        case QGeoTiledMap::PrefetchNeighbourLayer: {
            double zoomFraction = camera.zoomLevel() - currentIntZoom;
            int nearestNeighbourLayer = zoomFraction > 0.5 ? currentIntZoom + 1 : currentIntZoom - 1;
            if (nearestNeighbourLayer <= m_maxZoomLevel && nearestNeighbourLayer >= m_minZoomLevel) {
                camera.setZoomLevel(nearestNeighbourLayer);
                // Approx heuristic, keeping total # prefetched tiles roughly independent of the
                // fractional zoom level.
                double neighbourScale = (1.0 + zoomFraction)/2.0;
                m_prefetchTiles->setCameraData(camera);
                m_prefetchTiles->setViewExpansion(PREFETCH_FRUSTUM_SCALE * neighbourScale);
                tiles += m_prefetchTiles->createTiles();
            }
        }
            break;

        case QGeoTiledMap::PrefetchTwoNeighbourLayers: {
            // This is a simpler strategy, we just prefetch from layer above and below
            // for the layer below we only use half the size as this fills the screen
            if (currentIntZoom > m_minZoomLevel) {
                camera.setZoomLevel(currentIntZoom - 1);
                m_prefetchTiles->setCameraData(camera);
                m_prefetchTiles->setViewExpansion(0.5);
                tiles += m_prefetchTiles->createTiles();
            }

            if (currentIntZoom < m_maxZoomLevel) {
                camera.setZoomLevel(currentIntZoom + 1);
                m_prefetchTiles->setCameraData(camera);
                m_prefetchTiles->setViewExpansion(1.0);
                tiles += m_prefetchTiles->createTiles();
            }
        }
            break;

        default:
            break;
        }

        m_tileRequests->requestTiles(tiles - m_mapScene->texturedTiles());
    }
}

QGeoMapType QGeoTiledMapPrivate::activeMapType()
{
    return m_visibleTiles->activeMapType();
}

// Called before changeCameraData
void QGeoTiledMapPrivate::onCameraCapabilitiesChanged(const QGeoCameraCapabilities &oldCameraCapabilities)
{
    // Handle varying min/maxZoomLevel
    if (oldCameraCapabilities.minimumZoomLevel() != m_cameraCapabilities.minimumZoomLevel())
        m_minZoomLevel = static_cast<int>(std::ceil(m_cameraCapabilities.minimumZoomLevel()));
    if (oldCameraCapabilities.maximumZoomLevel() != m_cameraCapabilities.maximumZoomLevel())
        m_maxZoomLevel = static_cast<int>(std::ceil(m_cameraCapabilities.maximumZoomLevel()));

    // Handle varying tile size
    if (oldCameraCapabilities.tileSize() != m_cameraCapabilities.tileSize()) {
        m_visibleTiles->setTileSize(oldCameraCapabilities.tileSize());
        m_prefetchTiles->setTileSize(oldCameraCapabilities.tileSize());
        m_mapScene->setTileSize(oldCameraCapabilities.tileSize());
    }
}

void QGeoTiledMapPrivate::changeCameraData(const QGeoCameraData &cameraData)
{
    Q_Q(QGeoTiledMap);

    QGeoCameraData cam = cameraData;

    // The incoming zoom level is intended for a tileSize of 256.
    // Adapt it to the current tileSize
    double zoomLevel = cameraData.zoomLevel();
    if (m_visibleTiles->tileSize() != 256)
        zoomLevel = zoomLevelFrom256(zoomLevel, m_visibleTiles->tileSize());
    cam.setZoomLevel(zoomLevel);

    // For zoomlevel, "snap" 0.01 either side of a whole number.
    // This is so that when we turn off bilinear scaling, we're
    // snapped to the exact pixel size of the tiles
    int izl = static_cast<int>(std::floor(cam.zoomLevel()));
    float delta = cam.zoomLevel() - izl;

    if (delta > 0.5) {
        izl++;
        delta -= 1.0;
    }

    // TODO: Don't do this if there's tilt or bearing.
    if (qAbs(delta) < 0.01) {
        cam.setZoomLevel(izl);
    }

    m_visibleTiles->setCameraData(cam);
    m_mapScene->setCameraData(cam);

    updateScene();
    q->sgNodeChanged(); // ToDo: explain why emitting twice
}

void QGeoTiledMapPrivate::updateScene()
{
    Q_Q(QGeoTiledMap);
    // detect if new tiles introduced
    const QSet<QGeoTileSpec>& tiles = m_visibleTiles->createTiles();
    bool newTilesIntroduced = !m_mapScene->visibleTiles().contains(tiles);
    m_mapScene->setVisibleTiles(tiles);

    if (newTilesIntroduced && m_copyrightVisible)
        q->evaluateCopyrights(tiles);

    // don't request tiles that are already built and textured
    QMap<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > cachedTiles =
            m_tileRequests->requestTiles(m_visibleTiles->createTiles() - m_mapScene->texturedTiles());

    for (auto it = cachedTiles.cbegin(); it != cachedTiles.cend(); ++it)
        m_mapScene->addTile(it.key(), it.value());

    if (!cachedTiles.isEmpty())
        emit q->sgNodeChanged();
}

void QGeoTiledMapPrivate::setVisibleArea(const QRectF &visibleArea)
{
    Q_Q(QGeoTiledMap);
    const QRectF va = clampVisibleArea(visibleArea);
    if (va == m_visibleArea)
        return;

    m_visibleArea = va;
    m_geoProjection->setVisibleArea(va);

    m_visibleTiles->setVisibleArea(va);
    m_prefetchTiles->setVisibleArea(va);
    m_mapScene->setVisibleArea(va);

     if (m_copyrightVisible)
        q->evaluateCopyrights(m_mapScene->visibleTiles());
    updateScene();
    q->sgNodeChanged(); // ToDo: explain why emitting twice
}

QRectF QGeoTiledMapPrivate::visibleArea() const
{
    return m_visibleArea;
}

void QGeoTiledMapPrivate::changeActiveMapType(const QGeoMapType mapType)
{
    m_visibleTiles->setTileSize(m_cameraCapabilities.tileSize());
    m_prefetchTiles->setTileSize(m_cameraCapabilities.tileSize());
    m_mapScene->setTileSize(m_cameraCapabilities.tileSize());
    m_visibleTiles->setMapType(mapType);
    m_prefetchTiles->setMapType(mapType);
    changeCameraData(m_cameraData); // Updates the zoom level to the possibly new tile size
    // updateScene called in changeCameraData()
}

void QGeoTiledMapPrivate::changeTileVersion(int version)
{
    m_visibleTiles->setMapVersion(version);
    m_prefetchTiles->setMapVersion(version);
    updateScene();
}

void QGeoTiledMapPrivate::clearScene()
{
    m_mapScene->clearTexturedTiles();
    m_mapScene->setVisibleTiles(QSet<QGeoTileSpec>());
    updateScene();
}

void QGeoTiledMapPrivate::changeViewportSize(const QSize& size)
{
    Q_Q(QGeoTiledMap);

    m_visibleTiles->setScreenSize(size);
    m_prefetchTiles->setScreenSize(size);
    m_mapScene->setScreenSize(size);


    if (!size.isEmpty() && m_cache) {
        // absolute minimum size: one tile each side of display, 32-bit colour
        int texCacheSize = (size.width() + m_visibleTiles->tileSize() * 2) *
                (size.height() + m_visibleTiles->tileSize() * 2) * 4;

        // multiply by 3 so the 'recent' list in the cache is big enough for
        // an entire display of tiles
        texCacheSize *= 3;
        // TODO: move this reasoning into the tilecache

        int newSize = qMax(m_cache->minTextureUsage(), texCacheSize);
        m_cache->setMinTextureUsage(newSize);
    }

    if (m_copyrightVisible)
        q->evaluateCopyrights(m_mapScene->visibleTiles());
    updateScene();
}

void QGeoTiledMapPrivate::updateTile(const QGeoTileSpec &spec)
{
     Q_Q(QGeoTiledMap);
    // Only promote the texture up to GPU if it is visible
    if (m_visibleTiles->createTiles().contains(spec)){
        QSharedPointer<QGeoTileTexture> tex = m_tileRequests->tileTexture(spec);
        if (!tex.isNull() && !tex->image.isNull()) {
            m_mapScene->addTile(spec, tex);
            emit q->sgNodeChanged();
        }
    }
}

QSGNode *QGeoTiledMapPrivate::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window)
{
    return m_mapScene->updateSceneGraph(oldNode, window);
}

QT_END_NAMESPACE
