#include "guitools.h"

//------------------------------------------------------------------------------
//         QFitsSimplestButton
//------------------------------------------------------------------------------
QFitsSimplestButton::QFitsSimplestButton(QPixmap pm, QWidget *parent) :
                                                                QLabel(parent) {
    setPixmap(pm);
}

QFitsSimplestButton::QFitsSimplestButton(const QString &te, QWidget *parent) :
                                                            QLabel(te, parent) {
    setAlignment(Qt::AlignCenter);
}

void QFitsSimplestButton::mouseReleaseEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton) emit clicked();
}

void QFitsSimplestButton::mouseDoubleClickEvent(QMouseEvent *e) {
    emit doubleClicked();
}

dpDoubleEdit::dpDoubleEdit(QString t, QWidget *parent) : QLineEdit(t, parent) {
    setValidator(new QDoubleValidator(this));

    connect(this, SIGNAL(textEdited(const QString &)), SLOT(notifyChange(const QString &)));
}

void dpDoubleEdit::notifyChange(const QString &t) {
    emit valueChanged(t.toDouble());
}

void dpDoubleEdit::setValue(const double &v) {
    setText(QString::number(v));
}

double dpDoubleEdit::value() {
    return text().toDouble();
}

dpFitEstimate::dpFitEstimate(QString t, QWidget *parent) : dpDoubleEdit(t, parent) {
    minConstrain = new QLabel("min", this);
    maxConstrain = new QLabel("max", this);
    minConstrain->setAlignment(Qt::AlignRight | Qt::AlignBottom);
    maxConstrain->setAlignment(Qt::AlignRight | Qt::AlignTop);
    QFont theFont(font());
    theFont.setPointSizeF(font().pointSizeF() * .6);
    minConstrain->setFont(theFont);
    maxConstrain->setFont(theFont);
    minConstrain->setStyleSheet("color: rgba(0,0,0,128)");
    maxConstrain->setStyleSheet("color: rgba(0,0,0,128)");
    minConstrain->setVisible(false);
    maxConstrain->setVisible(false);
    parameterLock = new QLabel("", this);
    parameterLock->setPixmap(QIcon(":/padlock.svg").pixmap(10, 10));
    parameterLock->adjustSize();
    parameterLock->hide();
    popupButton = new QFitsSimplestButton(">", this);
    popupButton->setCursor(Qt::ArrowCursor);

//    result = new QLabel("result", this);
//    error = new QLabel("error", this);

    parameters = new QWidget();
    fixed = new QCheckBox("fixed", parameters);
    fixed->adjustSize();
    fixed->move(5, 0);
    constrained = new QCheckBox("constrained", parameters);
    constrained->adjustSize();
    constrained->move(5, fixed->height());
    lowerBound = new dpDoubleEdit("", parameters);
    lowerBound->adjustSize();
    lowerBound->move(5, constrained->y() + constrained->height());
    upperBound = new dpDoubleEdit("", parameters);
    upperBound->adjustSize();
    upperBound->move(lowerBound->x() + lowerBound->width(), lowerBound->y());

    parameters->setFixedSize(upperBound->x() + upperBound->width() + 5, lowerBound->y() + lowerBound->height() + 5);
//    parameters->adjustSize();

    parameters->setWindowFlag(Qt::Popup);
//    parameters->setStyleSheet("background: rgba(0, 0, 0, 240)");
//    parameters->setAttribute(Qt::WA_NoSystemBackground);
//    parameters->setAttribute(Qt::WA_TranslucentBackground);
    parameters->hide();

    connect(fixed, SIGNAL(toggled(bool)), parameterLock, SLOT(setVisible(bool)));
    connect(constrained, SIGNAL(toggled(bool)), minConstrain, SLOT(setVisible(bool)));
    connect(constrained, SIGNAL(toggled(bool)), maxConstrain, SLOT(setVisible(bool)));
    connect(lowerBound, SIGNAL(textChanged(QString)), minConstrain, SLOT(setText(QString)));
    connect(upperBound, SIGNAL(textChanged(QString)), maxConstrain, SLOT(setText(QString)));
    connect(popupButton, SIGNAL(clicked()), this, SLOT(popupParameters()));
}

void dpFitEstimate::resizeEvent(QResizeEvent *e) {
    popupButton->setGeometry(e->size().width() - e->size().height(), 0, e->size().height(), e->size().height());

    QFont theFont(font());
    while (QFontMetrics(theFont).boundingRect("0").height() > e->size().height() / 2.) theFont.setPointSizeF(theFont.pointSizeF() * .9);
    minConstrain->setGeometry(0, e->size().height() / 2, e->size().width() - e->size().height(), e->size().height() / 2);
    minConstrain->setFont(theFont);
    maxConstrain->setGeometry(0, 0, e->size().width() - e->size().height(), e->size().height() / 2);
    maxConstrain->setFont(theFont);
    parameterLock->move(width() - parameterLock->width() - e->size().height(), (height()-parameterLock->height()) / 2);
//    result->setGeometry(e->size().width(), 0, e->size().width(), e->size().height());
//    error->setGeometry(2 * e->size().width(), 0, e->size().width(), e->size().height());
//    fixed->setGeometry(e->size().width() + 5, 0, fixed->size().width(), e->size().height());
//    constrained->setGeometry(0, e->size().height() + 5, e->size().width() + 5 + fixed->size().width(), constrained->size().height());
//    lowerBound->setGeometry(0, constrained->y() + constrained->height() + 5, e->size().width(), e->size().height());
//    upperBound->setGeometry(lowerBound->size().width() + 5, constrained->y() + constrained->height() + 5, e->size().width(), e->size().height());
//    parameters->adjustSize();
}

//void dpFitEstimate::mousePressEvent(QMouseEvent *event) {
//    if (event->button() == Qt::LeftButton) popupParameters();
//    QLineEdit::mousePressEvent(event);
//}

void dpFitEstimate::contextMenuEvent(QContextMenuEvent *event) {
    popupParameters();
//    QMenu *menu = createStandardContextMenu();
//    menu->addAction("specify constrains...", this, SLOT(popupParameters()));
//    menu->exec(event->globalPos());
//    delete menu;
}

void dpFitEstimate::popupParameters() {
    parameters->move(mapToGlobal(QPoint(width(), 0)));
//    parameters->move(mapToGlobal(pos()));
//    estimate->setText(text());
//    estimate->setFocus();
    parameters->show();
}

dpFitResult::dpFitResult(QWidget *parent) : QWidget(parent) {
    value = 0.;
    error = 0.;
    v = new QLabel("", this);
    v->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    e = new QLabel("", this);
    e->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    pm = new QLabel("±", this);
    pm->setAlignment(Qt::AlignCenter);
    pm->adjustSize();
}

void dpFitResult::adjustSize() {
    QRect s = fontMetrics().boundingRect("XXXXXXXXXX±XXXXXXXXXX");
    resize(s.width(), s.height());
}

void dpFitResult::resizeEvent(QResizeEvent *ev) {
    int w = (ev->size().width() - pm->width()) / 2;
    v->setGeometry(0, 0, w, ev->size().height());
    pm->setGeometry(w, 0, pm->width(), ev->size().height());
    e->setGeometry(w + pm->width(), 0, w, ev->size().height());
}

void dpFitResult::setResult(double nv, double ne) {
    value = nv;
    error = ne;
    v->setText(QString::number(value, 'g', 5));
    e->setText(QString::number(error, 'g', 4));
    if (ne < 0.) {
        e->hide();
        pm->hide();
    } else {
        e->show();
        pm->show();
    }
}

QString dpFitResult::text() const {
    return v->text() + "," + e->text();
}

QString dpFitResult::getValue() const {
    return v->text();
}

QString dpFitResult::getError() const {
    return e->text();
}
