/***************************************************************************
 * C++ Implementation:                                                     *
 * Copyright (C) 2012-2014 by Eduard Kalinowski                            *
 * Germany, Lower Saxony, Hanover                                          *
 * eduard_kalinowski@yahoo.de                                              *
 *                                                                         *
 * HTTraQt is free software; you can redistribute it and/or                *
 * modify it under the terms of the GNU Lesser General Public              *
 * License as published by the Free Software Foundation; either            *
 * version 3 of the License, or (at your option) any later version.        *
 *                                                                         *
 * HTTraQt 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 Lesser 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();

    QToolButton* b[] = {buttonLinks, buttonBuild, buttonRulez, buttonLimits, buttonProxy,
                        buttonExperts, buttonMime, buttonFlow, buttonSpider, buttonBrowser, buttonLog
                       };
    memcpy(buttons, b, OPTION_SITES * sizeof(QToolButton*));

    for (int i = 0; i < OPTION_SITES; i++) {
        buttons[i]->setText(translate(headers[i]));
    }

    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);

    initOptions();

    setFontForWidgets();

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

    //      connect(gridWidget, SIGNAL(resizeEvent()), this, SLOT(onOk()));

    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()));

    for (int i = 0; i < OPTION_SITES; i++) {
        connect(buttons[i], SIGNAL(clicked(bool)), this, SLOT(switchPages()));
    }

    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();

    buttons[0]->click();
}


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::resizeEvent(QResizeEvent* se)
{
    // QSize s = gridWidget->sizeHint();

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

    QVector<trWidgets>::iterator ivec;

    for (ivec = _tabTextInfos.begin(); ivec != _tabTextInfos.end(); ++ivec) {
        switch ((*ivec).wtype) {
            case LABEL: {
                if((*ivec).gui_ID != -1) {
                    QString t = autoWrap(translate((*ivec).gui_ID), ((QLabel*)(*ivec).wg)->width() / 10.0); // autowrap
                    //                     ((QLabel*)(*ivec).wg)->update();
                    //                     qDebug() << "LABEL" << ((QLabel*)(*ivec).wg)->width();
                    ((QLabel*)(*ivec).wg)->setText(t);
                }

                break;
            }

            case CHECKBOX: {
                if((*ivec).gui_ID != -1) {
                    QString t = autoWrap(translate((*ivec).gui_ID), ((QCheckBox*)(*ivec).wg)->width() / 10.0); // autowrap
                    //                     ((QCheckBox*)(*ivec).wg)->update();
                    //                     qDebug() << "CHECKBOX" << ((QCheckBox*)(*ivec).wg)->width();
                    ((QCheckBox*)(*ivec).wg)->setText(t);
                }

                break;
            }

            case RADIO: {
                if((*ivec).gui_ID != -1) {
                    QString t = autoWrap(translate((*ivec).gui_ID), ((QRadioButton*)(*ivec).wg)->width() / 10.0); // autowrap
                    //                     ((QRadioButton*)(*ivec).wg)->update();
                    //                     qDebug() << "RADIO" << ((QRadioButton*)(*ivec).wg)->width();
                    ((QRadioButton*)(*ivec).wg)->setText(t);
                }

                break;
            }

        }
    }

    QDialog::resizeEvent(se);
}


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);

    QString sSheet = QString().sprintf("font-size: %dpt", parent->fontSize + 4);

    labelMain->setStyleSheet(sSheet);
}


void OptionsDialog::initOptions()
{
    for (QMap<QString, OptStruct>::const_iterator iopt = parent->prOptions.constBegin(); iopt != parent->prOptions.constEnd(); ++iopt) {
        QString k = iopt.key();
        trWidgets* w = findId(k);

        if (w != NULL) {
            (*w).value = (*iopt).value;
        }

#ifdef MY_DEBUG

        if (w == NULL) {
            qDebug() << "set to gui" << iopt.key() << "not found in gui!";
        }

#endif
    }
}


trWidgets *OptionsDialog::findId(const QString &k)
{
    QVector<trWidgets>::iterator ivec;

    for (ivec = _tabTextInfos.begin(); ivec != _tabTextInfos.end(); ++ivec) {
        if ((*ivec).idString == k) {
            return ivec;
        }
    }

    return NULL;
}


void OptionsDialog::getFromGUI()
{
    for (QMap<QString, OptStruct>::iterator iopt = parent->prOptions.begin(); iopt != parent->prOptions.end(); ++iopt) {
        QString k = iopt.key();
        trWidgets* w = findId(k);

        if (w == NULL) {
#ifdef MY_DEBUG
            qDebug() << "get from gui" << iopt.key() << "not found in gui!";
#endif
            continue;
        }

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

            case EDITLINE: {
                if ((*w).opttype == INTEGER) {
                    if (((QLineEdit*)(*w).wg)->text().length() > 0) {
                        (*w).value = ((QLineEdit*)(*w).wg)->text().toInt();
                    }
                } else {
                    (*w).value = -1;
                }

                if ((*w).opttype == FLOAT) {
                    if (((QLineEdit*)(*w).wg)->text().length() > 0) {
                        (*w).value = ((QLineEdit*)(*w).wg)->text().toFloat();
                    } else {
                        (*w).value = -1;
                    }
                }

                if ((*w).opttype == TEXT) {
                    (*w).value = ((QLineEdit*)(*w).wg)->text();
                }

                break;
            }

            case LABEL: {
                if ((*w).opttype == TEXT) {
                    (*w).value = ((QLabel*)(*w).wg)->text();
                }

                break;
            }

            case TEXTEDIT: { // this one only for rulez->scanList
                (*w).value = ((QTextEdit*)(*w).wg)->toPlainText();
                break;
            }

            case RADIO: // not exists
                break;

            case GROUPBOX: {
                if ((*w).opttype == BOOLEAN) {
                    (*w).value = ((QGroupBox*)(*w).wg)->isChecked() ? 1 : 0;
                }

                break;
            }

            case COMBOBOX: {
                if ((*w).opttype == TEXT) {
                    (*w).value = ((QComboBox*)(*w).wg)->currentText();
                }

                if ((*w).opttype == INTEGER || (*w).opttype == FLOAT) {
                    bool ok;
                    QString ct = ((QComboBox*)(*w).wg)->currentText();

                    if (ct == "" || ct == "-") {
                        //                                 qDebug() << "get options combo" << (*w).idString << (*w).value;
                        if ((*w).opttype == INTEGER ) {
                            (*w).value = -1;
                        }

                        if ((*w).opttype == FLOAT ) {
                            (*w).value = -1.0;
                        }
                    } else {
                        if ((*w).opttype == INTEGER ) {
                            int  num = ct.toInt(&ok);

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

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

                break;
            }
        }

        (*iopt).value = (*w).value;
    }
}


QString OptionsDialog::autoWrap(const QString &t, const int max)
{
    QString res;
    QString tmp = t;

    //     if (max == NOWRAP ) {
    //         return tmp;
    //     }

    tmp.replace("\n", " ");
    int pos;

    if (t.length() == 0) {
        return "";
    }

    if (t.length() < max) {
        return tmp;
    }

    pos = tmp.lastIndexOf(" ", max);

    if (pos <= 0 ) {
        return tmp;
    }

    while (pos > 0) {
        //         if (pos > 0){
        res += tmp.left(pos) + "\n";
        tmp = tmp.mid(pos + 1);
        //         }
        //         res += "\n";
        pos = tmp.lastIndexOf(" ", max);

        if (pos < 0) {
            res += tmp;
            break;
        }
    };

    return res;
}


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

    for (ivec = _tabTextInfos.begin(); ivec != _tabTextInfos.end(); ++ivec) {
        switch ((*ivec).wtype) {
            case LABEL: {
                if((*ivec).gui_ID != -1) {
                    QString t = autoWrap(translate((*ivec).gui_ID), ((QLabel*)(*ivec).wg)->width() / 10); // autowrap
                    ((QLabel*)(*ivec).wg)->setText(t);
                } else {
                    ((QLabel*)(*ivec).wg)->setText(translate((*ivec).value.toInt()));
                }

                break;
            }

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

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

                break;
            }

            case CHECKBOX: {
                if((*ivec).gui_ID != -1) {
                    QString t = autoWrap(translate((*ivec).gui_ID), ((QCheckBox*)(*ivec).wg)->width() / 10); // autowrap
                    ((QCheckBox*)(*ivec).wg)->setText(t);
                }

                if ((*ivec).opttype != TEXT) {
                    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).gui_ID != -1) {
                    ((QGroupBox*)(*ivec).wg)->setTitle(translate((*ivec).gui_ID));
                }

                if ((*ivec).opttype == BOOLEAN) {
                    if ((*ivec).value.toInt() == 1) {
                        ((QGroupBox*)(*ivec).wg)->setChecked(true);
                    } else {
                        ((QGroupBox*)(*ivec).wg)->setChecked(false);
                    }
                }

                break;
            }

            case COMBOBOX: {
                if ((*ivec).opttype == TEXT) {
                    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);
                        ((QComboBox*)(*ivec).wg)->model()->sort(0);
                        int tInd = ((QComboBox*)(*ivec).wg)->findText(t);
                        ((QComboBox*)(*ivec).wg)->setCurrentIndex(tInd);
                    }
                } else {
                    int num;

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

                    if ((*ivec).opttype == INTEGER) {
                        int pos;

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

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

                            if (pos >= 0) {
                                ((QComboBox*)(*ivec).wg)->setCurrentIndex(pos);
                            } else {
                                QString t = QString::number((*ivec).value.toInt());
                                ((QComboBox*)(*ivec).wg)->addItem(t);
                                ((QComboBox*)(*ivec).wg)->model()->sort(0);
                                int tInd = ((QComboBox*)(*ivec).wg)->findText(t);
                                ((QComboBox*)(*ivec).wg)->setCurrentIndex(tInd);
                            }
                        }

                        break;
                    }

                    if ((*ivec).opttype == 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 {
                            pos = ((QComboBox*)(*ivec).wg)->findText(QString::number((*ivec).value.toFloat()));

                            if (pos >= 0) {
                                ((QComboBox*)(*ivec).wg)->setCurrentIndex(pos);
                            } else {
                                QString t = QString::number((*ivec).value.toFloat());
                                ((QComboBox*)(*ivec).wg)->addItem(t);
                                ((QComboBox*)(*ivec).wg)->model()->sort(0);
                                int tInd = ((QComboBox*)(*ivec).wg)->findText(t);
                                ((QComboBox*)(*ivec).wg)->setCurrentIndex(tInd);
                            }
                        }

                        break;
                    }
                }

                break;
            }

            case RADIO: {
                if((*ivec).gui_ID != -1) {
                    QString t = autoWrap(translate((*ivec).gui_ID), ((QRadioButton*)(*ivec).wg)->width() / 10); // autowrap
                    ((QRadioButton*)(*ivec).wg)->setText(t);
                }

                break;
            }

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

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

                if ((*ivec).opttype == TEXT) {
                    ((QLineEdit*)(*ivec).wg)->setText((*ivec).value.toString());
                }

                break;
            }
        }
    }
}


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


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

    for (int i = 0; i < OPTION_SITES; i++) {
        if (buttons[i] == s) {
            n = i;
            break;
        }
    }

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

    for (int i = 0; i < OPTION_SITES; i++) {
        disconnect(buttons[i], SIGNAL(clicked(bool)), this, SLOT(switchPages()));
    }

    for (int i = 0; i < OPTION_SITES; i++) {
        if (i == n) {
            labelMain->setText(translate(headers[i]));
            pages[i]->show();
            //             pages[i]->adjustSize();
            buttons[i]->setChecked(true);
            continue;
        }

        pages[i]->hide();
        buttons[i]->setChecked(false);
    }

    for (int i = 0; i < OPTION_SITES; i++) {
        connect(buttons[i], SIGNAL(clicked(bool)), this, SLOT(switchPages()));
    }
}


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


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


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

    reject();
}





