/***************************************************************************
 * C++ Implementation:                                                     *
 * Copyright (C) 2012-2017 by Eduard Kalinowski                            *
 * Germany, Lower Saxony, Hanover                                          *
 * eduard_kalinowski@yahoo.de                                              *
 *                                                                         *
 * HTTraQt is free software; may be distributed and/or modified under the  *
 * terms of the GNU General Public License version 3 as published by the   *
 * Free Software Foundation and appearing in the file LICENSE_GPLv3        *
 * included in the packaging of this file.                                 *
 *                                                                         *
 * This program is distributed in the hope that it will be useful,         *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
 * GNU General Public License for more details.                            *
 *                                                                         *
 * You should have received a copy of the GNU Lesser General Public        *
 * License along with HTTraQt. If not, see  http://www.gnu.org/licenses    *
 ***************************************************************************/

#include <stdio.h>
#include <stdlib.h>

#include <QtGui>
#include <QProgressBar>
#include <QTableView>
#include <QPushButton>

#ifndef NStatsBuffer
#define NStatsBuffer  14
#endif

#ifdef __cplusplus
extern "C" {
#endif


// #include <htscore.h>
#include "httrack-library.h"
#include "htsopt.h"

extern int hts_is_parsing(httrackp *opt, int flag);
extern int hts_setpause(httrackp *opt, int flag);
extern int hts_is_testing(httrackp *opt);
extern int hts_is_exiting(httrackp *opt);

#ifdef __cplusplus
}
#endif


#define DESCR_COLUMN    0
#define FILENAME_COLUMN 1
#define SIZE_COLUMN     2
#define CANCEL_COLUMN   3

#include "includes/httraqt.h"
#include "includes/ProgressTab.h"


ProgressTab::ProgressTab(QWidget *parent, Qt::WindowFlags fl)
    : QWidget(parent, fl)
{
    setupUi(this);

    this->parent = static_cast<HTTraQt*>(parent);
    this->parent->global_opt = NULL;

    progressSheet->setColumnCount(4);
    //     progressSheet->setColumnHidden(3 , true);
    progressSheet->setRowCount(NStatsBuffer);

    QPalette* palette1 = new QPalette();
    palette1->setColor(QPalette::ButtonText, Qt::red);

    // qDebug() << "progresstab" << NStatsBuffer;
    for (int i = 0; i < NStatsBuffer; i++) {
        progressSheet->setCellWidget(i, 0, new QLabel());

        QProgressBar* pb = new QProgressBar();
        pb->setRange(0, 1000);
        progressSheet->setRowHeight(i, 20);
        progressSheet->setCellWidget(i, 1, pb);

        progressSheet->setCellWidget(i, 2, new QLabel());
        // "<font color=darkred><b>X</b></font>"

        QPushButton *nb;
        nb = new QPushButton("X");
        nb->setToolTip(translate(_CANCEL)); // cancel downloading of current file
        nb->setPalette(*palette1);
        nb->setHidden(true);
        cancelButtons << nb;

        progressSheet->setCellWidget( i, 3, nb);// for cancelButtons
        //         progressSheet->cellWidget(i, 3)->setHidden(true);

        connect(nb, SIGNAL(pressed()), this, SLOT(cancelDwnload()));
    }

    //     for (int i = 0; i < NStatsBuffer; i++) {
    //         progressSheet->setRowHidden(i, (i >= this->parent->maxProgressRows));
    //     }
}


void ProgressTab::resizeEvent(QResizeEvent *event)
{
    int tableWidth = width();
    progressSheet->setColumnWidth(0, tableWidth * 0.12);
    progressSheet->setColumnWidth(1, tableWidth * 0.50);
    progressSheet->setColumnWidth(2, tableWidth * 0.12); // for size
    progressSheet->setColumnWidth(3, tableWidth * 0.10); // for "cancel" button
}


void ProgressTab::translateTab()
{
    setMinimumSize(410, 250);

    // ajust size(hight) to content
    //     progressSheet->setFixedHeight(progressSheet->document()->size().height() + progressSheet->contentsMargins().top()*2);
    //     int maxRows = 32;//parent->maxConnections;
    if (parent->programStyleSheet.length() > 0) {
        setStyleSheet(parent->programStyleSheet);
    }

    l_process->setText(translate(_INPROGRESS) + " " + parent->currentProject);
    //     groupBox->setTitle(translate(_INFO));
    l_saved->setText(translate(_BYTESSAVED));
    l_time->setText(translate(_TIME));
    l_rate->setText(translate(_TRRATE));
    l_actconn->setText(translate(_CONNECTIONS));
    l_scanned->setText(translate(_LINKSSCANNED));
    l_written->setText(translate(_FILESWR));
    l_updated->setText(translate(_FILESUP));
    l_errors->setText(translate(_ERRORS));

    QStringList horzHeaders;
    horzHeaders << translate(_OP)
                << QString(translate(_FILE) + "/" + translate(_PROGR))
                << translate(_SIZE)
                << "";

    progressSheet->setHorizontalHeaderLabels(horzHeaders);

    //     for (int i = 0; i < NStatsBuffer; i++) {
    //         progressSheet->setRowHidden(i, (i >= parent->maxProgressRows));
    //     }
}


void ProgressTab::cancelDwnload()
{
    QObject *p;
    p = sender();

    for(int i = 0; i < cancelButtons.count(); ++i) {
        if (p == cancelButtons[i]) {
            hts_cancel_file_push(parent->global_opt, parent->StatsBuffer[i].url_sav.toLatin1());
            break;
        }
    }
}


// Refresh
void ProgressTab::update()
{
    if (parent->global_opt == NULL) {
        return;
    }

    parent->mutex.lock();

    if (!parent->termine) {
        if (parent->SInfo.refresh) {
            hts_is_parsing(parent->global_opt, 0);        // refresh demandé si en mode parsing

            // while(INFILLMEM_LOCKED) Sleep(10);    // attendre au cas où
            if (!parent->termine) {
                inProcessRefresh();    // on refresh!
            }
        }

        //         parent->SInfo.ask_refresh = 1;
    }

    parent->mutex.unlock();
}


void ProgressTab::inProcessRefresh()
{
    static int toggle = 0;

    if (!((!parent->termine) && (!parent->termine_requested))) {
        return;
    }

    if (!parent->SInfo.refresh) {
        return;
    }

    QString lnk;

    l_process->setText(translate(_INPROGRESS) + " " + parent->currentProject);

#if USE_QT_VERSION == 6

    if (parent->SInfo.stat_back) {
        lnk.asprintf("%d/%d (+%d)", parent->SInfo.lien_n, parent->SInfo.lien_tot - 1, parent->SInfo.stat_back);
    } else {
        lnk.asprintf("%d/%d", parent->SInfo.lien_n, parent->SInfo.lien_tot - 1);
    }

#else

    if (parent->SInfo.stat_back) {
        lnk.sprintf("%d/%d (+%d)", parent->SInfo.lien_n, parent->SInfo.lien_tot - 1, parent->SInfo.stat_back);
    } else {
        lnk.sprintf("%d/%d", parent->SInfo.lien_n, parent->SInfo.lien_tot - 1);
    }

#endif

    bool isIconic = parent->trayIcon->isVisible();

    // not Iconmodus
    if (isIconic == false) {
        bool parsing = false;

        if (!parent->soft_term_requested) {
            if (!hts_setpause(parent->global_opt, -1)) {
                if (!(parsing = hts_is_parsing(parent->global_opt, -1))) {
                    inforun->setText(translate(_RECFILES));
                } else {
                    switch (hts_is_testing(parent->global_opt)) {
                        case 0:
                            inforun->setText(translate(_PARSHTML));
                            break;

                        case 1:
                            inforun->setText(translate(_TESTINGLINKS));
                            break;

                        case 2:
                            inforun->setText(translate(_PURG));
                            break;

                        case 3:
                            inforun->setText(translate(_LCACHE));
                            break;

                        case 4:
                            inforun->setText(translate(_WAITTIME));
                            break;

                        case 5:
                            inforun->setText(translate(_TRDATA));
                            break;
                    }
                }
            } else {
                if (((toggle++) / 5) % 2) {
                    inforun->setText(translate(_PAUSED));
                } else {
                    inforun->setText("");
                }
            }
        } else {
            if (((toggle++) / 5) % 2) {
                inforun->setText(translate(_STOPNOW));
            } else {
                inforun->setText("");
            }
        }

        if (parent->SInfo.stat_time > 0) {
            QString st = QString::number(parent->SInfo.stat_time);
            i1->setText(st);        // time
        } else {
            QString st = QString::number(parent->SInfo.stat_time);
            i1->setText(st);          // time
        }

        float mbytes = parent->SInfo.stat_bytes / (1024.0 * 1024.0);
#if USE_QT_VERSION == 6

        if (mbytes > 1.0 && mbytes < 1024.0) {
            i0->setText(QString().asprintf("%.2f MB", mbytes));       // bytes
        } else if (mbytes > 1024.0) {
            i0->setText(QString().asprintf("%.4f GB", mbytes / 1024.0));     // bytes
        } else {
            i0->setText(QString::number(parent->SInfo.stat_bytes));
        }

#else

        if (mbytes > 1.0 && mbytes < 1024.0) {
            i0->setText(QString().sprintf("%.2f MB", mbytes));       // bytes
        } else if (mbytes > 1024.0) {
            i0->setText(QString().sprintf("%.4f GB", mbytes / 1024.0));     // bytes
        } else {
            i0->setText(QString::number(parent->SInfo.stat_bytes));
        }

#endif
        i2->setText(lnk);    // scanned

        if (parent->SInfo.stat_nsocket > 0 /*&& parent->SInfo.stat_nsocket < 32*/) {
            QString st = QString::number(parent->SInfo.stat_nsocket);
            i3->setText(st);          // socks
        } else {
            i3->setText("none");       // wait
        }

        QString st;

        if (parent->SInfo.rate < 0 || parent->SInfo.rate > (1024.0 * 1024.0)) {
            parent->SInfo.rate = 0;
        }

#if USE_QT_VERSION == 6
        st.asprintf("%d (%d)", parent->SInfo.irate, parent->SInfo.rate);
#else
        st.sprintf("%d (%d)", parent->SInfo.irate, parent->SInfo.rate);
#endif
        i4->setText(st);    // rate

        i5->setText(QString::number(parent->SInfo.stat_errors));

        i6->setText(QString::number(parent->SInfo.stat_written));

        QString tempo;
        int pc = 0;

        if (parent->SInfo.stat_written) {
            pc = (int)((parent->SInfo.stat_updated * 100) / (parent->SInfo.stat_written));
        }

#if USE_QT_VERSION == 6

        if (pc) {
            tempo.asprintf("%d (%d%%)", parent->SInfo.stat_updated, pc);
        } else {
            tempo.asprintf("%d", parent->SInfo.stat_updated);
        }

#else

        if (pc) {
            tempo.sprintf("%d (%d%%)", parent->SInfo.stat_updated, pc);
        } else {
            tempo.sprintf("%d", parent->SInfo.stat_updated);
        }

#endif
        i7->setText(tempo);

        //         for (int j = 0; j < NStatsBuffer; j++) {
        //             progressSheet->setRowHidden(j, (j >= parent->maxProgressRows));
        //             //         progressSheet->cellWidget(i, CANCEL_COLUMN)->setHidden(false);
        //         }

        /*if (!parsing)*/
        {
            {
                for(int i = 0; i < NStatsBuffer; i++) {
                    if (parent->StatsBuffer[i].sizeTotal > 0) {
                        TStamp d = ((TStamp) parent->StatsBuffer[i].size * 1000);
                        d = d / ((TStamp) parent->StatsBuffer[i].sizeTotal);
                        parent->StatsBuffer[i].offset = (int) d;

                        QLabel *tsize = (QLabel*) progressSheet->cellWidget(i, SIZE_COLUMN);
                        qint64 sz = parent->StatsBuffer[i].sizeTotal;
                        QString s;
#if USE_QT_VERSION == 6

                        if (sz < 1e3) { // bytes
                            s.asprintf("%4.1f B", (float)sz);
                        } else if ((sz >= 1000) && (sz < 1e6)) { // kBytes
                            s.asprintf("%4.1f kB", (float)(sz / 1024.0));
                        } else if ((sz >= 1e6) && (sz < 1e9)) { // kBytes
                            s.asprintf("%4.1f MB", (float)(sz / (1024.0 * 1024.0)));
                        } else { // mbytes
                            s.asprintf("%4.1f GB", (float)(sz / (1024.0 * 1024.0 * 1024.0)));
                        }

#else

                        if (sz < 1e3) { // bytes
                            s.sprintf("%4.1f B", (float)sz);
                        } else if ((sz >= 1000) && (sz < 1e6)) { // kBytes
                            s.sprintf("%4.1f kB", (float)(sz / 1024.0));
                        } else if ((sz >= 1e6) && (sz < 1e9)) { // kBytes
                            s.sprintf("%4.1f MB", (float)(sz / (1024.0 * 1024.0)));
                        } else { // mbytes
                            s.sprintf("%4.1f GB", (float)(sz / (1024.0 * 1024.0 * 1024.0)));
                        }

#endif

                        if (s.length() > 0) {
                            tsize->setText(s);
                        }
                    } else {
                        parent->StatsBuffer[i].offset = 0;
                    }
                }
            }

            if (!parsing) {
                QProgressBar *p;
                p = (QProgressBar *) progressSheet->cellWidget(0, FILENAME_COLUMN);
                p->setRange(0, 1000);

                p = (QProgressBar *) progressSheet->cellWidget(0, FILENAME_COLUMN);
                p->setValue(parent->StatsBuffer[0].offset);
            }

            for (int j = 1; j < NStatsBuffer; j++) {
                QProgressBar *p;
                p = (QProgressBar *) progressSheet->cellWidget(j, FILENAME_COLUMN);
                p->setRange(0, 1000);

                p = (QProgressBar *) progressSheet->cellWidget(j, FILENAME_COLUMN);
                p->setValue(parent->StatsBuffer[j].offset);
            }

            // redraw en boucle
            {
                int i = 0;

                if (parsing) {
                    i++;
                }

                for( ; i < NStatsBuffer; i++) {
                    QString st;
                    QLabel *ti = (QLabel*) progressSheet->cellWidget(i, DESCR_COLUMN);
                    st = parent->StatsBuffer[i].strStatus;
                    st.replace("&", "&&");

                    if (st.length() == 0) {
                        progressSheet->cellWidget(i, CANCEL_COLUMN)->setHidden(true);

                        if (progressSheet->isRowHidden(i) == false) {
                            progressSheet->setRowHidden(i, true);
                        }
                    } else {
                        progressSheet->cellWidget(i, CANCEL_COLUMN)->setHidden(false);

                        if (progressSheet->isRowHidden(i) == true) {
                            progressSheet->setRowHidden(i, false);
                        }

                        ti->setText(st);

                        QProgressBar *p;
                        p = (QProgressBar *) progressSheet->cellWidget(i, FILENAME_COLUMN);
                        //ti = (QLabel*) progressSheet->cellWidget(i,FILENAME_COLUMN);
                        st = parent->StatsBuffer[i].name;
                        st.replace("&", "&&");
                        p->setFormat( st);

                        st = parent->StatsBuffer[i].file;
                        st.replace("&", "&&");
                        p->setToolTip(st);


                        //                         if (!parsing) {
                        //                             if (parent->StatsBuffer[i].strStatus.length() > 0){
                        //                                 progressSheet->cellWidget(i, CANCEL_COLUMN)->setHidden(false);
                        //                             }
                        //                             else{
                        //                                 progressSheet->cellWidget(i, CANCEL_COLUMN)->setHidden(true);
                        //                             }
                        if ((parent->StatsBuffer[i].strStatus.length() == 0) != (parent->StatsBuffer[i].actived)) {
                            parent->StatsBuffer[i].actived = !parent->StatsBuffer[i].actived;

                            if (!parent->StatsBuffer[i].actived) {
                                progressSheet->cellWidget(i, CANCEL_COLUMN)->setHidden(true);
                            } else {
                                progressSheet->cellWidget(i, CANCEL_COLUMN)->setHidden(false);
                            }
                        }

                        /*      } else {

                                  progressSheet->cellWidget(i, CANCEL_COLUMN)->setHidden(true);
                              }*/
                    }
                }
            }
            //
        }

        /* else*/
        if (parsing) {  // parsing
            //
            QProgressBar *p;
            p = (QProgressBar *) progressSheet->cellWidget(0, FILENAME_COLUMN);
            p->setRange(0, 100);
            p->setValue(parsing);

            QLabel *ti = (QLabel*) progressSheet->cellWidget(0, DESCR_COLUMN);
            ti->setText(translate(_SCANNING));

            p = (QProgressBar *) progressSheet->cellWidget(0, FILENAME_COLUMN);
            p->setFormat(parent->StatsBuffer[0].name);

        }
    }


    QString info;
    QTableWidgetItem * ti;

    if ((parent->SInfo.stat_nsocket == -1)) {
        ti = progressSheet->item(0, DESCR_COLUMN);

        if (ti == NULL) {
            return;
        }

        ti->setText(translate(_WAITSPECHOUR));
#if USE_QT_VERSION == 6

        if (isIconic == true /*&& ( !this_CSplitterFrame->iconifie )*/) {    // minimise mais pas en icone
            info.asprintf("[%d s]", parent->SInfo.stat_time);
            parent->trayIcon->setToolTip(info);
        } else {
            info =  translate(_MIRRWAIT);
            info.replace("%d", QString::number(parent->SInfo.stat_time));
        }

#else

        if (isIconic == true /*&& ( !this_CSplitterFrame->iconifie )*/) {    // minimise mais pas en icone
            info.sprintf("[%d s]", parent->SInfo.stat_time);
            parent->trayIcon->setToolTip(info);
        } else {
            info =  translate(_MIRRWAIT);
            info.replace("%d", QString::number(parent->SInfo.stat_time));
        }

#endif
    } else {
        if (isIconic == true ) {    // iconmodus
            info = QString("[" +  lnk + "]");
            parent->trayIcon->setToolTip(info);
        } else {
            QString byteb;
#if USE_QT_VERSION == 6

            if (parent->SInfo.stat_bytes > (1024.0 * 1024.0)) {
                byteb = QString().asprintf("%.2f MB", parent->SInfo.stat_bytes / (1024.0 * 1024.0));     // bytes
            } else {
                byteb = QString().asprintf("%d B", parent->SInfo.stat_bytes);
            }

#else

            if (parent->SInfo.stat_bytes > (1024.0 * 1024.0)) {
                byteb = QString().sprintf("%.2f MB", parent->SInfo.stat_bytes / (1024.0 * 1024.0));     // bytes
            } else {
                byteb = QString().sprintf("%d B", parent->SInfo.stat_bytes);
            }

#endif
            info = translate(_MIRRINPROGRESS);

            if (byteb.length() > 0) {
                info.replace("%s,", QString(lnk + ","));
                info.replace("%s", QString(byteb));
            } else {
                info.replace(", %s", lnk);
            }
        }
    }

    static QString last_info = "";

    if (info != last_info) {    /* a change */
        if (info.length() > 0) {
            last_info = info;
            parent->setWindowTitle(last_info);
        }
    }

    //             parent->clearStatsBuffer();
}



