#include "CrateConfigDialog.h"
#include "ui_CrateConfigDialog.h"

#include <QHostAddress>
#include <QPushButton>
#include <QMessageBox>
#include <QLineEdit>
#include <QCheckBox>
#include "ConfigPasswordDialog.h"





CrateConfigDialog::CrateConfigDialog(Config &cfg,  QWidget *parent,
                                           int flags) :
    QDialog(parent),
    ui(new Ui::CrateConfigDialog),
    m_modified(false), m_flags(flags) {

    ui->setupUi(this);

    bool addition_set_present = false;

    QString ipNumbReg = "(25\\d|2[0-4]{1,1}\\d|[0-1]{0,1}\\d{1,2}|\\d{1,2}){1,1}";
    QRegExpValidator* ipValidator = new QRegExpValidator(
                QRegExp( ipNumbReg + "\\." + ipNumbReg + "\\."
                         + ipNumbReg + "\\." + ipNumbReg), this);
    QString macNumbReg = "(\\d|[A-F]|[a-f]){2}";
    QString macRegexp  = "(" + macNumbReg + "\\" + macSeparator() + "){5}" + macNumbReg;
    QRegExpValidator* macValidator = new QRegExpValidator(
                QRegExp(macRegexp), this);


    ui->IpAddr->setValidator(ipValidator);
    ui->IpMask->setValidator(ipValidator);
    ui->IpGateway->setValidator(ipValidator);

    ui->CrateInterface->setCurrentIndex(cfg.iface);
    ui->IpAddr->setText(QHostAddress(cfg.ip_addr).toString());
    ui->IpMask->setText(QHostAddress(cfg.ip_netmask).toString());
    ui->IpGateway->setText(QHostAddress(cfg.ip_gateway).toString());

    connect(ui->IpAddr, SIGNAL(textChanged(QString)), SLOT(dataChanged()));
    connect(ui->IpMask, SIGNAL(textChanged(QString)), SLOT(dataChanged()));
    connect(ui->IpGateway, SIGNAL(textChanged(QString)), SLOT(dataChanged()));
    connect(ui->CrateInterface, SIGNAL(currentIndexChanged(int)), SLOT(dataChanged()));

    if (flags & FlagShowDHCP) {
        dhcpEnCheck = new QCheckBox();
        dhcpEnCheck->setChecked(cfg.dhcp_en);
        ui->paramsLout->addRow(tr("Get IP-paramtes automatically"), dhcpEnCheck);
        connect(dhcpEnCheck, SIGNAL(stateChanged(int)), SLOT(dataChanged()));
    }

    if (flags & FlagShowFactoryMac) {
        addition_set_present = true;
        factoryMacEdit = new QLineEdit();
        factoryMacEdit->setReadOnly(true);
        factoryMacEdit->setValidator(macValidator);
        QFont font = factoryMacEdit->font();
        font.setFamily("Monospace");
        font.setStyleHint(QFont::TypeWriter);
        factoryMacEdit->setFont(font);


        factoryMacEdit->setText(macStr(cfg.factory_mac));

        ui->additionalParamsLout->addRow(tr("Factory MAC-address"), factoryMacEdit);
    }

    if (flags & FlagShowUserMac) {
        addition_set_present = true;
        userMacCheck = new QCheckBox();
        userMacCheck->setChecked(cfg.user_mac_en);
        connect(userMacCheck, SIGNAL(stateChanged(int)), SLOT(dataChanged()));
        ui->additionalParamsLout->addRow(tr("Enable user MAC-address"), userMacCheck);

        userMacEdit = new QLineEdit();
        userMacEdit->setValidator(macValidator);
        QFont font = userMacEdit->font();
        font.setFamily("Monospace");
        font.setStyleHint(QFont::TypeWriter);
        userMacEdit->setFont(font);

        userMacEdit->setText(macStr(cfg.user_mac));
        connect(userMacEdit, SIGNAL(textChanged(QString)), SLOT(dataChanged()));
        ui->additionalParamsLout->addRow(tr("User MAC-address"), userMacEdit);
    }


    if (flags & FlagShowSetPassword) {
        addition_set_present = true;
        newPassSetCheck = new QCheckBox();
        newPassSetCheck->setChecked(false);
        ui->additionalParamsLout->addRow(tr("Set new password"), newPassSetCheck);
        connect(newPassSetCheck, SIGNAL(stateChanged(int)), SLOT(dataChanged()));


        newPassEdit = new QLineEdit();
        newPassEdit->setEchoMode(QLineEdit::Password);
        newPassEdit->setEnabled(false);
        ui->additionalParamsLout->addRow(tr("New password"), newPassEdit);
        connect(newPassEdit, SIGNAL(textChanged(QString)), SLOT(dataChanged()));


        newPassRepeatEdit = new QLineEdit();
        newPassRepeatEdit->setEchoMode(QLineEdit::Password);
        newPassRepeatEdit->setEnabled(false);
        ui->additionalParamsLout->addRow(tr("Repeat new password"), newPassRepeatEdit);
        connect(newPassRepeatEdit, SIGNAL(textChanged(QString)), SLOT(dataChanged()));
    }



    ui->additionalParams->setVisible(addition_set_present);




    dataChanged();
    resize(width(), 20);
    m_modified = false;
}

CrateConfigDialog::~CrateConfigDialog() {
    delete ui;
}

quint8 CrateConfigDialog::crateInterface() const {
    return ui->CrateInterface->currentIndex();
}

quint32 CrateConfigDialog::ipAddr() const {
    return  QHostAddress(ui->IpAddr->text()).toIPv4Address();
}

quint32 CrateConfigDialog::ipMask() const {
    return QHostAddress(ui->IpMask->text()).toIPv4Address();
}

quint32 CrateConfigDialog::ipGate() const {
    return QHostAddress(ui->IpGateway->text()).toIPv4Address();
}

QString CrateConfigDialog::passwd() const {
    return m_pass;
}

bool CrateConfigDialog::useDhcp() const {
    return m_flags & FlagShowDHCP ? dhcpEnCheck->isChecked() : false;
}

bool CrateConfigDialog::setUserMac() const {
    return m_flags & FlagShowUserMac ? userMacCheck->isChecked() : false;
}

QByteArray CrateConfigDialog::userMac() const {
    QByteArray ret;
    QStringList macStr = userMacEdit->text().split(macSeparator());
    if (macStr.size() == Config::MAC_ADDR_LEN) {
        foreach (QString macByte, macStr) {
            ret.append(macByte.toInt(0, 16));
        }
    }
    return ret;
}

bool CrateConfigDialog::setNewPass() const {
    return m_flags & FlagShowSetPassword ? newPassSetCheck->isChecked() : false;
}

QString CrateConfigDialog::newPass() const {
    return m_flags & FlagShowSetPassword ? newPassEdit->text() : QString();
}


void CrateConfigDialog::accept() {
    if (m_modified) {
        if (m_flags & FlagPasswordRequired) {
            ConfigPasswordDialog passDlg(this);
            if (passDlg.exec() == QDialog::Accepted) {
                m_pass = passDlg.passwd();
                QDialog::accept();
            }
        } else {
            if (QMessageBox::information(this, tr("Changes saving"),
                                         tr("Write new crate settings?"),
                                         QMessageBox::Yes | QMessageBox::No)==QMessageBox::Yes) {
                QDialog::accept();
            } else {
                QDialog::reject();
            }
        }
    } else {
        QDialog::reject();
    }
}



void CrateConfigDialog::dataChanged() {
    bool cfg_ok = true;
    int pos=0;
    m_modified = true;

    QString text = ui->IpAddr->text();
    if (ui->IpAddr->validator()->validate(text, pos) == QValidator::Acceptable) {
        ui->IpAddr->setStyleSheet("QLineEdit { color: darkGreen }");
    } else {
        ui->IpAddr->setStyleSheet("QLineEdit { color: darkRed }");
        cfg_ok = false;
    }

    text = ui->IpMask->text();
    if (ui->IpMask->validator()->validate(text, pos) == QValidator::Acceptable) {
        ui->IpMask->setStyleSheet("QLineEdit { color: darkGreen }");
    } else {
        ui->IpMask->setStyleSheet("QLineEdit { color: darkRed }");
        cfg_ok = false;
    }

    text = ui->IpGateway->text();
    if (ui->IpGateway->validator()->validate(text, pos) == QValidator::Acceptable) {
        ui->IpGateway->setStyleSheet("QLineEdit { color: darkGreen }");
    } else {
        ui->IpGateway->setStyleSheet("QLineEdit { color: darkRed }");
        cfg_ok = false;
    }

    if (ui->CrateInterface->currentIndex()==LTR_CRATE_IFACE_UNKNOWN)
        cfg_ok =  false;

    if (m_flags & FlagShowUserMac) {
        text = userMacEdit->text();
        if (userMacEdit->validator()->validate(text, pos) == QValidator::Acceptable) {
            userMacEdit->setStyleSheet("QLineEdit { color: darkGreen }");
        } else {
            userMacEdit->setStyleSheet("QLineEdit { color: darkRed }");
            cfg_ok = false;
        }
    }

    if (m_flags & FlagShowSetPassword)  {
        bool setPass = newPassSetCheck->isChecked();

        if (setPass) {
            newPassEdit->setEnabled(true);
            newPassRepeatEdit->setEnabled(true);


            if (newPassEdit->text()!=newPassRepeatEdit->text()) {
                newPassRepeatEdit->setStyleSheet("QLineEdit { color: darkRed }");
                cfg_ok = false;
            } else {
                newPassRepeatEdit->setStyleSheet("QLineEdit { color: darkGreen }");
            }
        } else {
            newPassEdit->setEnabled(false);
            newPassRepeatEdit->setEnabled(false);
            newPassRepeatEdit->setStyleSheet(QString());
        }
    }

    ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(cfg_ok);
}



QString CrateConfigDialog::macStr(const quint8 *mac) {
    QString ret;
    for (unsigned i = 0; i < Config::MAC_ADDR_LEN; i++) {
        ret += QString("%1").arg(mac[i], 2, 16, QChar('0'));
        if (i!=(Config::MAC_ADDR_LEN-1))
            ret += macSeparator();
    }
    return ret;
}
