// SPDX-License-Identifier: LGPL-2.1-or-later
//
// SPDX-FileCopyrightText: 2016 Torsten Rahn <tackat@kde.org>
//

#include "tileprocessor.h"

#include <QDebug>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QPainter>
#include <QTextStream>

#include <cmath>

int TileProcessor::progress = 0;

TileProcessor::TileProcessor(QObject *parent)
    : QObject(parent)
    , m_tileLevel(14)
{
}

void TileProcessor::parseFileList(const QString &fileListUrl)
{
    m_fileList.clear();

    QDir rootDir(fileListUrl);

    QStringList dirList = rootDir.entryList(QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot);

    for (int i = 0; i < dirList.length(); ++i) {
        QString urlPath = fileListUrl + QLatin1Char('/') + dirList.at(i);
        QDir columnDir = QDir(urlPath);
        QStringList files = columnDir.entryList(QStringList() << "*.jpg", QDir::Files);
        for (int j = 0; j < files.length(); ++j) {
            QString filePath = urlPath + QLatin1Char('/') + files.at(j);
            m_fileList << filePath;
        }
    }
    qDebug() << "Total file count: " << m_fileList.length();
}

void TileProcessor::loadReferenceImages(const QString &maskPath, const QString &bathymetryPath)
{
    qDebug() << "Loading mask from" << maskPath;
    bool success = m_mask.load(maskPath);
    if (!success)
        qDebug() << "Loading mask failed: " << maskPath;
    qDebug() << "Loading bathymetry from" << bathymetryPath;
    success = m_bathymetry.load(bathymetryPath);
    if (!success)
        qDebug() << "Loading bathymetry failed: " << bathymetryPath;
    qDebug() << "Reference images loaded.";

    if (m_mask.width() != m_bathymetry.width() || m_mask.height() != m_bathymetry.height()) {
        qDebug() << "Mask and bathymetry geometries don't match:";
        qDebug() << "Mask: " << m_mask.width() << "x" << m_mask.height();
        qDebug() << "Bathymetry: " << m_bathymetry.width() << "x" << m_bathymetry.height();
    }
}

void TileProcessor::process()
{
    for (int i = 0; i < m_fileList.length(); ++i) {
        QFileInfo fileInfo(m_fileList.at(i));
        if (fileInfo.isFile()) {
            colorForFile(m_fileList.at(i));
        }
    }
}

void TileProcessor::colorForFile(const QString &filePath)
{
    ++progress;

    //    int tileCountBathymetry = pow(2, m_tileLevel);
    int tileCount = pow(2, m_tileLevel);

    int xTile = filePath.section(QLatin1Char('/'), -2, -2).toUInt();
    int yTile = filePath.section(QLatin1Char('/'), -1).section(QLatin1Char('.'), 0, 0).toUInt();
    int x = m_bathymetry.width() * xTile / (double)tileCount;

    qreal lat_rad = atan(sinh(M_PI * (1 - 2 * yTile / (double)tileCount)));
    int y = (int)(m_bathymetry.height() * (-lat_rad + M_PI / 2) / M_PI);

    int maskValueTopLeft = qRed(m_mask.pixel(2 * x, 2 * y));
    int maskValueTopRight = qRed(m_mask.pixel(2 * x + 1, 2 * y));
    int maskValueBottomLeft = qRed(m_mask.pixel(2 * x, 2 * y + 1));
    int maskValueBottomRight = qRed(m_mask.pixel(2 * x + 1, 2 * y + 1));

    if (maskValueTopLeft != 0 || maskValueTopRight != 0 || maskValueBottomLeft != 0 || maskValueBottomRight != 0) { // for all areas which are not black
        QColor bathymetryColor = QColor(m_bathymetry.pixel(x, y));

        QImage tile(256, 256, QImage::Format_RGB32);
        tile.fill(bathymetryColor);

        QImage origTile;
        bool success = origTile.load(filePath);

        if (!success)
            qDebug() << "Loading tile failed: " << filePath;

        QPainter painter;
        painter.begin(&tile);
        qreal opacity;
        opacity = 1.0 - (double)(maskValueTopLeft) / 255.0;
        painter.setOpacity(opacity);
        painter.drawImage(QRect(0, 0, 128, 128), origTile, QRect(0, 0, 128, 128));
        opacity = 1.0 - (double)(maskValueTopRight) / 255.0;
        painter.setOpacity(opacity);
        painter.drawImage(QRect(128, 0, 128, 128), origTile, QRect(128, 0, 128, 128));
        opacity = 1.0 - (double)(maskValueBottomLeft) / 255.0;
        painter.setOpacity(opacity);
        painter.drawImage(QRect(0, 128, 128, 128), origTile, QRect(0, 128, 128, 128));
        opacity = 1.0 - (double)(maskValueBottomRight) / 255.0;
        painter.setOpacity(opacity);
        painter.drawImage(QRect(128, 128, 128, 128), origTile, QRect(128, 128, 128, 128));
        painter.end();

        QString modFilePath = filePath;
        //        modFilePath = modFilePath.replace(".", "_mod.");

        tile.save(modFilePath, "JPG", 85);
        if (opacity > 0.0) {
            qDebug() << progress << filePath.section(QLatin1Char('/'), -2, -2) << filePath.section(QLatin1Char('/'), -1).section(QLatin1Char('.'), 0, 0);
            qDebug() << maskValueTopLeft << modFilePath;
        }
    } else {
        //        qDebug() << maskValue;
    }
}

#include "moc_tileprocessor.cpp"
