/* pinentrydialog.cpp - A secure KDE dialog for PIN entry.
   Copyright (C) 2002 Klarälvdalens Datakonsult AB
   Copyright (C) 2007-2015 X2Go Project
   Written by Steffen Hansen <steffen@klaralvdalens-datakonsult.se>.
   Modified for X2Go by Oleksandr Shneyder <oleksandr.shneyder@obviously-nice.de>
   and Mike Gabriel <mike.gabriel@das-netzwerkteam.de>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This program 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
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA  */


#include <QLayout>
#include <QPushButton>
#include <QLabel>
#include <QMessageBox>
#include <QButtonGroup>

#include "pinlineedit.h"
#include <QKeyEvent>
#include "pinentrydialog.h"
#include <QDebug>

PinEntryDialog::PinEntryDialog( QWidget* parent, const char* , bool  )
        : QDialog( parent ), _grabbed( false )
{
     setWindowTitle(tr("X2Go Pinpad"));
    _icon = new QLabel( this );
    _icon->setPixmap( QMessageBox::standardIcon( QMessageBox::Information ) );

    _error = new QLabel( this );

    _desc = new QLabel( this );


    _edit = new PinLineEdit( this );
    _edit->setMaxLength( 256 );
    _edit->setEchoMode( QLineEdit::Password );

    _ok = new QPushButton( QIcon(":/icons/button_ok.png"), "",this );
    _cancel = new QPushButton(QIcon(":/icons/button_cancel.png"),"" , this );
    _bs= new QPushButton(QString(8592), this );

    QFont f=_bs->font();
    f.setPointSize(20);
    _bs->setFont(f);
    _icon->hide();
    _error->hide();

    QGridLayout* butLay=new QGridLayout();
    butLay->addWidget(_cancel,3,2);
    butLay->addWidget(_ok,3,0);
    QHBoxLayout* bhlay=new QHBoxLayout();

    bhlay->addLayout(butLay);
    bhlay->addStretch();
    QButtonGroup* numGroup=new QButtonGroup(this);
    for(uint i=0;i<10;++i)
    {
        if(i<9)
        {
            _num[i]=new QPushButton(QString::number(i+1),this);
            butLay->addWidget(_num[i],i/3,i%3);
        }
        else
        {
            _num[i]=new QPushButton("0",this);
            butLay->addWidget(_num[i],3,1);
        }
        _num[i]->setFont(f);
        _num[i]->setFixedSize(QSize(_num[i]->sizeHint()).height(),QSize(_num[i]->sizeHint()).height());
        _num[i]->setFocusPolicy(Qt::NoFocus);
        numGroup->addButton(_num[i],i);
    }
    connect(numGroup,SIGNAL(buttonClicked(int)),this,SLOT(slot_numButClicked( int )));
    connect(_bs,SIGNAL(clicked()),this,SLOT(slot_bs()));

    _ok->setFixedSize(QSize(_num[0]->sizeHint()).height(),QSize(_num[0]->sizeHint()).height());
    _cancel->setFixedSize(QSize(_num[0]->sizeHint()).height(),QSize(_num[0]->sizeHint()).height());
    _bs->setFixedSize(QSize(_num[0]->sizeHint()).height(),QSize(_num[0]->sizeHint()).height());
    _bs->setFocusPolicy(Qt::NoFocus);
    _edit->setFixedHeight(_num[0]->sizeHint().height());
    _ok->setDefault(true);

    QVBoxLayout* mlay=new QVBoxLayout(this);
    _edit->setFixedWidth(_num[0]->width()*3+mlay->spacing()*2);

    QHBoxLayout* icLay=new QHBoxLayout();
    icLay->addWidget(_icon);
    icLay->addWidget(_error);
    icLay->addStretch();

    mlay->addLayout(icLay);
    mlay->addWidget(_desc);
    QHBoxLayout* edLay=new QHBoxLayout();
    //   edLay->addWidget(_prompt);

    edLay->addWidget(_edit);
    edLay->addWidget(_bs);
    edLay->addStretch();
    mlay->addLayout(edLay);


    mlay->addLayout(bhlay);
    mlay->addStretch();


    connect( _ok, SIGNAL( clicked() ),
             this, SIGNAL( accepted() ) );
    connect( _cancel, SIGNAL( clicked() ),
             this, SIGNAL( rejected() ) );

    connect (this, SIGNAL (accepted ()),
             this, SLOT (accept ()));
    connect (this, SIGNAL (rejected ()),
             this, SLOT (reject ()));
    connect (_edit,SIGNAL(bs_pressed()),this,SLOT(slot_bs()));
    connect (_edit,SIGNAL(cancel_pressed()),this,SLOT(reject()));
    f.setPointSize(14);
    _edit->setFont(f);
    _edit->setFocus();
}

void PinEntryDialog::paintEvent( QPaintEvent* ev )
{
    // Grab keyboard when widget is mapped to screen
    // It might be a little weird to do it here, but it works!
    if( !_grabbed )
    {
        _edit->grabKeyboard();
        _grabbed = true;
    }
    QDialog::paintEvent( ev );
}

void PinEntryDialog::hideEvent( QHideEvent* ev )
{
    _edit->releaseKeyboard();
    _grabbed = false;
    QDialog::hideEvent( ev );
}

void PinEntryDialog::keyPressEvent( QKeyEvent* e )
{
    if ( e->key() == Qt::Key_Escape )
    {
        emit rejected();
        return;
    }
    QDialog::keyPressEvent( e );
}

void PinEntryDialog::setDescription( const QString&  )
{
    _desc->setText(tr("Please, enter your PIN"));
    //     _desc->setText(txt);
    _icon->setPixmap( QMessageBox::standardIcon( QMessageBox::Information ) );
    setError( QString::null );
}

QString PinEntryDialog::description() const
{
    return _desc->text();
}

void PinEntryDialog::setError( const QString& txt )
{
    if( !txt.isNull() )
        _icon->setPixmap( QMessageBox::standardIcon( QMessageBox::Critical ) );
    _error->setText( txt );
}

QString PinEntryDialog::error() const
{
    return _error->text();
}

void PinEntryDialog::setText( const QString& txt )
{
    _edit->setText( txt );
}

QString PinEntryDialog::text() const
{
    return _edit->text();
}

void PinEntryDialog::setPrompt( const QString& )
{
    //   _prompt->setText( txt );
}

QString PinEntryDialog::prompt() const
{
    return "PIN";
    //   return _prompt->text();
}

void PinEntryDialog::setOkText( const QString& txt )
{
    _ok->setText( txt );
}

void PinEntryDialog::setCancelText( const QString& txt )
{
    _cancel->setText( txt );
}


void PinEntryDialog::slot_numButClicked(int id)
{
    int num=id+1;
    if(num==10)
        num=0;
    _edit->setText(_edit->text()+QString::number(num));
}


void PinEntryDialog::slot_bs()
{
    _edit->backspace();
}
