/*
 *  Copyright (C) 2007-2008 CMM Sigma Andrzej Chmielowiec <cmmsigma@cmmsigma.eu>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 3
 *  as published by the Free Software Foundation.
 *
 *  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.
 */

#include "GenInfoWidget.h"
#include "MainWindow.h"

#include "crd_ut10xx.h"

GenInfoWidget::GenInfoWidget(QWidget *parent): QStackedWidget(parent)
{
	QGridLayout *layout;
	QGridLayout *gLayout;
	QVBoxLayout *vLayout;
	QGroupBox *gBox;
	
	//////////////////////////////////////////////////////////////////////////////////////////////
	//
	//	Widget for configured token.
	//
	//////////////////////////////////////////////////////////////////////////////////////////////
	mConfWidget = new QWidget;
	layout = new QGridLayout;
	
	gBox = new QGroupBox(tr("Details"));
	vLayout = new QVBoxLayout;
	mConfTechInfo = new QLabel;
	vLayout->addWidget(mConfTechInfo);
	gBox->setLayout(vLayout);
	layout->addWidget(gBox, 0, 0);
	
	gBox = new QGroupBox(tr("Configuration details"));
	vLayout = new QVBoxLayout;
	mConfInfo = new QLabel;
	vLayout->addWidget(mConfInfo);
	gBox->setLayout(vLayout);
	layout->addWidget(gBox, 1, 0);
	
	layout->setRowStretch(2, 1);
	
	mConfWidget->setLayout(layout);
	
	//////////////////////////////////////////////////////////////////////////////////////////////
	//
	//	Widget for not configured token.
	//
	//////////////////////////////////////////////////////////////////////////////////////////////
	mNotConfWidget = new QWidget;
	layout = new QGridLayout;
	
	gBox = new QGroupBox(tr("Details"));
	vLayout = new QVBoxLayout;
	mNotConfTechInfo = new QLabel;
	vLayout->addWidget(mNotConfTechInfo);
	gBox->setLayout(vLayout);
	layout->addWidget(gBox, 0, 0);
	
	gBox = new QGroupBox(tr("Configuration details"));
	gLayout = new QGridLayout;
	
	mNotConfInfo = new QLabel(tr("<center><b>Token is not initialized</b></center>"));
	gLayout->addWidget(mNotConfInfo, 0, 0, 1, 3);
	
	mTokenName = new QLineEdit;
	mTokenName->setMaxLength(10);
	gLayout->addWidget(new QLabel(tr("Name:")), 1, 0);
	gLayout->addWidget(mTokenName, 1, 1, 1, 2);
	
	gLayout->addWidget(new QLabel(tr("<center>Administrator</center>")), 2, 1);
	gLayout->addWidget(new QLabel(tr("<center>User</center>")), 2, 2);
	
	mSoPinLimit = new QSpinBox;
	mSoPinLimit->setMinimum(1);
	mSoPinLimit->setMaximum(20);
	mSoPinLimit->setValue(10);
	mUserPinLimit = new QSpinBox;
	mUserPinLimit->setMinimum(1);
	mUserPinLimit->setMaximum(20);
	mUserPinLimit->setValue(3);
	gLayout->addWidget(new QLabel(tr("Password tries limit:")), 3, 0);
	gLayout->addWidget(mSoPinLimit, 3, 1);
	gLayout->addWidget(mUserPinLimit, 3, 2);
	
	mSoPin = new QLineEdit;
	mSoPin->setMaxLength(8);
	mSoPin->setEchoMode(QLineEdit::Password);
	mUserPin = new QLineEdit;
	mUserPin->setMaxLength(8);
	mUserPin->setEchoMode(QLineEdit::Password);
	gLayout->addWidget(new QLabel(tr("Password: ")), 4, 0);
	gLayout->addWidget(mSoPin, 4, 1);
	gLayout->addWidget(mUserPin, 4, 2);
	
	mSoPinCheck = new QLineEdit;
	mSoPinCheck->setMaxLength(8);
	mSoPinCheck->setEchoMode(QLineEdit::Password);
	mUserPinCheck = new QLineEdit;
	mUserPinCheck->setMaxLength(8);
	mUserPinCheck->setEchoMode(QLineEdit::Password);
	gLayout->addWidget(new QLabel(tr("Re-entered password: ")), 5, 0);
	gLayout->addWidget(mSoPinCheck, 5, 1);
	gLayout->addWidget(mUserPinCheck, 5, 2);
	
	mConfigure = new QPushButton(QIcon(QString(":img/configure.png")), tr("Configure"));
	gLayout->addWidget(mConfigure, 7, 2);
	connect(mConfigure, SIGNAL(clicked()), this, SLOT(confSlot()));
	
	gLayout->setRowStretch(6, 1);
	gBox->setLayout(gLayout);
	layout->addWidget(gBox, 1, 0);
	
	layout->setRowStretch(2, 1);
	mNotConfWidget->setLayout(layout);
	
	//////////////////////////////////////////////////////////////////////////////////////////////
	//
	//	Widget for locked token.
	//
	//////////////////////////////////////////////////////////////////////////////////////////////
	mLockWidget = new QWidget;
	layout = new QGridLayout;
	
	gBox = new QGroupBox(tr("Details"));
	vLayout = new QVBoxLayout;
	mLockTechInfo = new QLabel;
	vLayout->addWidget(mLockTechInfo);
	gBox->setLayout(vLayout);
	layout->addWidget(gBox, 0, 0);
	
	gBox = new QGroupBox(tr("Configuration details"));
	gLayout = new QGridLayout;
	
	mLockInfo = new QLabel;
	gLayout->addWidget(mLockInfo, 0, 0, 1, 3);
	
	mLockSoPin = new QLineEdit;
	mLockSoPin->setMaxLength(8);
	mLockSoPin->setEchoMode(QLineEdit::Password);
	gLayout->addWidget(new QLabel(tr("Administrator password: ")), 1, 0);
	gLayout->addWidget(mLockSoPin, 1, 1, 1, 2);
	
	mUnLock = new QPushButton(QIcon(QString(":img/unlock.png")), tr("Unlock"));
	gLayout->addWidget(mUnLock, 2, 2);
	connect(mUnLock, SIGNAL(clicked()), this, SLOT(unLockSlot()));
	
	gLayout->setColumnStretch(1, 1);
	gBox->setLayout(gLayout);
	layout->addWidget(gBox, 1, 0);
	
	layout->setRowStretch(2, 1);
	mLockWidget->setLayout(layout);
	
	//////////////////////////////////////////////////////////////////////////////////////////////
	//
	//	Add all widgets to stack.
	//
	//////////////////////////////////////////////////////////////////////////////////////////////
	addWidget(mConfWidget);
	addWidget(mNotConfWidget);
	addWidget(mLockWidget);
}

GenInfoWidget::~GenInfoWidget()
{
	clearInputs();
	clearFields();
}

void
GenInfoWidget::setInfo(const CRD_UT10XX_t *ut)
{
	const CRD_UT10XX_info_t *info = &ut->info;
	
	if (info->info & 0x04)
	{
		mLockTechInfo->setText(tr(
			"Serial number: <b>%1</b><br>"
			"Software version: <b>%2.%3</b><br>"
			"Available memory (bytes): <b>%4</b><br>"
			"Max number of keys: <b>%5</b><br>"
			"ECC domain: <b>%6</b><br>").
			arg(trUtf8(ut->serial_number)).
			arg(info->main_ver).
			arg(info->sub_ver).
			arg(info->public_mem).
			arg(info->keys_num).
			arg(info->ecc_params->name)
		);
		
		mLockInfo->setText(tr(
			"<h3 align=center>This token is locked</h3><br>"
			"Number / Limit of administrator password tries: <b>%1 / %2</b><br>").
			arg(info->so_pin_trys).
			arg(info->so_pin_limit)
		);
		
		setCurrentWidget(mLockWidget);
	}
	else if (info->info & 0x06)
	{
		mConfTechInfo->setText(tr(
			"Serial number: <b>%1</b><br>"
			"Software version: <b>%2.%3</b><br>"
			"Available memory (bytes): <b>%4</b><br>"
			"Max number of keys: <b>%5</b><br>"
			"ECC domain: <b>%6</b><br>").
			arg(trUtf8(ut->serial_number)).
			arg(info->main_ver).
			arg(info->sub_ver).
			arg(info->public_mem).
			arg(info->keys_num).
			arg(info->ecc_params->name)
		);
		
		mConfInfo->setText(tr(
			"Token name: <b>%1</b><br>"
			"Limit of User password tries: <b>%2</b><br>"
			"Limit of Administrator password tries: <b>%3</b><br>"
			"Administrator has permission to change User password: <b>%4</b><br>").
			arg(trUtf8(info->name)).
			arg(info->user_pin_limit).
			arg(info->so_pin_limit).
			arg((info->info & 0x10) ? tr("NO") : tr("YES"))
		);
		
		setCurrentWidget(mConfWidget);
	}
	else
	{
		mNotConfTechInfo->setText(tr(
			"Serial number: <b>%1</b><br>"
			"Software version: <b>%2.%3</b><br>"
			"Available memory (bytes): <b>%4</b><br>"
			"Max number of keys: <b>%5</b><br>"
			"ECC domain: <b>%6</b><br>").
			arg(trUtf8(ut->serial_number)).
			arg(info->main_ver).
			arg(info->sub_ver).
			arg(info->public_mem).
			arg(info->keys_num).
			arg(info->ecc_params->name)
		);
		
		setCurrentWidget(mNotConfWidget);
	}
}

void
GenInfoWidget::confSlot()
{
	mName = (mTokenName->text()).toUtf8();
	
	if (mName.length() > 11)
	{
		QMessageBox::critical(MainWindow::mainWnd, tr("Error"), tr("Token name is too long. It may contains up to 10 characters. National characters will be coded on 2 chars."));
		clearInputs();
		clearFields();
		return;
	}
	
	mSoPinLim = mSoPinLimit->value();
	mUserPinLim = mUserPinLimit->value();
	
	if (mSoPin->text() != mSoPinCheck->text())
	{
		QMessageBox::critical(MainWindow::mainWnd, tr("Error"), tr("Entered administrator passwords are not equal."));
		clearInputs();
		clearFields();
		return;
	}
	
	mSoPinBuf = (mSoPin->text()).toUtf8();
	
	if (mSoPinBuf.length() > 9)
	{
		QMessageBox::critical(MainWindow::mainWnd, tr("Error"), tr("Administrator password is too long. It may contains up to 8 characters. National characters will be coded on 2 chars."));
		clearInputs();
		clearFields();
		return;
	}
	
	if (mUserPin->text() != mUserPinCheck->text())
	{
		QMessageBox::critical(MainWindow::mainWnd, tr("Error"), tr("Entered User passwords are not equal."));
		clearInputs();
		clearFields();
		return;
	}
	
	mUserPinBuf = (mUserPin->text()).toUtf8();
	
	if (mUserPinBuf.length() > 9)
	{
		QMessageBox::critical(MainWindow::mainWnd, tr("Error"), tr("User password is too long. It may contains up to 8 characters. National characters will be coded on 2 chars."));
		clearInputs();
		clearFields();
		return;
	}
	
	mUpcna = 0;
	
	clearInputs();
	emit confSig(mName, mSoPinLim, mSoPinBuf, mUserPinLim, mUserPinBuf, mUpcna);
}

void
GenInfoWidget::unLockSlot()
{
	mSoPinBuf = (mLockSoPin->text()).toUtf8();
	clearInputs();
	emit unLockSig(mSoPinBuf);
	clearFields();
}

void
GenInfoWidget::clearFields()
{
	mName.clear();
	mSoPinLim = 0;
	mSoPinBuf.clear();
	mUserPinLim = 0;
	mUserPinBuf.clear();
	mUpcna = false;
}

void
GenInfoWidget::clearInputs()
{
	mTokenName->clear();
	mSoPinLimit->clear();
	mUserPinLimit->clear();
	mSoPin->clear();
	mSoPinCheck->clear();
	mUserPin->clear();
	mUserPinCheck->clear();
	
	mLockSoPin->clear();
}
