/***************************** LICENSE START ***********************************

 Copyright 2015 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include "MvQTextLine.h"

#include "MvQRequestPanelHelp.h"
#include "MvQLineEdit.h"

#include "LineFactory.h"
#include "MvIconParameter.h"
#include "RequestPanel.h"

#include <QDebug>

MvQTextLine::MvQTextLine(RequestPanel& owner, const MvIconParameter& param) :
    MvQRequestPanelLine(owner, param)
{
    lineEdit_ = new MvQLineEdit(parentWidget_);
    owner_.addWidget(lineEdit_, row_, 3);

    connect(lineEdit_, SIGNAL(textEdited(const QString&)),
            this, SLOT(slotTextEdited(const QString&)));

    connect(lineEdit_, SIGNAL(textCleared()),
            this, SLOT(slotCleared()));
}

void MvQTextLine::refresh(const vector<string>& values)
{
    string s;
    for (vector<string>::const_iterator j = values.begin(); j != values.end(); ++j) {
        if (s.length())
            s += "/";
        s += *j;
    }

    //Now this is the tricky part. Whenever the user types in a new character the
    //lineedit emits a changed signal and the request gets updated. And in the end this (refresh())
    //function will be called with the new text. Ideally the new string and the string stored in
    //the lineedit should be the same. However, mars tends to change incomplete floating point numbers like
    // "7." into integers!! So when the user wants to change e.g. "7.1" to "7.3" when they reach "7."
    //during the editing the string changes back to "7". In this case we do not want to set the linedit.
    //So we need to carefully compare the new and the previous string and decide what to do.

    string prevText = lineEdit_->text().toStdString();

    if (s.empty() || s != prevText) {
        //Single strings
        if (values.size() <= 1) {
            //if the original string was
            // "something" + "."  or
            // "-"
            //we do not update the lineedit

            if ((s + "." == prevText) ||
                (prevText == "-" && !s.empty() && s[0] == '-')) {
                return;
            }

            lineEdit_->setText(s.c_str());
            updateHelper();
        }
        //Lists
        else {
            QStringList lst     = QString::fromStdString(s).split("/");
            QStringList prevLst = QString::fromStdString(prevText).split("/");

            if (lst.count() == prevLst.count()) {
                bool found = false;
                for (int i = 0; i < lst.count(); i++) {
                    if ((lst[i] + "." == prevLst[i]) ||
                        (prevLst[i] == "-" && !lst[i].isEmpty() && lst.at(i).at(0) == '-')) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    lineEdit_->setText(s.c_str());
                    updateHelper();
                }
            }
            else {
                if ('/' + s != prevText) {
                    lineEdit_->setText(s.c_str());
                    updateHelper();
                }
            }
        }
    }
}

void MvQTextLine::dispatchChange()
{
    vector<string> vals;
    QString txt = lineEdit_->text();
    foreach (QString s, txt.split("/")) {
        vals.push_back(s.toStdString());
    }

    owner_.set(param_.name(), vals);
}

void MvQTextLine::updateHelper()
{
    if (!helper_)
        return;


    vector<string> vals;
    QString txt = lineEdit_->text();
    foreach (QString s, txt.split("/")) {
        vals.push_back(s.toStdString());
        helper_->refresh(vals);
    }
    helper_->refresh(vals);
}

void MvQTextLine::slotCleared()
{
    dispatchChange();
    updateHelper();
}

void MvQTextLine::slotTextEdited(const QString& /*text*/)
{
    dispatchChange();
    updateHelper();
}

void MvQTextLine::slotHelperEdited(const vector<string>& values, const vector<string>& noValues)
{
    QString txt     = lineEdit_->text();
    QStringList lst = txt.split("/");

    for (vector<string>::const_iterator it = values.begin(); it != values.end(); it++) {
        QString s(it->c_str());
        if (!lst.contains(s))
            lst << s;
    }

    for (vector<string>::const_iterator it = noValues.begin(); it != noValues.end(); it++) {
        QString s(it->c_str());
        if (lst.contains(s))
            lst.removeAll(s);
    }

    QString res = lst.join("/");
    if (res.startsWith("/"))
        res.remove(0, 1);

    if (res != txt) {
        lineEdit_->setText(res);
        dispatchChange();
    }
}

void MvQTextLine::slotHelperEdited(const vector<string>& values)
{
    if (values.size() > 0) {
        QString s(values[0].c_str());
        lineEdit_->setText(s);
        dispatchChange();
    }
}

static LineMaker<MvQTextLine> maker1("text");
