#include <tdeaction.h>
#include <tdeapplication.h>
#include <tdeconfig.h>
#include <kdebug.h>
#include <tdeversion.h>
#include <tdefiledialog.h>
#include <tdeglobal.h>
#include <tdeio/netaccess.h>
#include <tdelocale.h>
#include <tdemainwindow.h>
#include <kmimetype.h>
#include <tdemessagebox.h>
#include <kprinter.h>
#include <highscore/kscoredialog.h>
#include <kstandarddirs.h>
#include <kstatusbar.h>
#include <tdestdaccel.h>
#include <kstdaction.h>
#include <kstdgameaction.h>
#include <kstdguiitem.h>

#include <tqcolor.h>
#include <tqevent.h>
#include <tqfile.h>
#include <tqobject.h>
#include <tqmap.h>
#include <tqpoint.h>
#include <tqtimer.h>
#include <tqptrlist.h>
#include <tqpixmap.h>
#include <tqpixmapcache.h>
#include <tqfileinfo.h>
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqlayout.h>
#include <tqwidget.h>

#include <stdlib.h>

#include "game.h"
#include "floater.h"
#include "slope.h"
#include "newgame.h"
#include "scoreboard.h"
#include "editor.h"
#include "pluginloader.h"
#include "printdialogpage.h"
#include "kolf.h"

Kolf::Kolf()
    : TDEMainWindow(0, "Kolf")
{
	competition = false;
	game = 0;
	editor = 0;
	spacer = 0;
	scoreboard = 0;
	isTutorial = false;

	initGUI();

	obj = new ObjectList;
	initPlugins();

	filename = TQString();
	dummy = new TQWidget(this);
	setCentralWidget(dummy);
	layout = new TQGridLayout(dummy, 3, 1);

	resize(420, 480);
}

Kolf::~Kolf()
{
	// wipe out our objects
	obj->setAutoDelete(true);
	delete obj;
}

void Kolf::initGUI()
{
	newAction = KStdGameAction::gameNew(this, TQ_SLOT(newGame()), actionCollection());
	newAction->setText(newAction->text() + TQString("..."));

	endAction = KStdGameAction::end(this, TQ_SLOT(closeGame()), actionCollection());
	printAction = KStdGameAction::print(this, TQ_SLOT(print()), actionCollection());

	(void) KStdGameAction::quit(this, TQ_SLOT(close()), actionCollection());
	saveAction = KStdAction::save(this, TQ_SLOT(save()), actionCollection(), "game_save");
	saveAction->setText(i18n("Save &Course"));
	saveAsAction = KStdAction::saveAs(this, TQ_SLOT(saveAs()), actionCollection(), "game_save_as");
	saveAsAction->setText(i18n("Save &Course As..."));

	saveGameAction = new TDEAction(i18n("&Save Game"), 0, this, TQ_SLOT(saveGame()), actionCollection(), "savegame");
	saveGameAsAction = new TDEAction(i18n("&Save Game As..."), 0, this, TQ_SLOT(saveGameAs()), actionCollection(), "savegameas");

	loadGameAction = KStdGameAction::load(this, TQ_SLOT(loadGame()), actionCollection());
	loadGameAction->setText(i18n("Load Saved Game..."));

	highScoreAction = KStdGameAction::highscores(this, TQ_SLOT(showHighScores()), actionCollection());

	editingAction = new TDEToggleAction(i18n("&Edit"), "pencil", CTRL+Key_E, this, TQ_SLOT(emptySlot()), actionCollection(), "editing");
	newHoleAction = new TDEAction(i18n("&New"), "document-new", CTRL+SHIFT+Key_N, this, TQ_SLOT(emptySlot()), actionCollection(), "newhole");
	clearHoleAction = new TDEAction(KStdGuiItem::clear().text(), "locationbar_erase", CTRL+Key_Delete, this, TQ_SLOT(emptySlot()), actionCollection(), "clearhole");
	resetHoleAction = new TDEAction(i18n("&Reset"), CTRL+Key_R, this, TQ_SLOT(emptySlot()), actionCollection(), "resethole");
	undoShotAction = KStdAction::undo(this, TQ_SLOT(emptySlot()), actionCollection(), "undoshot");
	undoShotAction->setText(i18n("&Undo Shot"));
	//replayShotAction = new TDEAction(i18n("&Replay Shot"), 0, this, TQ_SLOT(emptySlot()), actionCollection(), "replay");

	holeAction = new TDEListAction(i18n("Switch to Hole"), 0, this, TQ_SLOT(emptySlot()), actionCollection(), "switchhole");
	nextAction = new TDEAction(i18n("&Next Hole"), "forward", TDEStdAccel::shortcut(TDEStdAccel::Forward), this, TQ_SLOT(emptySlot()), actionCollection(), "nexthole");
	prevAction = new TDEAction(i18n("&Previous Hole"), "back", TDEStdAccel::shortcut(TDEStdAccel::Back), this, TQ_SLOT(emptySlot()), actionCollection(), "prevhole");
	firstAction = new TDEAction(i18n("&First Hole"), "go-home", TDEStdAccel::shortcut(TDEStdAccel::Home), this, TQ_SLOT(emptySlot()), actionCollection(), "firsthole");
	lastAction = new TDEAction(i18n("&Last Hole"), CTRL+SHIFT+Key_End, this, TQ_SLOT(emptySlot()), actionCollection(), "lasthole");
	randAction = new TDEAction(i18n("&Random Hole"), "goto", 0, this, TQ_SLOT(emptySlot()), actionCollection(), "randhole");

	useMouseAction = new TDEToggleAction(i18n("Enable &Mouse for Moving Putter"), 0, this, TQ_SLOT(emptySlot()), actionCollection(), "usemouse");
	useMouseAction->setCheckedState(i18n("Disable &Mouse for Moving Putter"));
	connect(useMouseAction, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(useMouseChanged(bool)));
	TDEConfig *config = kapp->config();
	config->setGroup("Settings");
	useMouseAction->setChecked(config->readBoolEntry("useMouse", true));

	useAdvancedPuttingAction = new TDEToggleAction(i18n("Enable &Advanced Putting"), 0, this, TQ_SLOT(emptySlot()), actionCollection(), "useadvancedputting");
	useAdvancedPuttingAction->setCheckedState(i18n("Disable &Advanced Putting"));
	connect(useAdvancedPuttingAction, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(useAdvancedPuttingChanged(bool)));
	useAdvancedPuttingAction->setChecked(config->readBoolEntry("useAdvancedPutting", false));

	showInfoAction = new TDEToggleAction(i18n("Show &Info"), "application-vnd.tde.info", CTRL+Key_I, this, TQ_SLOT(emptySlot()), actionCollection(), "showinfo");
	showInfoAction->setCheckedState(i18n("Hide &Info"));
	connect(showInfoAction, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(showInfoChanged(bool)));
	showInfoAction->setChecked(config->readBoolEntry("showInfo", false));

	showGuideLineAction = new TDEToggleAction(i18n("Show Putter &Guideline"), 0, this, TQ_SLOT(emptySlot()), actionCollection(), "showguideline");
	showGuideLineAction->setCheckedState(i18n("Hide Putter &Guideline"));
	connect(showGuideLineAction, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(showGuideLineChanged(bool)));
	showGuideLineAction->setChecked(config->readBoolEntry("showGuideLine", true));

	TDEToggleAction *act=new TDEToggleAction(i18n("Enable All Dialog Boxes"), 0, this, TQ_SLOT(enableAllMessages()), actionCollection(), "enableAll");
	act->setCheckedState(i18n("Disable All Dialog Boxes"));

	soundAction = new TDEToggleAction(i18n("Play &Sounds"), 0, this, TQ_SLOT(emptySlot()), actionCollection(), "audio-x-generic");
	connect(soundAction, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(soundChanged(bool)));
	soundAction->setChecked(config->readBoolEntry("sound", true));

	(void) new TDEAction(i18n("&Reload Plugins"), 0, this, TQ_SLOT(initPlugins()), actionCollection(), "reloadplugins");
	(void) new TDEAction(i18n("Show &Plugins"), 0, this, TQ_SLOT(showPlugins()), actionCollection(), "showplugins");

	aboutAction = new TDEAction(i18n("&About Course"), 0, this, TQ_SLOT(emptySlot()), actionCollection(), "aboutcourse");
	tutorialAction = new TDEAction(i18n("&Tutorial"), 0, this, TQ_SLOT(tutorial()), actionCollection(), "tutorial");

	statusBar();
	setupGUI();
}

bool Kolf::queryClose()
{
	if (game)
		if (game->askSave(true))
			return false;
	return true;
}

void Kolf::startNewGame()
{
	NewGameDialog *dialog = 0;
	int firstHole = 1;

	if (loadedGame.isNull())
	{
		dialog = new NewGameDialog(filename.isNull(), dummy, "New Game Dialog");
		if (dialog->exec() != TQDialog::Accepted)
			goto end;
	}

	players.clear();
	delete scoreboard;
	scoreboard = new ScoreBoard(dummy, "Score Board");
	layout->addWidget(scoreboard, 1, 0);
	scoreboard->show();

	if (loadedGame.isNull())
	{
		PlayerEditor *curEditor = 0;
		int newId = 1;
		for (curEditor = dialog->players()->first(); curEditor; curEditor = dialog->players()->next(), ++newId)
		{
			players.append(Player());
			players.last().ball()->setColor(curEditor->color());
			players.last().setName(curEditor->name());
			players.last().setId(newId);
		}

		competition = dialog->competition();
		filename = filename.isNull()? dialog->course() : filename;
	}
	else
	{
		TDEConfig config(loadedGame);
		config.setGroup("0 Saved Game");

		if (isTutorial)
			filename = TDEGlobal::dirs()->findResource("appdata", "tutorial.kolf");
		else
			filename = config.readEntry("Course", TQString());

		if (filename.isNull())
			return;

		competition = config.readBoolEntry("Competition", false);
		firstHole = config.readNumEntry("Current Hole", 1);

		players.clear();
		KolfGame::scoresFromSaved(&config, players);
	}

	for (PlayerList::Iterator it = players.begin(); it != players.end(); ++it)
		scoreboard->newPlayer((*it).name());

	delete spacer;
	spacer = 0;
	delete game;
	game = new KolfGame(obj, &players, filename, dummy);
	game->setStrict(competition);

	connect(game, TQ_SIGNAL(newHole(int)), scoreboard, TQ_SLOT(newHole(int)));
	connect(game, TQ_SIGNAL(scoreChanged(int, int, int)), scoreboard, TQ_SLOT(setScore(int, int, int)));
	connect(game, TQ_SIGNAL(parChanged(int, int)), scoreboard, TQ_SLOT(parChanged(int, int)));
	connect(game, TQ_SIGNAL(modifiedChanged(bool)), this, TQ_SLOT(updateModified(bool)));
	connect(game, TQ_SIGNAL(newPlayersTurn(Player *)), this, TQ_SLOT(newPlayersTurn(Player *)));
	connect(game, TQ_SIGNAL(holesDone()), this, TQ_SLOT(gameOver()));
	connect(game, TQ_SIGNAL(checkEditing()), this, TQ_SLOT(checkEditing()));
	connect(game, TQ_SIGNAL(editingStarted()), this, TQ_SLOT(editingStarted()));
	connect(game, TQ_SIGNAL(editingEnded()), this, TQ_SLOT(editingEnded()));
	connect(game, TQ_SIGNAL(inPlayStart()), this, TQ_SLOT(inPlayStart()));
	connect(game, TQ_SIGNAL(inPlayEnd()), this, TQ_SLOT(inPlayEnd()));
	connect(game, TQ_SIGNAL(maxStrokesReached(const TQString &)), this, TQ_SLOT(maxStrokesReached(const TQString &)));
	connect(game, TQ_SIGNAL(largestHole(int)), this, TQ_SLOT(updateHoleMenu(int)));
	connect(game, TQ_SIGNAL(titleChanged(const TQString &)), this, TQ_SLOT(titleChanged(const TQString &)));
	connect(game, TQ_SIGNAL(newStatusText(const TQString &)), this, TQ_SLOT(newStatusText(const TQString &)));
	connect(game, TQ_SIGNAL(currentHole(int)), this, TQ_SLOT(setCurrentHole(int)));
	connect(holeAction, TQ_SIGNAL(activated(const TQString &)), game, TQ_SLOT(switchHole(const TQString &)));
	connect(nextAction, TQ_SIGNAL(activated()), game, TQ_SLOT(nextHole()));
	connect(prevAction, TQ_SIGNAL(activated()), game, TQ_SLOT(prevHole()));
	connect(firstAction, TQ_SIGNAL(activated()), game, TQ_SLOT(firstHole()));
	connect(lastAction, TQ_SIGNAL(activated()), game, TQ_SLOT(lastHole()));
	connect(randAction, TQ_SIGNAL(activated()), game, TQ_SLOT(randHole()));
	connect(editingAction, TQ_SIGNAL(activated()), game, TQ_SLOT(toggleEditMode()));
	connect(newHoleAction, TQ_SIGNAL(activated()), game, TQ_SLOT(addNewHole()));
	connect(clearHoleAction, TQ_SIGNAL(activated()), game, TQ_SLOT(clearHole()));
	connect(resetHoleAction, TQ_SIGNAL(activated()), game, TQ_SLOT(resetHole()));
	connect(undoShotAction, TQ_SIGNAL(activated()), game, TQ_SLOT(undoShot()));
	//connect(replayShotAction, TQ_SIGNAL(activated()), game, TQ_SLOT(replay()));
	connect(aboutAction, TQ_SIGNAL(activated()), game, TQ_SLOT(showInfoDlg()));
	connect(useMouseAction, TQ_SIGNAL(toggled(bool)), game, TQ_SLOT(setUseMouse(bool)));
	connect(useAdvancedPuttingAction, TQ_SIGNAL(toggled(bool)), game, TQ_SLOT(setUseAdvancedPutting(bool)));
	connect(soundAction, TQ_SIGNAL(toggled(bool)), game, TQ_SLOT(setSound(bool)));
	connect(showGuideLineAction, TQ_SIGNAL(toggled(bool)), game, TQ_SLOT(setShowGuideLine(bool)));
	connect(showInfoAction, TQ_SIGNAL(toggled(bool)), game, TQ_SLOT(setShowInfo(bool)));

	game->setUseMouse(useMouseAction->isChecked());
	game->setUseAdvancedPutting(useAdvancedPuttingAction->isChecked());
	game->setShowInfo(showInfoAction->isChecked());
	game->setShowGuideLine(showGuideLineAction->isChecked());
	game->setSound(soundAction->isChecked());

	layout->addWidget(game, 0, 0, AlignCenter);

	game->show();
	game->setFocus();

	setEditingEnabled(true);
	endAction->setEnabled(true);
	setHoleMovementEnabled(true);
	setHoleOtherEnabled(true);
	aboutAction->setEnabled(true);
	highScoreAction->setEnabled(true);
	printAction->setEnabled(true);
	saveAction->setEnabled(true);
	saveAsAction->setEnabled(true);
	saveGameAction->setEnabled(true);
	saveGameAsAction->setEnabled(true);

	clearHoleAction->setEnabled(false);
	newHoleAction->setEnabled(false);
	newAction->setEnabled(false);
	loadGameAction->setEnabled(false);
	tutorialAction->setEnabled(false);


	// so game can do stuff that needs to be done
	// after things above are connected
	game->startFirstHole(firstHole);

	end:
	delete dialog;
}

void Kolf::newGame()
{
	isTutorial = false;
	filename = TQString();
	startNewGame();
}

void Kolf::tutorial()
{
	TQString newfilename = TDEGlobal::dirs()->findResource("appdata", "tutorial.kolfgame");
	if (newfilename.isNull())
	        return;

	filename = TQString();
	loadedGame = newfilename;
	isTutorial = true;

	startNewGame();

	loadedGame = TQString();
}

void Kolf::closeGame()
{
	if (game)
	{
		if (game->askSave(true))
			return;
		game->pause();
	}

	filename = TQString();

	editingEnded();
	delete game;
	game = 0;
	loadedGame = TQString();

	editingAction->setChecked(false);
	setEditingEnabled(false);
	endAction->setEnabled(false);
	aboutAction->setEnabled(false);
	highScoreAction->setEnabled(false);
	printAction->setEnabled(false);
	saveAction->setEnabled(false);
	saveAsAction->setEnabled(false);
	saveGameAction->setEnabled(false);
	saveGameAsAction->setEnabled(false);
	setHoleMovementEnabled(false);
	setHoleOtherEnabled(false);

	clearHoleAction->setEnabled(false);
	newHoleAction->setEnabled(false);
	newAction->setEnabled(true);
	loadGameAction->setEnabled(true);
	tutorialAction->setEnabled(true);

	titleChanged(TQString());
	updateModified(false);

	TQTimer::singleShot(100, this, TQ_SLOT(createSpacer()));
}

void Kolf::createSpacer()
{
	// make a player to play the spacer hole
	spacerPlayers.clear();
	spacerPlayers.append(Player());
	spacerPlayers.last().ball()->setColor(yellow);
	spacerPlayers.last().setName("player");
	spacerPlayers.last().setId(1);

	delete spacer;
	spacer = new KolfGame(obj, &spacerPlayers, TDEGlobal::dirs()->findResource("appdata", "intro"), dummy);
	spacer->setSound(false);
	spacer->startFirstHole(1);
	layout->addWidget(spacer, 0, 0, AlignCenter);
	spacer->hidePutter();
	spacer->ignoreEvents(true);

	spacer->show();
}

void Kolf::gameOver()
{
	int curPar = 0;
	int lowScore = INT_MAX; // let's hope it doesn't stay this way!
	int curScore = 1;

	// names of people who had the lowest score
	TQStringList names;

	HighScoreList highScores;
	int scoreBoardIndex = 1;

	while (curScore != 0)
	{
		TQString curName;

		// name taken as a reference and filled out
		curScore = scoreboard->total(scoreBoardIndex, curName);

		scoreBoardIndex++;

		if (curName == i18n("Par"))
		{
			curPar = curScore;
			continue;
		}

		if (curScore == 0)
			continue;

		// attempt to add everybody to the highscore list
		// (ignored if we aren't competing down below)
		highScores.append(HighScore(curName, curScore));

		if (curScore < lowScore)
		{
			names.clear();
			lowScore = curScore;
			names.append(curName);
		}
		else if (curScore == lowScore)
			names.append(curName);
	}

	// only announce a winner if more than two entries
	// (player and par) are on the scoreboard + one to go past end
	// + 1 for koodoo
	if (scoreBoardIndex > 4)
	{
		if (names.count() > 1)
		{
			TQString winners = names.join(i18n(" and "));
			KMessageBox::information(this, i18n("%1 tied").arg(winners));
		}
		else
			KMessageBox::information(this, i18n("%1 won!").arg(names.first()));
	}

	if (competition)
	{
		// deal with highscores
		// KScoreDialog makes it very easy :-))

		KScoreDialog *scoreDialog = new KScoreDialog(KScoreDialog::Name | KScoreDialog::Custom1 | KScoreDialog::Score, this);
		scoreDialog->addField(KScoreDialog::Custom1, i18n("Par"), "Par");

		CourseInfo courseInfo;
		game->courseInfo(courseInfo, game->curFilename());

		scoreDialog->setConfigGroup(courseInfo.untranslatedName + TQString(" Highscores"));

		for (HighScoreList::Iterator it = highScores.begin(); it != highScores.end(); ++it)
		{
			KScoreDialog::FieldInfo info;
			info[KScoreDialog::Name] = (*it).name;
			info[KScoreDialog::Custom1] = TQString::number(curPar);

			scoreDialog->addScore((*it).score, info, false, true);
		}

		scoreDialog->setComment(i18n("High Scores for %1").arg(courseInfo.name));
		scoreDialog->show();
	}

	TQTimer::singleShot(700, this, TQ_SLOT(closeGame()));
}

void Kolf::showHighScores()
{
	KScoreDialog *scoreDialog = new KScoreDialog(KScoreDialog::Name | KScoreDialog::Custom1 | KScoreDialog::Score, this);
	scoreDialog->addField(KScoreDialog::Custom1, i18n("Par"), "Par");

	CourseInfo courseInfo;
	game->courseInfo(courseInfo, game->curFilename());

	scoreDialog->setConfigGroup(courseInfo.untranslatedName + TQString(" Highscores"));
	scoreDialog->setComment(i18n("High Scores for %1").arg(courseInfo.name));
	scoreDialog->show();
}

void Kolf::save()
{
	if (filename.isNull())
	{
		saveAs();
		return;
	}

	if (game)
		game->save();

	game->setFocus();
}

void Kolf::saveAs()
{
	TQString newfilename = KFileDialog::getSaveFileName(":kourses", "application/x-kourse", this, i18n("Pick Kolf Course to Save To"));
	if (!newfilename.isNull())
	{
		filename = newfilename;
		game->setFilename(filename);
		game->save();
		game->setFocus();
	}
}

void Kolf::saveGameAs()
{
	TQString newfilename = KFileDialog::getSaveFileName(":savedkolf", "application/x-kolf", this, i18n("Pick Saved Game to Save To"));
	if (newfilename.isNull())
		return;

	loadedGame = newfilename;

	saveGame();
}

void Kolf::saveGame()
{
	if (loadedGame.isNull())
	{
		saveGameAs();
		return;
	}

	TDEConfig config(loadedGame);
	config.setGroup("0 Saved Game");

	config.writeEntry("Competition", competition);
	config.writeEntry("Course", filename);

	game->saveScores(&config);

	config.sync();
}

void Kolf::loadGame()
{
	loadedGame = KFileDialog::getOpenFileName(":savedkolf", TQString::fromLatin1("application/x-kolf"), this, i18n("Pick Kolf Saved Game"));

	if (loadedGame.isNull())
		return;

	isTutorial = false;
	startNewGame();
}

// called by main for commmand line files
void Kolf::openURL(KURL url)
{
	TQString target;
	if (TDEIO::NetAccess::download(url, target, this))
	{
		isTutorial = false;
		TQString mimeType = KMimeType::findByPath(target)->name();
		if (mimeType == "application/x-kourse")
			filename = target;
		else if (mimeType == "application/x-kolf")
			loadedGame = target;
		else
		{
			closeGame();
			return;
		}

		TQTimer::singleShot(10, this, TQ_SLOT(startNewGame()));
	}
	else
		closeGame();
}

void Kolf::newPlayersTurn(Player *player)
{
	tempStatusBarText = i18n("%1's turn").arg(player->name());

	if (showInfoAction->isChecked())
		statusBar()->message(tempStatusBarText, 5 * 1000);
	else
		statusBar()->message(tempStatusBarText);

	scoreboard->setCurrentCell(player->id() - 1, game->currentHole() - 1);
}

void Kolf::newStatusText(const TQString &text)
{
	if (text.isEmpty())
		statusBar()->message(tempStatusBarText);
	else
		statusBar()->message(text);
}

void Kolf::editingStarted()
{
	delete editor;
	editor = new Editor(obj, dummy, "Editor");
	connect(editor, TQ_SIGNAL(addNewItem(Object *)), game, TQ_SLOT(addNewObject(Object *)));
	connect(editor, TQ_SIGNAL(changed()), game, TQ_SLOT(setModified()));
	connect(editor, TQ_SIGNAL(addNewItem(Object *)), this, TQ_SLOT(setHoleFocus()));
	connect(game, TQ_SIGNAL(newSelectedItem(CanvasItem *)), editor, TQ_SLOT(setItem(CanvasItem *)));

	scoreboard->hide();

	layout->addWidget(editor, 1, 0);
	editor->show();

	clearHoleAction->setEnabled(true);
	newHoleAction->setEnabled(true);
	setHoleOtherEnabled(false);

	game->setFocus();
}

void Kolf::editingEnded()
{
	delete editor;
	editor = 0;

	if (scoreboard)
		scoreboard->show();

	clearHoleAction->setEnabled(false);
	newHoleAction->setEnabled(false);
	setHoleOtherEnabled(true);

	if (game)
		game->setFocus();
}

void Kolf::inPlayStart()
{
	setEditingEnabled(false);
	setHoleOtherEnabled(false);
	setHoleMovementEnabled(false);
}

void Kolf::inPlayEnd()
{
	setEditingEnabled(true);
	setHoleOtherEnabled(true);
	setHoleMovementEnabled(true);
}

void Kolf::maxStrokesReached(const TQString &name)
{
	KMessageBox::sorry(this, i18n("%1's score has reached the maximum for this hole.").arg(name));
}

void Kolf::updateHoleMenu(int largest)
{
	TQStringList items;
	for (int i = 1; i <= largest; ++i)
		items.append(TQString::number(i));

	// setItems for some reason enables the action
	bool shouldbe = holeAction->isEnabled();
	holeAction->setItems(items);
	holeAction->setEnabled(shouldbe);
}

void Kolf::setHoleMovementEnabled(bool yes)
{
	if (competition)
		yes = false;

	holeAction->setEnabled(yes);

	nextAction->setEnabled(yes);
	prevAction->setEnabled(yes);
	firstAction->setEnabled(yes);
	lastAction->setEnabled(yes);
	randAction->setEnabled(yes);
}

void Kolf::setHoleOtherEnabled(bool yes)
{
	if (competition)
		yes = false;

	resetHoleAction->setEnabled(yes);
	undoShotAction->setEnabled(yes);
	//replayShotAction->setEnabled(yes);
}

void Kolf::setEditingEnabled(bool yes)
{
	editingAction->setEnabled(competition? false : yes);
}

void Kolf::checkEditing()
{
	editingAction->setChecked(true);
}

void Kolf::print()
{
	KPrinter pr;
	pr.addDialogPage(new PrintDialogPage());

    if (pr.setup(this, i18n("Print %1 - Hole %2").arg(game->courseName()).arg(game->currentHole())))
	{
		pr.newPage();
		if (game)
			game->print(pr);
	}
}

void Kolf::updateModified(bool mod)
{
	courseModified = mod;
	titleChanged(title);
}

void Kolf::titleChanged(const TQString &newTitle)
{
	title = newTitle;
	setCaption(title, courseModified);
}

void Kolf::useMouseChanged(bool yes)
{
	TDEConfig *config = kapp->config(); config->setGroup("Settings"); config->writeEntry("useMouse", yes); config->sync();
}

void Kolf::useAdvancedPuttingChanged(bool yes)
{
	TDEConfig *config = kapp->config(); config->setGroup("Settings"); config->writeEntry("useAdvancedPutting", yes); config->sync();
}

void Kolf::showInfoChanged(bool yes)
{
	TDEConfig *config = kapp->config(); config->setGroup("Settings"); config->writeEntry("showInfo", yes); config->sync();
}

void Kolf::showGuideLineChanged(bool yes)
{
	TDEConfig *config = kapp->config(); config->setGroup("Settings"); config->writeEntry("showGuideLine", yes); config->sync();
}

void Kolf::soundChanged(bool yes)
{
	TDEConfig *config = kapp->config(); config->setGroup("Settings"); config->writeEntry("sound", yes); config->sync();
}

void Kolf::initPlugins()
{
	//kdDebug(12007) << "initPlugins" << endl;
	if (game)
		game->pause();

	obj->setAutoDelete(true);
	obj->clear();
	plugins.setAutoDelete(false);
	plugins.clear();

	// add prefab objects
	obj->append(new SlopeObj());
	obj->append(new PuddleObj());
	obj->append(new WallObj());
	obj->append(new CupObj());
	obj->append(new SandObj());
	obj->append(new WindmillObj());
	obj->append(new BlackHoleObj());
	obj->append(new FloaterObj());
	obj->append(new BridgeObj());
	obj->append(new SignObj());
	obj->append(new BumperObj());

	ObjectList *other = PluginLoader::loadAll();
	Object *object = 0;
	for (object = other->first(); object; object = other->next())
	{
		obj->append(object);
		plugins.append(object);
	}

	if (game)
	{
		game->setObjects(obj);
		game->unPause();
	}

	//kdDebug(12007) << "end of initPlugins" << endl;
}

void Kolf::showPlugins()
{
	TQString text = TQString("<h2>%1</h2><ol>").arg(i18n("Currently Loaded Plugins"));
	Object *object = 0;
	for (object = plugins.first(); object; object = plugins.next())
	{
		text.append("<li>");
		text.append(object->name());
		text.append(" - ");
		text.append(i18n("by %1").arg(object->author()));
		text.append("</li>");
	}
	text.append("</ol>");
	KMessageBox::information(this, text, i18n("Plugins"));
}

void Kolf::enableAllMessages()
{
	KMessageBox::enableAllMessages();
}

void Kolf::setCurrentHole(int hole)
{
	if (!holeAction)
		return;
	// Golf is 1-based, TDEListAction is 0-based
	holeAction->setCurrentItem(hole - 1);
}

#include "kolf.moc"
