#include "ConnectDialog.h"
#include "ui_ConnectDialog.h"
#include <QPushButton>
#include "ChatServer.h"
#include "ChatClient.h"
#include "MainWindow.h"

ConnectDialog::ConnectDialog(QWidget *parent) :
	QDialog(parent),
	ui(new Ui::ConnectDialog),
	chatServer(NULL),
	chatClient(NULL)
{
	ui->setupUi(this);

	buttonConnect = ui->buttonBox->addButton(tr("&Connect"), QDialogButtonBox::AcceptRole);
	buttonConnect->setDefault(true);
	buttonConnect->setEnabled(false);
	connect( buttonConnect, SIGNAL(clicked()), this, SLOT(buttonConnectPressed()) );

	connect( ui->buttonBox, SIGNAL(rejected()), this, SLOT(close()) );
	connect( ui->radioButtonServerMode, SIGNAL(clicked()), this, SLOT(serverModeSelected()) );
	connect( ui->radioButtonClientMode, SIGNAL(clicked()), this, SLOT(clientModeSelected()) );

	// Try to enable connect button
	connect( ui->lineEditNickname, SIGNAL(textChanged(QString)), this, SLOT(tryEnableConnectButton()) );
	connect( ui->lineEditAddress, SIGNAL(textChanged(QString)), this, SLOT(tryEnableConnectButton()) );
	connect( ui->lineEditPort, SIGNAL(textChanged(QString)), this, SLOT(tryEnableConnectButton()) );
}

ConnectDialog::~ConnectDialog()
{
	delete ui;
}

QString ConnectDialog::getUserNickname() const
{
	return ui->lineEditNickname->text().trimmed();
}

void ConnectDialog::tryEnableConnectButton()
{
	buttonConnect->setEnabled( canEnableConnectButton() );
}

void ConnectDialog::serverModeSelected()
{
	ui->lineEditAddress->setEnabled(false);
	tryEnableConnectButton();
}

void ConnectDialog::clientModeSelected()
{
	ui->lineEditAddress->setEnabled(true);
	tryEnableConnectButton();
}

void ConnectDialog::buttonConnectPressed()
{
	ui->radioButtonServerMode->isChecked() ? connectAsServer() : connectAsClient();
}

bool ConnectDialog::canEnableConnectButton() const
{
	// Nickname is always required
	if ( ui->lineEditNickname->text().trimmed().isEmpty() )
		return false;

	// Address (IP or domain) is only required in client mode
	if ( ui->radioButtonClientMode->isChecked() && ui->lineEditAddress->text().trimmed().isEmpty() )
		return false;

	// Port is always required
	if ( ui->lineEditPort->text().trimmed().isEmpty() ) return false;

	// Everything is suffixed, connect button can be enabled
	return true;
}

bool ConnectDialog::connectAsServer()
{
	if ( ! chatServer ) chatServer = new ChatServer(this);
	int port = ui->lineEditPort->text().toInt();
	if ( ! chatServer->listen(QHostAddress::Any, port) )
	{
		qDebug("Failed to bind to port %i", port);
		return false;
	}

	qDebug("Listening in port %i", port);
	close();
	return true;
}

bool ConnectDialog::connectAsClient()
{
	MainWindow* mainWindow = dynamic_cast<MainWindow*>(parent());
	Q_ASSERT(mainWindow);

	if ( ! chatClient ) chatClient = new ChatClient(mainWindow, this);
	QString address = ui->lineEditAddress->text();
	int port = ui->lineEditPort->text().toInt();
	chatClient->connectToHost(address, port);
	qDebug("Connecting to server %s:%i...", qPrintable(address), port);
	connect(chatClient, SIGNAL(connected()), this, SLOT(close()));
	return true;
}
