#include "loginWidget.h"

void LoginWidget::submitButtonClickedSlot(bool checked) {
	LoginDetails loginDetails = getLoginDetailsFromForm();
	emit submitLoginSignal(loginDetails);
}
void LoginWidget::saveButtonClickedSlot(bool checked) {

	int result = showConfirmSaveDialog();

	if (result == QDialog::Accepted) {
		LoginDetails loginDetails = getLoginDetailsFromForm();

		if (selectedIndex_ != - 1) {
			allLoginDetails_[selectedIndex_] = loginDetails;

			int rowForIndex = findRowByIndex(selectedIndex_);

			if (rowForIndex != -1) {
				QTableWidgetItem * loginItem = ui_.loginItemsTable->item(rowForIndex, 0);
				QTableWidgetItem * serverItem = ui_.loginItemsTable->item(rowForIndex, 1);
				QTableWidgetItem * portItem = ui_.loginItemsTable->item(rowForIndex, 2);

				QString login = QString::fromUtf8(loginDetails.name.c_str());
				QString password = QString::fromUtf8(loginDetails.password.c_str());
				QString server = QString::fromUtf8(loginDetails.server.c_str());
				QString port = QString::number(loginDetails.port);

				loginItem->setText(login);
				serverItem->setText(server);
				portItem->setText(port);
			}	
		}

		saveConnections(filePath_);
	}	
}

void LoginWidget::addButtonClickedSlot(bool checked) {
	int result = showConfirmAddDialog();

	if (result == QDialog::Accepted) {
		LoginDetails loginDetails = getLoginDetailsFromForm();

		QString login = QString::fromUtf8(loginDetails.name.c_str());
		QString password = QString::fromUtf8(loginDetails.password.c_str());
		QString server = QString::fromUtf8(loginDetails.server.c_str());
		QString port = QString::number(loginDetails.port);

		insertConnectionItem(login, password, server, port);

		int selectedIndex = ui_.loginItemsTable->rowCount();
		ui_.removeButton->setEnabled(true);

		ui_.loginItemsTable->clearSelection();

		int lastRow = ui_.loginItemsTable->rowCount() - 1;

		QTableWidgetItem * loginItem = ui_.loginItemsTable->item(lastRow, 0);
		QTableWidgetItem * serverItem = ui_.loginItemsTable->item(lastRow, 1);
		QTableWidgetItem * portItem = ui_.loginItemsTable->item(lastRow, 2);

		if (loginItem && serverItem && portItem) {
			loginItem->setSelected(true);
			serverItem->setSelected(true);
			portItem->setSelected(true);
		}

		saveConnections(filePath_);
	}
}

void LoginWidget::removeButtonClickedSlot(bool checked) {
	int result = showConfirmRemoveDialog();

	if (result == QDialog::Accepted) {
		if (selectedIndex_ == -1) {
			return;
		}

		int rowForIndex = findRowByIndex(selectedIndex_);	

		if (rowForIndex != -1) {
			ui_.loginItemsTable->removeRow(rowForIndex);
			allLoginDetails_.erase(selectedIndex_);
		}

		ui_.loginItemsTable->clearSelection();
		selectedIndex_ = -1;

		ui_.removeButton->setEnabled(false);

		clearForm();

		saveConnections(filePath_);
	}
}

std::pair<int, LoginDetails> LoginWidget::getLoginDetailsFromTable(int row, int column) {
	QTableWidgetItem * loginItem = ui_.loginItemsTable->item(row, 0);		
	int index = loginItem->data(Qt::UserRole).toInt();
	return std::make_pair(index, allLoginDetails_[index]);
}

void LoginWidget::cellDoubleClickedSlot(int row, int column) {
	LoginDetails loginDetails = getLoginDetailsFromTable(row, column).second;
	emit submitLoginSignal(loginDetails);
}

void LoginWidget::cellClickedSlot(int row, int column) {
	std::pair<int, LoginDetails> loginPair = getLoginDetailsFromTable(row, column);

	int index = loginPair.first;
	LoginDetails details = loginPair.second;

	ui_.loginEdit->setText(QString::fromUtf8(details.name.c_str()));
	ui_.passwordEdit->setText(QString::fromUtf8(details.password.c_str()));
	ui_.serverEdit->setText(QString::fromUtf8(details.server.c_str()));
	ui_.portEdit->setText(QString::number(details.port));

	selectedIndex_ = index;

	ui_.saveButton->setEnabled(false);
	ui_.addButton->setEnabled(false);
	ui_.removeButton->setEnabled(true);
}

void LoginWidget::settingsChangedSlot() {
	bool isCorrect = true;

	if (ui_.loginEdit->text().isEmpty()) {
		isCorrect = false;
	}

	if (ui_.passwordEdit->text().isEmpty()) {
		isCorrect = false;
	}

	if (ui_.serverEdit->text().isEmpty()) {
		isCorrect = false;
	}

	if (ui_.portEdit->text().isEmpty()) {
		isCorrect = false;
	}

	if (isCorrect) {
		ui_.addButton->setEnabled(true);

		if (selectedIndex_ != -1) {
			ui_.saveButton->setEnabled(true);
		}
		else {
			ui_.saveButton->setEnabled(false);
		}
	}
	else {
		ui_.addButton->setEnabled(false);
		ui_.saveButton->setEnabled(false);
	}
}

LoginWidget::LoginWidget(QWidget * parent) : QWidget(parent) {
	ui_.setupUi(this);

	selectedIndex_ = -1;

	confirmDialog_ = NULL;

	ui_.loginSection->setName(L"Přihlášení do hry");

	ui_.loginItemsTable->horizontalHeader()->resize(120, 20);
	ui_.passwordEdit->setEchoMode(QLineEdit::Password);

	ui_.saveButton->setEnabled(false);
	ui_.addButton->setEnabled(false);
	ui_.removeButton->setEnabled(false);

	bool isConnected = true;	
		
	isConnected = isConnected && connect(ui_.submitButton, SIGNAL(clicked(bool)), this, SLOT(submitButtonClickedSlot(bool)));	
	isConnected = isConnected && connect(ui_.saveButton, SIGNAL(clicked(bool)), this, SLOT(saveButtonClickedSlot(bool)));	
	isConnected = isConnected && connect(ui_.addButton, SIGNAL(clicked(bool)), this, SLOT(addButtonClickedSlot(bool)));	
	isConnected = isConnected && connect(ui_.removeButton, SIGNAL(clicked(bool)), this, SLOT(removeButtonClickedSlot(bool)));	

	isConnected = isConnected && connect(ui_.loginItemsTable, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(cellDoubleClickedSlot(int, int)));
	isConnected = isConnected && connect(ui_.loginItemsTable, SIGNAL(cellClicked(int,int)), this, SLOT(cellClickedSlot(int, int)));

	isConnected = isConnected && connect(ui_.loginEdit, SIGNAL(textChanged(const QString &)), this, SLOT(settingsChangedSlot()));
	isConnected = isConnected && connect(ui_.passwordEdit, SIGNAL(textChanged(const QString &)), this, SLOT(settingsChangedSlot()));
	isConnected = isConnected && connect(ui_.serverEdit, SIGNAL(textChanged(const QString &)), this, SLOT(settingsChangedSlot()));
	isConnected = isConnected && connect(ui_.portEdit, SIGNAL(textChanged(const QString &)), this, SLOT(settingsChangedSlot()));

	isConnected = isConnected && connect(ui_.registerButton, SIGNAL(clicked(bool)), this, SLOT(registerButtonClickedSlot()));

	assert(isConnected && "Signals not connected");
}

void LoginWidget::setEnabled(bool enabled) {
	QWidget::setEnabled(enabled);
	ui_.passwordEdit->setEnabled(true);
	ui_.loginEdit->setEnabled(true);
}

void LoginWidget::loadConnections(const QString & filePath) {		
	this->filePath_ = filePath;

	QFile file(filePath);

	if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
		return;
	}

	QTextStream in(&file);

	while (!in.atEnd()) {
		QString line = in.readLine();

		if (line == "") {
			continue;
		}

		QStringList parts = line.split(";");

		if (parts.size() != 4) {
			continue;
		}

		QString login = parts[0];
		QString password = parts[1];
		QString server = parts[2];
		QString port = parts[3];

		if (login == "admin") {
			continue;
		}

		insertConnectionItem(login, password, server, port);
	}

	file.close();

	ui_.loginItemsTable->resizeColumnsToContents();
}

void LoginWidget::saveConnections() {
	saveConnections(filePath_);
}

void LoginWidget::saveConnections(const QString & filePath) {
	QFile file(filePath);
		
	if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
		return;
	}

	for (std::map<int, LoginDetails>::const_iterator it = allLoginDetails_.begin(); it != allLoginDetails_.end(); ++it) {
		QTextStream out(&file);
		const LoginDetails & loginDetails = (it->second);
			
		QString login = QString::fromUtf8(loginDetails.name.c_str());
		QString password = QString::fromUtf8(loginDetails.password.c_str());
		QString server = QString::fromUtf8(loginDetails.server.c_str());
		QString port = QString::number(loginDetails.port);

		out << login << ";" << password << ";" << server << ";" << port << "\n";
	}

	file.close();
}

LoginDetails LoginWidget::getLoginDetailsFromForm() {
	LoginDetails loginDetails;
	loginDetails.name = ui_.loginEdit->text().toUtf8().data();
	loginDetails.password = ui_.passwordEdit->text().toUtf8().data();
	loginDetails.server = ui_.serverEdit->text().toUtf8().data();
	loginDetails.port = ui_.portEdit->text().toULong();

	return loginDetails;
}

void LoginWidget::clearForm() {
	ui_.loginEdit->setText("");
	ui_.passwordEdit->setText("");
	ui_.serverEdit->setText("");
	ui_.portEdit->setText("");
}

int LoginWidget::findRowByIndex(int index) {
	for (int row = 0; row < ui_.loginItemsTable->rowCount(); ++row) {
		QTableWidgetItem * item = ui_.loginItemsTable->item(row, 0);

		if (item != NULL) {
			int indexOfRow = item->data(Qt::UserRole).toInt();
			if (indexOfRow == index) {
				return row;
			}
		}
	}

	return -1;
}

void LoginWidget::insertConnectionItem(QString login, QString password, QString server, QString port) {
	int rowCount = ui_.loginItemsTable->rowCount();
	ui_.loginItemsTable->insertRow(rowCount);

	LoginDetails loginDetails;
	loginDetails.name = login.toUtf8();
	loginDetails.password = password.toUtf8();
	loginDetails.server = server.toUtf8();
	loginDetails.port = port.toULong();

	allLoginDetails_.insert(std::make_pair(rowCount, loginDetails));

	QTableWidgetItem * loginItem = new QTableWidgetItem(login);
	loginItem->setData(Qt::UserRole, rowCount);

	ui_.loginItemsTable->setItem(rowCount, 0, loginItem);
	ui_.loginItemsTable->setItem(rowCount, 1, new QTableWidgetItem(server));
	ui_.loginItemsTable->setItem(rowCount, 2, new QTableWidgetItem(port));
}

int LoginWidget::showConfirmDialog(const std::wstring & title, const std::wstring & text) {
	if (confirmDialog_ == NULL) {
		confirmDialog_ = new ConfirmDialog(this);	
		confirmDialog_->setModal(true);
		confirmDialog_->setWindowFlags(Qt::SplashScreen);
	}

    confirmDialog_->activateWindow();
	confirmDialog_->setTitle(title);
	confirmDialog_->setMessage(text);

	return confirmDialog_->exec();
}

int LoginWidget::showConfirmAddDialog() {
	return showConfirmDialog(L"Přidání nového spojení", L"Opravdu chceš přidat nové spojení?");
}

int LoginWidget::showConfirmSaveDialog() {
	return showConfirmDialog(L"Uložení změněného spojení", L"Opravdu chceš uložit provedené změny ve spojení?");
}

int LoginWidget::showConfirmRemoveDialog() {
	return showConfirmDialog(L"Odebrání zadaného spojení", L"Opravdu chceš odebrat zadané spojení?");
}

LoginWidget::~LoginWidget() {
	if (confirmDialog_ != NULL) {
		delete confirmDialog_;
	}
}

void LoginWidget::registerButtonClickedSlot() {
	RegistrationData data;

	data.realname = ui_.registerNameEdit->text().toUtf8().data();
	data.username = ui_.registerLoginEdit->text().toUtf8().data();
	data.password = ui_.registerPasswordEdit->text().toUtf8().data();

	data.server = ui_.registerServerEdit->text().toUtf8().data();
	data.port = ui_.registerPortEdit->text().toULong();

	emit submitRegistrationSignal(data);	
}

void LoginWidget::addConnection(const LoginDetails & details) {
    for (int i = ui_.loginItemsTable->rowCount() - 1; i >= 0; --i) {
		ui_.loginItemsTable->removeRow(i);
    } 

	allLoginDetails_.clear();

	loadConnections(filePath_);

	insertConnectionItem(
		QString::fromUtf8(details.name.c_str()),
		QString::fromUtf8(details.password.c_str()),
		QString::fromUtf8(details.server.c_str()),
		QString::number(details.port));

	saveConnections(filePath_);
}