// bytran -|- spectral calculations for portable devices using the HITRAN database
//
// Developed by Dzianis Pliutau (Denis Plutov) and Kostya Roslyakov
// www.bytran.org | bytran@bytran.org
// Copyright (c) 2016 Dzianis Pliutau
// Distributed under the MIT license
//
// The MIT License (MIT)
// Copyright (c) 2016 Dzianis Pliutau
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.



// Object is used to download TIPS files from the HITRAN server
#include "tipsfilesdownloader.h"
#include <QMessageBox>
#include <QDir>
#include <QFileInfo>
#include <QApplication>

TipsFilesDownloader::TipsFilesDownloader(QObject *parent) : QObject(parent)
{
    // File downloader
    downloader = new FileDownloader();
    downloader->setSaveToHarddrive(true);

    // Method to create connections
    createActions();
}

// Method to create actions
void TipsFilesDownloader::createActions()
{
    connect(this->downloader, SIGNAL(dataDownloaded(QByteArray*,bool)), this, SLOT(tipsOneFileDownloadComplete(QByteArray*,bool)));
}

// Methods to get and set the TIPS download folders
QString TipsFilesDownloader::getTipsDownloadPath() { return this->tipsDownloadPath; }
void TipsFilesDownloader::setTipsDownloadPath(QString newTipsDownloadPath) { this->tipsDownloadPath = newTipsDownloadPath; }

// Methods to get and set the save folder on the local device where the TIPS files would be stored
QString TipsFilesDownloader::getTipsFolder() { return this->tipsFolder; }
void TipsFilesDownloader::setTipsFolder(QString newTipsFolder) { this->tipsFolder = newTipsFolder; }

// Method to initiate the download of TIPS files
void TipsFilesDownloader::downloadTipsFiles()
{
    int i; // Loop variable
    int j; // Loop variable


    // Forming an array of TIPS file names to attempt to download
    tipsFileNames.clear();
    for (i = 0; i < mol->count(); i++)
    {
        for (j = 0; j < (*mol)[i].getIso()->count(); j++)
        {
            if (((*mol)[i]).getIsoAt(j)->getTipsFileAvailableOnHitranServer() == true)
            {
                tipsFileNames.append("q" + QString::number(((*mol)[i]).getIsoAt(j)->getGlobalId()) + ".txt");
            }
        }
    }

    // Intializing variables
    this->numDownloaded = 0;
    this->numAttempted = 0;

    // Initiating download of a single TIPS file
    downloadOneTipsFile();
}

// Method to download a single TIPS file
void TipsFilesDownloader::downloadOneTipsFile()
{
    QString filePath;   // Path to the file on a remote server to download
    QByteArray byteArray;  // Blank byte array


    // Setting the file path to download a TIPS file from the remote server
    filePath = this->tipsFolder + "/" + tipsFileNames[this->numAttempted];

    // Check if the file already exists locally (download only if file is not already there)
    QFileInfo checkFile(filePath);  //  "/" is not added because it is already there

    if (!checkFile.exists())
    {
        // Setting the download path on a remote server
        downloader->setDownloadPath(this->tipsDownloadPath + tipsFileNames[this->numAttempted]);
        downloader->setSavePath(filePath);

        // Initiating the download
        downloader->download();
    }
    else
    {
        // Switching to the next file
        tipsOneFileDownloadComplete(&byteArray, true); // Not downloaded but returning true because file is already present to avoid displaying an error to the user
    }
}

// Slot executed once download for a single file is complete
void TipsFilesDownloader::tipsOneFileDownloadComplete(QByteArray *data, bool success)
{
    // Need to have a delay after the mesage and inform user of unsuccesful downloads

    // Incrementing the number of downloaded files if the download has been successful
    if (success) { this->numDownloaded++; }
    this->numAttempted++;

    // Informing the user about the number of downloaded files
    if (numAttempted >= tipsFileNames.count())
    {
        // Clearing the notification area
        emit notify("", 0, false, false);

        // If the number of downloaded files is larger than 0, then informing the user that files have been downloaded
        if ((numAttempted > 0) && (numDownloaded > 0)) { emit tipsFilesDownloaded(true); }
                                                  else { emit tipsFilesDownloaded(false); }
    }
    else
    {
        // Only notifying of the file download if it was succesful
        if (success) { emit notify("Please wait for this task to complete.\nInitializing application. Downloading\nTIPS from HITRANonline (HITRAN.org)\nAcquired TIPS file: " + tipsFileNames[this->numAttempted] + " of " + QString::number(tipsFileNames.count()) + " files.", 0, true, false); }

        // Downloading the next TIPS file
        downloadOneTipsFile();
    }
}

// Method to set a reference to the molecules array
void TipsFilesDownloader::setMolArray(QVector<HitranOneMol> *newMol) { this->mol = newMol; }
