#include <QBoxLayout>
#include <QApplication>
#include <QDesktopWidget>
#include <QEvent>
#include <QRegExpValidator>

#include "lineeditwidget.h"

LineEditWidget::LineEditWidget(QWidget *parent)
    : QLineEdit(parent)
    , _layout(new QHBoxLayout())
    , _popup(0)
    , _optimalLength(0)
{
    _layout->setSpacing(0);
    _layout->setContentsMargins(1, 3, 2, 3);
    _layout->addWidget(new QWidget());

    setLayout(_layout);
    setContentsMargins(0, 0, 0, 0);
    installEventFilter(this);
}

LineEditWidget::~LineEditWidget()
{
    _toolbuttons.clear();
}


QSize LineEditWidget::sizeHint() const
{
    QSize size;
    size = QLineEdit::sizeHint();

    int width = 0;

    if(_optimalLength) {
        width += fontMetrics().width("0") * _optimalLength;
    }
    else {
        width += size.width();
    }
    width += textMargins().right();
    size.setWidth(width);
    return size;
}

void LineEditWidget::showEvent(QShowEvent *e)
{
    // Width of standard QLineEdit plus extended tool buttons
    int width = 0;
    for(int i = _toolbuttons.size() - 1; i >= 0; i--) {
        width += _toolbuttons[i]->width();
    }

    setTextMargins(0, 0, width, 0);
    QLineEdit::showEvent(e);
}

bool LineEditWidget::eventFilter(QObject *o, QEvent *e)
{
    return QLineEdit::eventFilter(o, e);
}

void LineEditWidget::setRxValidator(const QString &str)
{
    _rxValidator = str;
    if (str.isEmpty()) {
        return;
    }

    QRegExp rx(str);
    QRegExpValidator *validator = new QRegExpValidator(rx, this);
    setValidator(validator);
}

void LineEditWidget::addWidget(QWidget *w)
{
    _toolbuttons << w;
    _layout->addWidget(w);
}

void LineEditWidget::setPopup(QWidget *w)
{
    if(_popup) {
        delete _popup;
        _popup = 0;
    }

    _popup = new QFrame(this);
    _popup->setWindowFlags(Qt::Popup);
    _popup->setFrameStyle(QFrame::StyledPanel);
    _popup->setAttribute(Qt::WA_WindowPropagation);
    _popup->setAttribute(Qt::WA_X11NetWmWindowTypeCombo);

    QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom);
    layout->setSpacing(0);
    layout->setMargin(0);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->addWidget(w);
    _popup->setLayout(layout);
}

void LineEditWidget::showPopup()
{
    _popup->adjustSize();
    _popup->move(mapToGlobal(QPoint(width() - _popup->geometry().width(), height())));
    QSize size = qApp->desktop()->size();
    QRect rect = _popup->geometry();

    // if widget is beyond edge of display
    if(rect.right() > size.width()) {
        rect.moveRight(size.width());
    }

    if(rect.bottom() > size.height()) {
        rect.moveBottom(size.height());
    }

    _popup->move(rect.topLeft());
    _popup->show();
}

void LineEditWidget::hidePopup()
{
    if (_popup->isVisible()) {
        _popup->hide();
    }
}
