#include "inter.h"
#include "inter.moc"

#include <qmessagebox.h>
#include <qtimer.h>
#include <klocale.h>
#include <kapp.h>

#include "field.h"
#include "dialogs.h"
#include "version.h"
#include "defines.h"
#include "ai.h"

Interface::Interface(KAccel *kacc, QWidget *parent, const char *name)
: MPSimpleInterface(::gameInfo(), kacc, parent, name)
{
	setAction(i18n("Move left"),     "Move left",     SLOT(pMoveLeft()));
	setAction(i18n("Move right"),    "Move right",    SLOT(pMoveRight()));
	setAction(i18n("Drop down"),     "Drop down",     SLOT(pDropDown()));
	setAction(i18n("One line down"), "One line down", SLOT(pOneLineDown()));
	setAction(i18n("Rotate left"),   "Rotate left",   SLOT(pRotateLeft()));
	setAction(i18n("Rotate right"),  "Rotate right",  SLOT(pRotateRight()));

	QArray<const char **> defaultKeys(1);
	const char *oneHumanKeys[6]
		= { "Left", "Right", "Down", "Shift", "Up", "Return" };
	defaultKeys[0] = oneHumanKeys;
	setKeysConfiguration(defaultKeys);

	defaultKeys.resize(2);
	const char *twoHumansKeys[6] = { "F", "G", "D", "Space", "E", "Alt" };
	defaultKeys[0] = twoHumansKeys;
	defaultKeys[1] = oneHumanKeys;
	setKeysConfiguration(defaultKeys);

	kacc->readSettings(); // keys settings
}

MPBoard *Interface::newBoard(uint)
{
	Field *f = new Field(this);
	connect(this, SIGNAL(enablePreference(int, bool)),
			f, SLOT(enablePreference(int, bool)));
	connect(this, SIGNAL(AIConfigChangedSignal()), f, SLOT(AIConfigChanged()));
	setPreferences();
	return f;
}

void Interface::preferences()
{
	OptionDialog od(this);
	if ( !od.exec() ) return;
	setPreferences();
}

void Interface::setPreferences()
{
	emit enablePreference(Field::ShowShadow, OptionDialog::readShadow());
	emit enablePreference(Field::ShowNext, OptionDialog::readShowNext());
	emit enablePreference(Field::Animations, OptionDialog::readAnimations());
}

void Interface::configureAI()
{
	AI *ai = createAI();
	if ( ai->configDialog(this) ) emit AIConfigChangedSignal();
	delete ai;
}

void Interface::_init(bool server)
{
	if (server) data.resize(nbPlayers());
}

bool Interface::_readPlayData()
{
	bool end = FALSE;
	for (uint i=0; i<nbPlayers(); i++) {
		readingStream(i) >> data[i];
		if (data[i].end) end = TRUE;
	}
	return end;
}

void Interface::_sendPlayData()
{
	ServerPlayData sd;
	for(uint i=0; i<nbPlayers(); i++) {
		sd.prevHeight = data[prev(i)].height;
		sd.nextHeight = data[next(i)].height;
		sd.gift       = data[prev(i)].gift;
		writingStream(i) << sd;
	}
}

void Interface::_showGameOverData(bool server)
{
	if (server && nbPlayers()==1 ) {
		if ( HighScores::betterEntry(&gameOverData[0])==-1 ) return;
		HighScores hs(&gameOverData[0], this);
		hs.exec();
	} else {
		MultiScores ms(gameOverData.count(), this);
		for (uint i=0; i<gameOverData.count(); i++) ms.add(gameOverData[i]);
		ms.exec();
	}
}

uint Interface::prev(uint i) const
{
	if ( i==0 ) return nbPlayers()-1;
	else return i-1;
}

uint Interface::next(uint i) const
{
	if ( i==(nbPlayers()-1) ) return 0;
	else return i+1;
}

// server only
void Interface::_firstInit()
{
	// #### TODO (?)
}

void Interface::_treatInit()
{
	ServerInitData sid;
	sid.seed = kapp->random();
	for (uint i=0; i<nbPlayers(); i++) {
		sid.prevName = playerName(prev(i));
		sid.nextName = playerName(next(i));
		sid.name     = playerName(i);
		writingStream(i) << sid;
	}
}

void Interface::_sendGameOverData(QDataStream &s)
{
	gameOverData.clear();
	GameOverItem item;
	for (uint i=0; i<nbPlayers(); i++) {
		readingStream(i) >> item;
		item.name = playerName(i);
		gameOverData.append(item);
	}
	s << gameOverData;
}

// client only
void Interface::_readGameOverData(QDataStream &s)
{
	s >> gameOverData;
}
