/*! @file

    @id $Id$
*/
//       1         2         3         4         5         6         7         8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890

#ifndef __PINDIALOG_HXX__
#define __PINDIALOG_HXX__

#include <cryptoki.hxx>
#include <qbrowserlib/log.hxx>
#include <ui_pinentry.h>
#include <QtGui/QDialog>
#include <QtCore/QDateTime>
#include <QtNetwork/QSslCertificate>

#include <cassert>

class PinEntry: public QDialog, public Ui::PinEntry {
    Q_OBJECT;
  public:
    PinEntry(const QSslCertificate& cert, QWidget *parent=0):
        QDialog(parent),
        _maxPinLen(-1), _minPinLen(0) {
      setModal(true);
      setupUi(this);
      _cert->certificate(cert);
      on__showDetails_toggled(false);
      _name->setText(utfConv(cert.subjectInfo(QSslCertificate::CommonName))
                     .remove(" (Authentication)"));
      _mail->setText(utfConv(cert.alternateSubjectNames()
                             .value(QSsl::EmailEntry)));
      if (!cert.subjectInfo(QByteArray("serialNumber")).isEmpty()) {
        _certSerialTitle->setText(tr("SuisseID Number:"));
        _certSerial->setText(cert.subjectInfo(QByteArray("serialNumber")));
      } else {
        _certSerialTitle->setText
          (tr("Postzertifikat:", "title for postzertificate serial number"));
        _certSerial->setText(cert.serialNumber());
      }
    }
    PinEntry& tokeninfo(const cryptoki::TokenInfo& ti) {
      _maxPinLen = ti.maxPinLen;
      _minPinLen = ti.minPinLen;
      on__pin_textChanged(_pin->text());
      return *this;
    }
    PinEntry& retries(int num) {
      _pinstatus->setCurrentIndex(num==-1?1:(num==-2?2:0));
      _retries->setText(tr("there are %1 PIN attempts left").arg(num));
      return *this;
    }
    QString pin() const {
      return _pin->text();
    }
    int myexec() {
      TRC;
      _pin->clear();
      show();
      LOG<<"SSSSSSSSSTTTTTTTAAAAAAAAAAAAARRRRRRRRRRTTTTTTTTTT";
      int res(_run.exec(QEventLoop::ExcludeSocketNotifiers));
      LOG<<"EEEEEEEEEEEEENNNNNNNNNNNNNNNNNNNNNDDDDDDDDDDDDDDEEEEEEEEEEEEE";
      hide();
      return res;
    }
  public Q_SLOTS:
    virtual void accept() {
      TRC;
      QDialog::accept();
    }
    virtual void done(int r) {
      TRC; LOG<<r;
      _run.exit(r);
      assert(!_run.isRunning());
      LOG<<"DDDDDDDDOOOOOOOOOOOONNNNNNNNNNNEEEEEEE";
      QDialog::done(r);
    }
    virtual void reject() {
      TRC;
      QDialog::reject();
    }
  protected Q_SLOTS:
    void on__showDetails_toggled(bool s) {
      _cert->setVisible(s);
      adjustSize();
    }
    void on__pin_textChanged(const QString &text) {
      _buttonBox->button(QDialogButtonBox::Ok)
        ->setEnabled((unsigned long)text.size()>=_minPinLen &&
                     (unsigned long)text.size()<=_maxPinLen);
    }
  protected:
    QString utfConv(const QString& txt) {
      QByteArray value(txt.toAscii());
      for (int i(-1); (i=value.indexOf("\\x"))!=-1 && i+3<value.size();)
        value.replace(i, 4, QByteArray::fromHex(value.mid(i+2, 2)));
      return QString::fromUtf8(value.data(), value.size());
    }
  private:
    QEventLoop _run;
    unsigned long _maxPinLen;
    unsigned long _minPinLen;
};

#endif
