/***************************************************************************
 * 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 <QtGui>
#include <QSettings>
#include <QRadioButton>


#include "../main/includes/httraqt.h"
#include "includes/OptionsDialog.h"


int OptionsDialog::headers[OPTION_SITES] = {_LINKS, _BUILD, _SCANRULEZ, _LIMITS, _PROXY, _EXPERTS, _MIMETYPES, _FLOWCONTROL,
                                            _SPIDER, _BROWSERID, _LOGINDEX
                                           };

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

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

    _tabTextInfos.clear();

    for (int i = 0; i < OPTION_SITES; i++) {
        tabBar->insertTab (i, translate(headers[i]));
    }

    connect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(switchPages(int)));

    pBuild = new optionsBuild(this);
    gridWidget->addWidget((QWidget*)pBuild);

    pBrowser = new optionsBrowser(this);
    gridWidget->addWidget((QWidget*)pBrowser);

    pFlow = new optionsFlow(this);
    gridWidget->addWidget((QWidget*)pFlow);

    pLimits = new optionsLimits(this);
    gridWidget->addWidget((QWidget*)pLimits);

    pLinks = new optionsLinks(this);
    gridWidget->addWidget((QWidget*)pLinks);

    pProxy = new optionsProxy(this);
    gridWidget->addWidget((QWidget*)pProxy);

    pRulez = new optionsRulez(this);
    gridWidget->addWidget((QWidget*)pRulez);

    pExperts = new optionsExperts(this);
    gridWidget->addWidget((QWidget*)pExperts);

    pLog = new optionsLog(this);
    gridWidget->addWidget((QWidget*)pLog);

    pSpider = new optionsSpider(this);
    gridWidget->addWidget((QWidget*)pSpider);

    pMime = new optionsMime(this);
    gridWidget->addWidget((QWidget*)pMime);

    initOptionsDialog();

    setFontForWidgets();

    QSettings s(QSettings::UserScope, "KarboSoft", "HTTraQt");
    QPoint pos = s.value("posSettings", QPoint(200, 200)).toPoint();
    QSize size = s.value("sizeSettings", QSize(700, 550)).toSize();
    resize(size);
    move(pos);

    connect(buttonOk, SIGNAL(clicked()), this, SLOT(onOk()));
    connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
    connect(pushDefault, SIGNAL(clicked()), this, SLOT(onSaveDefOptions()));
    connect(buttonHelp, SIGNAL(clicked()), this, SLOT(onHelp()));

    QWidget* p[] = {pLinks, pBuild, pRulez, pLimits, pProxy, pExperts, pMime, pFlow, pSpider, pBrowser, pLog};
    memcpy(pages, p, OPTION_SITES * sizeof(QWidget*));

    for (int i = 0; i < OPTION_SITES; i++) {
        pages[i]->adjustSize();
    }

    update();

    setToGUI();

    emit switchPages(0);
}


OptionsDialog::~OptionsDialog()
{
    QSettings s(QSettings::UserScope, "KarboSoft", "HTTraQt");
    s.setValue("posSettings", pos());
    s.setValue("sizeSettings", size());
    s.sync();

    delete pBuild;
    delete pBrowser;
    delete pFlow;
    delete pLimits;
    delete pLinks;
    delete pProxy;
    delete pRulez;
    delete pExperts;
    delete pLog;
    delete pSpider;
    delete pMime;
}


void OptionsDialog::setFontForWidgets(void)
{
    QFont f = parent->sysFont;

    setFont(f);

    pBuild->setFont(f);
    pBrowser->setFont(f);
    pFlow->setFont(f);
    pLimits->setFont(f);
    pLinks->setFont(f);
    pProxy->setFont(f);
    pRulez->setFont(f);
    pExperts->setFont(f);
    pLog->setFont(f);
    pSpider->setFont(f);
    pMime->setFont(f);
}


void OptionsDialog::initOptionsDialog()
{
    QVector<trWidgets>::iterator ivec;

    for (ivec = _tabTextInfos.begin(); ivec != _tabTextInfos.end(); ++ivec) {
        (*ivec).value = prOptions[ (*ivec).idString ];
#ifdef MY_DEBUG

        if ((*ivec).opttype != prOptions[ (*ivec).idString ].type) {
            qDebug() << "set to gui" << iopt.key() << "not found in gui!";
        }

#endif
    }
}


void OptionsDialog::getFromGUI()
{
    for (QVector<trWidgets>::iterator ivec = _tabTextInfos.begin(); ivec != _tabTextInfos.end(); ++ivec) {
        QMetaType::Type optType = (QMetaType::Type)(*ivec).value.type();

        switch ((*ivec).wtype) {
            case CHECKBOX:
                (*ivec).value = ((QCheckBox*)(*ivec).wg)->isChecked() ? 1 : 0;
                break;

            case EDITLINE: {
                if ( optType == QMetaType::Int) {
                    if (((QLineEdit*)(*ivec).wg)->text().length() > 0) {
                        (*ivec).value = ((QLineEdit*)(*ivec).wg)->text().toInt();
                    }
                } else {
                    (*ivec).value = -1;
                }

                if (optType == QMetaType::Float) {
                    if (((QLineEdit*)(*ivec).wg)->text().length() > 0) {
                        (*ivec).value = ((QLineEdit*)(*ivec).wg)->text().toFloat();
                    } else {
                        (*ivec).value = -1.0;
                    }
                }

                if (optType == QMetaType::QString) {
                    (*ivec).value = ((QLineEdit*)(*ivec).wg)->text();
                }

                break;
            }

            case LABEL: {
                if (optType == QMetaType::QString) {
                    (*ivec).value = ((QLabel*)(*ivec).wg)->text();
                }

                break;
            }

            case TEXTEDIT: { // this one only for rulez->scanList
                (*ivec).value = (((QTextEdit*)(*ivec).wg)->toPlainText()).replace("\n", " ").simplified();
                break;
            }

            case RADIO: // not exists
                break;

            case GROUPBOX: {
                if (optType == QMetaType::Int) {
                    (*ivec).value = ((QGroupBox*)(*ivec).wg)->isChecked() ? 1 : 0;
                }

                break;
            }

            case COMBOBOX: {
                if (optType == QMetaType::QString) {
                    (*ivec).value = ((QComboBox*)(*ivec).wg)->currentText();
                }

                if (optType == QMetaType::Int || optType == QMetaType::Float) {
                    bool ok;
                    QString ct = ((QComboBox*)(*ivec).wg)->currentText();

                    if (ct == "" || ct == "-") {
                        //                                 qDebug() << "get options combo" << (*ivec).idString << (*ivec).value;
                        if (optType == QMetaType::Int ) {
                            (*ivec).value = -1;
                        }

                        if (optType == QMetaType::Float ) {
                            (*ivec).value = -1.0;
                        }
                    } else {
                        if (optType == QMetaType::Int ) {
                            int  num = ct.toInt(&ok);

                            if (ok == true) {
                                (*ivec).value = num;
                            } else {
                                (*ivec).value = ((QComboBox*)(*ivec).wg)->currentIndex();
                            }
                        } else {
                            float  num = ct.toFloat(&ok);

                            if (ok == true) {
                                (*ivec).value = num;
                            } else {
                                (*ivec).value = ((QComboBox*)(*ivec).wg)->currentIndex();
                            }
                        }
                    }
                }

                break;
            }
        }

        prOptions[ (*ivec).idString ] = (*ivec).value;
    }
}


void OptionsDialog::setToGUI()
{
    for (QVector<trWidgets>::iterator ivec = _tabTextInfos.begin(); ivec != _tabTextInfos.end(); ++ivec) {
        QMetaType::Type optTypeLo = (QMetaType::Type)(*ivec).value.type();// & 0x0f;
        //         bool nonZero = (((*ivec).opttype & 0x80) != 0);

        switch ((*ivec).wtype) {
            case LABEL: {
                if((*ivec).idTr != -1) {
                    QString t = translate((*ivec).idTr);
                    ((QLabel*)(*ivec).wg)->setText(t.replace("\n", " "));
                } else {
                    QString t = translate((*ivec).value.toInt());
                    ((QLabel*)(*ivec).wg)->setText(t.replace("\n", " "));
                }

                break;
            }

            case TEXTEDIT: { // this one only for rulez->scanList, without translation
                ((QTextEdit*)(*ivec).wg)->setText((*ivec).value.toString());
                break;
            }

            case BUTTON: {
                if((*ivec).idTr != -1) {
                    ((QPushButton*)(*ivec).wg)->setText(translate((*ivec).idTr));
                }

                break;
            }

            case CHECKBOX: {
                if((*ivec).idTr != -1) {
                    QString t = translate((*ivec).idTr);
                    ((QCheckBox*)(*ivec).wg)->setText(t.replace("\n", " "));
                }

                if (optTypeLo != QMetaType::QString) {
                    if ((*ivec).value.toInt() == 1) {
                        ((QCheckBox*)(*ivec).wg)->setCheckState(Qt::Checked);
                    } else {
                        ((QCheckBox*)(*ivec).wg)->setCheckState(Qt::Checked); // for toggling
                        ((QCheckBox*)(*ivec).wg)->setCheckState(Qt::Unchecked);
                    }
                }

                break;
            }

            case GROUPBOX: {
                if((*ivec).idTr != -1) {
                    ((QGroupBox*)(*ivec).wg)->setTitle(translate((*ivec).idTr));
                }

                if (optTypeLo == QMetaType::Int) {
                    if ((*ivec).value.toInt() == 1) {
                        ((QGroupBox*)(*ivec).wg)->setChecked(true);
                    } else {
                        ((QGroupBox*)(*ivec).wg)->setChecked(false);
                    }
                }

                break;
            }

            case COMBOBOX: {
                if (optTypeLo == QMetaType::QString) {
                    int index = ((QComboBox*)(*ivec).wg)->findText((*ivec).value.toString());

                    if (index >= 0) {
                        ((QComboBox*)(*ivec).wg)->setCurrentIndex(index);
                    } else {
                        QString t = (*ivec).value.toString();
                        ((QComboBox*)(*ivec).wg)->addItem(t);
                        int tInd = ((QComboBox*)(*ivec).wg)->findText(t);
                        ((QComboBox*)(*ivec).wg)->setCurrentIndex(tInd);
                    }

                    break;
                }

                int num;

                if (((QComboBox*)(*ivec).wg)->findText("") == -1) {
                    num = (*ivec).value.toInt();
                    ((QComboBox*)(*ivec).wg)->setCurrentIndex(num);
                    break;
                }

                if (optTypeLo == QMetaType::Int) {
                    int pos;

                    num = (*ivec).value.toInt();

                    if ( num == -1 ) {
                        pos = ((QComboBox*)(*ivec).wg)->findText("");
                        ((QComboBox*)(*ivec).wg)->setCurrentIndex(pos);
                    } else {
                        QString st = QString::number(num);
                        insertInCombo(*(QComboBox*)(*ivec).wg, st);
                    }

                    break;
                }

                if (optTypeLo == QMetaType::Float) {
                    int pos;

                    // qDebug() << "set to gui" << (*ivec).idString << (*ivec).value;
                    if ((*ivec).value.toFloat() == -1.0 ) {
                        pos = ((QComboBox*)(*ivec).wg)->findText("");
                        ((QComboBox*)(*ivec).wg)->setCurrentIndex(pos);
                    } else {
                        QString st = QString::number((*ivec).value.toFloat());
                        insertInCombo(*(QComboBox*)(*ivec).wg, st);
                    }

                    break;
                }
            }

            case RADIO: {
                if((*ivec).idTr != -1) {
                    QString t = translate((*ivec).idTr);
                    ((QRadioButton*)(*ivec).wg)->setText(t.replace("\n", " "));
                }

                break;
            }

            case EDITLINE: {// no translate for edit widget
                if (optTypeLo == QMetaType::Int) {
                    if ((*ivec).value.toInt() == -1 ) {
                        ((QLineEdit*)(*ivec).wg)->setText("");
                    } else {
                        ((QLineEdit*)(*ivec).wg)->setText(QString::number((*ivec).value.toInt()));
                    }

                    break;
                }

                if (optTypeLo == QMetaType::Float) {
                    if ((*ivec).value.toFloat() == -1.0 ) {
                        ((QLineEdit*)(*ivec).wg)->setText("");
                    } else {
                        ((QLineEdit*)(*ivec).wg)->setText(QString::number((*ivec).value.toFloat()));
                    }

                    break;
                }

                if (optTypeLo == QMetaType::QString) {
                    ((QLineEdit*)(*ivec).wg)->setText((*ivec).value.toString());
                    break;
                }
            }
        }
    }
}


void OptionsDialog::insertInCombo( QComboBox &box, const QString &s)
{
    float tmp;
    bool conv;

    tmp = s.toFloat(&conv);

    if (conv == false) {
        qDebug() << "convert error" << s << "to float";
        return;
    }

    if (box.count() < 2) {
        return;
    }

    for(int ib = 1; ib != box.count() - 1; ++ib) { // the first is "space" or -1
        float a, b;
        a = box.itemText(ib).toFloat();

        if (tmp < a) {
            continue;
        }

        b = box.itemText(ib + 1).toFloat();

        if (tmp == a) {
            box.setCurrentIndex(ib);
            return; // exists
        }

        if (tmp == b) {
            box.setCurrentIndex(ib + 1);
            return; // exists
        }

        if (tmp < b) {
            box.insertItem(ib + 1, s);
            return;
        }
    }
}


void OptionsDialog::onHelp()
{
    QDesktopServices::openUrl(QUrl::fromLocalFile(qPrintable( parent->helpDir + "/step9.html")));
}


void OptionsDialog::switchPages(int n)
{
    QToolButton* s = (QToolButton*)sender();

    if (n == -1) {
        return;
    }

    for (int i = 0; i < OPTION_SITES; i++) {
        if (i == n) {
            pages[i]->show();
            continue;
        }

        pages[i]->hide();
    }
}


void OptionsDialog::onResetDefOptions()
{
    parent->initOptions();
    parent->writeSettings(true);
}


void OptionsDialog::onSaveDefOptions()
{
    getFromGUI();
    parent->writeSettings(true);
}


void OptionsDialog::onOk()
{
    getFromGUI();
    parent->writeSettings(false); // project settings

    reject();
}





