/***************************************************************************
                          mainwindow.cpp  -  description
                             -------------------
    begin                : Sun Oct 21 2001
    copyright            : (C) 2001 by Primoz Anzur (zer0Kode)
    email                : zerokode@gmx.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "mainwindow.h"
#include "mainwindow.moc"
#include <kdebug.h>

#include "answer.h"
#include <pwd.h>
#include <time.h>

MainWindow::MainWindow(QWidget *parent, const char *name) : FrontEnd(parent, name)
{
	guesses=0L;
	tGuesses=0L;
	messups=0L;
	solvedWords=0L;

	//cfg = new Config();
	newCfg = new KmwConfigurator();
	connect(newCfg,SIGNAL(sig_reload()), this, SLOT(winRefresh()) );
	connect(&showConfig, SIGNAL(getClose()), this, SLOT(slot_messup()) );

	//config
	config = kapp->config();

	//popup menu
	mainMenu = new KPopupMenu(this);
	loadPopupMenu();
	btnConfig->setPopup(mainMenu);

	//Help Menu
	helpMenu = new KHelpMenu(this, KGlobal::instance()->aboutData(), true);
	btnHelp->setPopup(helpMenu->menu());

	setIcon(QPixmap(locate("icon","locolor/16x16/apps/kmessedwords.png")));
	kMessedDataDir=locate("data","kmessedwords/");

	setLocalDictionary=locateLocal("data","kmesswords/");
	QFile f(setLocalDictionary+"easy.txt");
	if (! f.exists())
	{
		setLocalDictionary=locate("data","kmessedwords/");
	}

	setCaption(i18n ("KMessedWords %1").arg(LOCAL_VERSION));
	guesses = 0;
	btnMess->setFocus();	//focus on "Messup" button

	first_run(); //makes the config file and all...
	check_update();


	winRefresh();

	mainScreen->setAutoMask(true);

	silly=new MinParser ();
}

MainWindow::~MainWindow(){
    delete silly;
}

void MainWindow::slot_close()
{
	close();
}

void MainWindow::randomizer(int level)
{
	reloadStructure();
	if(level==0)
	{
		lines=configInputData.easyDict->numLines();
		cleanWord=configInputData.easyDict->textLine( random.getLong(lines) ).stripWhiteSpace();
	}
	if(level==1)
	{
		lines=configInputData.mediumDict->numLines();
		cleanWord=configInputData.mediumDict->textLine( random.getLong(lines) ).stripWhiteSpace();
	}
	if(level==2)
	{
		lines=configInputData.hardDict->numLines();
		cleanWord=configInputData.hardDict->textLine( random.getLong(lines) ).stripWhiteSpace();
	}
}

void MainWindow::confuse_words()
{
	QPtrList <QChar> messList;
	messList.setAutoDelete(true);

	// Put all letters of the word in the list
	for(unsigned int i = 0; i < cleanWord.length(); i++)
	{
		messList.append(new QChar( cleanWord[i] ));
	}

	// Shuffle the list
	random.randomize(&messList);

	// Give the messed up string the right length.
	messedWord.fill(' ', cleanWord.length());

	// Copy all letters to the messed u-p string.
	for(unsigned int i = 0; i < cleanWord.length(); i++)
	{
		messedWord[i] = *(messList.at(i));
	}
}


void MainWindow::slot_messup()
{
	if (!newCfg->globalSillyFile.isEmpty() && newCfg->chkSilly->isChecked()) //the same... Why enabled, if no file??
	{
		sillyMess();
	}
	else
	{
		// enable Buttons on first button click
		if (!guessedText->isEnabled())
		{
			guessedText->setEnabled(true);
			txtGuess->setEnabled(true);
			btnTry->setEnabled(true);
			btnMess->setDefault(false);
		}
		randomizer(leveler->currentItem());
		confuse_words();

	//prevents clean words to be displayed...
		if (cleanWord.stripWhiteSpace()==messedWord.stripWhiteSpace())
		{
			slot_messup();
		//messups ++;  //this is for nothing more than monitoring the completenumbers of messed and clean words...
		}
		else
		{
			messups++;
			mainScreen->setText(messedWord.stripWhiteSpace());
			guessedText->setFocus();
		}
	}
}

void MainWindow::slot_try()
{
	if (!newCfg->globalSillyFile.isEmpty() && newCfg->chkSilly->isChecked()) //the same... Why enabled, if no file??
	{
		if(!guessedText->text().isEmpty())
		{
			if (guessedText->text()==c_word)
			{
				config->setGroup("Environment");
				bool gfxStyle=config->readBoolEntry("UseGfxStyle",true);
				kdDebug() << gfxStyle << endl;
				if (gfxStyle)
				{
					Answer *answer = new Answer();
					emit answer->doAnswer(true);
					connect(answer, SIGNAL(gameExit()), this, SLOT(theEnd()) );
					connect(answer, SIGNAL(gameReplay()), this, SLOT(theReply()) );
					answer->show();
				}
				else
				{
					if (KMessageBox::questionYesNo(this,i18n("Congratulations! You got the right answer!\n\nPlay again?"), "KMessedWords", i18n("Play again"), KStdGuiItem::quit()) ==4)
					{
						close();
					}
					else
					{
						guessedText->setText("");
						sillyMess();
					}
				}
			}
			else
			{
				config->setGroup("Environment");
				bool gfxStyle=config->readBoolEntry("UseGfxStyle",true);

				if (gfxStyle)
				{
					Answer *answer = new Answer();
					emit answer->doAnswer(false);
					answer->show();

					guessedText->setText("");
				}
				else
				{
					KMessageBox::information(this,i18n("Sorry... Try again...") );
					guessedText->setText("");
				}
			}
		}
	}
	else
	{
		if(!guessedText->text().isEmpty())
		{
			guesses++;
			tGuesses++;
			//kdDebug() << "try " << guessedText->text()  << endl;
			//kdDebug() << "answare " << cleanWord << endl;  No cheating!!!

			config->setGroup("Environment");
			bool gfxStyle=config->readBoolEntry("UseGfxStyle",true);

			if (gfxStyle)
			{
				if(QString::compare(guessedText->text().stripWhiteSpace(),cleanWord.stripWhiteSpace())==0) //when you are right in graphic environment...
				{
					Answer *answer = new Answer();
					emit answer->doAnswer(true);
					connect(answer, SIGNAL(gameExit()), this, SLOT(theEnd()) );
					connect(answer, SIGNAL(gameReplay()), this, SLOT(theReply()) );
					answer->show();

				}
				else
				{
					Answer *answer = new Answer();
					emit answer->doAnswer(false);
					answer->show();

					guessedText->setText("");
				}
			}
			else
			{
				if(QString::compare(guessedText->text().stripWhiteSpace(),cleanWord.stripWhiteSpace())==0)
				{
					kdDebug() << "correct" << endl;
					if (KMessageBox::questionYesNo(this,i18n("Congratulations! You got the right answer after %1 attempts.\n\nPlay again?").arg(guesses), "KMessedWords", i18n("Play again"), KStdGuiItem::quit()) ==4)
					{
						//scoring final calc thingy goes here :)
						config->setGroup("Environment");
						shareLoginName=config->readEntry("GamerName", "");

						solvedWords++;
						write_scores();
						QString justtext=i18n("Name: %1\n").arg(shareLoginName) + i18n("Solved: %1\n").arg(solvedWords)+ i18n ("Rounds: %1\n").arg(messups);
						KMessageBox::information(this,justtext);
						close();
					}
					else
					{ //here goes on...
						//scoring calc thingy goes here :)
						solvedWords++;
						guesses=0;
						guessedText->setText("");
						slot_messup();
					}
				}
				else
				{ //if you are wrong...
					kdDebug() << "wrong" << endl;
					KMessageBox::information(this,i18n("You missed! Try again..."), "KMessedWords"); //this should be replaced by a graphical box [?]
					guessedText->setText("");
				}
			} //end dialog

		}//end graphic style...
	}
}

void MainWindow::slot_textAccel()
{
	if(!guessedText->text().isEmpty())
	{
		slot_try();
	}
}

void MainWindow::slot_openBook()
{
	showConfig.show();
}

void MainWindow::reloadStructure(){
	//this too is a-must-have for the paths and fie checkings and stuff...
	setLocalDictionary=locateLocal("data","kmesswords/"); //<-this NEEDS to be there due to the info, that is in the Locate path [graphics and files]
	QFile f(setLocalDictionary+"easy.txt");
	if (! f.exists())
	{
		setLocalDictionary=locate("data","kmessedwords/");
	}

	//this is just a patch.. It reloads the files into the dictionary buffer...
	QFile openEasyFile(setLocalDictionary+"easy.txt");
	openEasyFile.open(IO_ReadOnly);
	QTextStream readEasyStr(&openEasyFile);
	configInputData.easyDict->setText(readEasyStr.read().stripWhiteSpace());
	openEasyFile.close();

	QFile openMediumFile(setLocalDictionary+"medium.txt");
	openMediumFile.open(IO_ReadOnly);
	QTextStream readMediumStr(&openMediumFile);
	configInputData.mediumDict->setText(readMediumStr.read().stripWhiteSpace());
	openMediumFile.close();

	QFile openHardFile(setLocalDictionary+"hard.txt");
	openHardFile.open(IO_ReadOnly);
	QTextStream readHardStr(&openHardFile);
	configInputData.hardDict->setText(readHardStr.read().stripWhiteSpace());
	openHardFile.close();
}

void MainWindow::slot_scores()
{
	showScores.show(); //much better solution... It shows only one instance of the window...
}

void MainWindow::read_scores() //actually... This is not even needed (me thinks)...
{
	for (int i=0; i<=9; i++)
	{
		HighScores showScores;
		config->setGroup("Easy_scores");
		readName[i]=config->readEntry(QString("name%1").arg(i),"Anonymous");
		readSolved[i]=config->readNumEntry(QString("solved%1").arg(i),0);
		readRounds[i]=config->readNumEntry(QString("rounds%1").arg(i),0);
		readGuesses[i]=config->readNumEntry(QString("guesses%1").arg(i),0);
	}
}

void MainWindow::write_scores()
{
	config->setGroup("Environment");
	shareLoginName=config->readEntry("GamerName", "");

	//this is for the levels...
	if (leveler->currentItem()==0)
		config->setGroup("Easy_scores");
	else if (leveler->currentItem()==1)
		config->setGroup("Medium_scores");
	else
		config->setGroup("Hard_scores");

        int rank = 10;
        int j = 0;
	for (int i=0; j<=9; i++,j++) //we load everything in cache
	{
		readName[j]=config->readEntry(QString("name%1").arg(i),"Anonymous");
		readSolved[j]=config->readNumEntry(QString("solved%1").arg(i),0);
		readRounds[j]=config->readNumEntry(QString("rounds%1").arg(i),0);
		readGuesses[j]=config->readNumEntry(QString("guesses%1").arg(i),0);
		if ((rank > i) && (readSolved[i] < solvedWords))
		{
			// Insert new score here.
			rank = i;
			j++;
			if (j <= 9)
			{
				readName[j] = readName[i];
				readSolved[j] = readSolved[i];
				readRounds[j] = readRounds[i];
				readGuesses[j] = readGuesses[i];
			}
			readName[i] = shareLoginName;
			readSolved[i] = solvedWords;
			readRounds[i] = messups;
			readGuesses[i] = tGuesses;
		}
	}

qWarning("Rank = %d", rank);
	if (rank > 9)
		return;

	for (int x=0;  x<=9; x++) // write back all scores
	{
		config->writeEntry(QString("name%1").arg(x), readName[x]);
		config->writeEntry(QString("solved%1").arg(x),readSolved[x]);
		config->writeEntry(QString("rounds%1").arg(x),readRounds[x]);
		config->writeEntry(QString("guesses%1").arg(x),readGuesses[x]);
	}
	config->sync();
}

void MainWindow::first_run()
{
	config->setGroup("First_run");
	if (config->readBoolEntry("Run",true)==true)
	{
		//KMessageBox::information(this,i18n("The player name has been set to that of the user account. The player name can be changed in Configure, Configuration."));
		config->writeEntry("Run","false");
	}

	struct passwd* pw;

	config->setGroup("Environment");
	shareLoginName=config->readEntry("GamerName","");

	if (shareLoginName.isEmpty())
	{
		pw = getpwuid(getuid());
		if (pw)
		{
			shareLoginName = pw->pw_gecos;
			int i = shareLoginName.find(',');
			if (i>0)
				shareLoginName.truncate(i);
		}
		config->setGroup("Environment");
		config->writeEntry("GamerName",shareLoginName);
	}
	else
	{
		kdDebug() << "Name set to user, that has been read from configuration file..." << endl;
	}
	kdDebug() << "Name found: " << shareLoginName << endl;
	config->sync();
}

void MainWindow::slot_changeLevel()
{
	//a complete reset for other levels... [docs?]
	KMessageBox::information(this,i18n("Now playing another level"));
	messups=0;
	solvedWords=0;
	guesses=0;
	tGuesses=0;
	guessedText->setText("");

	//we have to lock it up for the other level...
	guessedText->setEnabled(false);
	txtGuess->setEnabled(false);
	btnTry->setEnabled(false);
	btnMess->setDefault(true);
}

void MainWindow::check_update()
{
	config->setGroup("Version");
	if (config->readEntry("version","") !="1.0.0")
	{
		for (int i=0; i<=9; i++)
		{
			config->setGroup("Easy_scores");
			config->writeEntry(QString("guesses%1").arg(i),"0");

			config->setGroup("Medium_scores");
			config->writeEntry(QString("guesses%1").arg(i),"0");

			config->setGroup("Hard_scores");
			config->writeEntry(QString("guesses%1").arg(i),"0");
		}
		config->setGroup("Version");
		config->writeEntry("version","1.0.0");
		config->sync();
	}
}

void MainWindow::loadPopupMenu()
{
	mainMenu->insertItem(QPixmap(locate("data","kmessedwords/wrench_small.png")),i18n("&Configuration..."), this, SLOT(showAppConfig()));
	mainMenu->insertItem(QPixmap(locate("data","kmessedwords/dict.png")),i18n("&Dictionary..."), this, SLOT(slot_openBook()));
}

void MainWindow::showAppConfig()
{
 newCfg->show();
//	cfg->show();
}

void MainWindow::closeEvent(QCloseEvent *)
{
	exit(0);
}

void MainWindow::winRefresh()
{
	QPixmap bgPix;
	//leveler->setEnabled(!cfg->chkSilly->isChecked());
	if (!newCfg->globalSillyFile.isEmpty() && newCfg->chkSilly->isChecked()) //there is no use enabling silly things, if there is no file...
	{
		leveler->setEnabled(false);
		//reset...

			//a complete reset for other levels... [docs?]
		//KMessageBox::information(this,i18n("Now playing with syllables..."));
		messups=0;
		solvedWords=0;
		guesses=0;
		tGuesses=0;
		guessedText->setText("");

		//we have to lock it up for the other level...
		guessedText->setEnabled(false);
		txtGuess->setEnabled(false);
		btnTry->setEnabled(false);
		btnMess->setDefault(true);
		//Scorings are reseted now... We won't keep scores for syllables...
	}
	else
	{
		leveler->setEnabled(true);
	}
	config->setGroup("Theme");
	themeName=config->readEntry("Name","default");
	if(config->readBoolEntry("Background",true))
	{
		bgPix=QPixmap(locate("data","kmessedwords/themes/"+themeName+"/kmessedbg.png"));
		setBackgroundPixmap(bgPix);
		mainScreen->setBackgroundOrigin( QLabel::ParentOrigin );
		mainScreen->setBackgroundPixmap(bgPix);
	} else {
		setBackgroundColor("#DCDCDC");
		mainScreen->setBackgroundColor("#DCDCDC");
	}

	config->setGroup("Theme");
	isThemeBtn=config->readBoolEntry("Buttons",false);

	if(isThemeBtn)
	{
		btnClose->setPixmap(QPixmap(locate("data","kmessedwords/themes/"+themeName+"/btnbye.png")));
		btnHelp->setPixmap(QPixmap(locate("data","kmessedwords/themes/"+themeName+"/btnhelp.png")));
		btnConfig->setPixmap(QPixmap(locate("data","kmessedwords/themes/"+themeName+"/btnconf.png")));
		btnScore->setPixmap(QPixmap(locate("data","kmessedwords/themes/"+themeName+"/btnscore.png")));
		btnMess->setPixmap(QPixmap(locate("data","kmessedwords/themes/"+themeName+"/btnmess.png")));
		btnTry->setPixmap(QPixmap(locate("data","kmessedwords/themes/"+themeName+"/btntry.png")));
	} else 	{
		btnClose->setText(KStdGuiItem::quit().text());
		btnHelp->setText(KStdGuiItem::help().text());
		btnConfig->setText(i18n("Co&nfigure"));
		btnScore->setText(i18n("&Scores"));
		btnMess->setText(i18n("&Randomize"));
		btnTry->setText(i18n("&Try"));
	}
}

void MainWindow::theEnd()
{
	config->setGroup("Environment");
	shareLoginName=config->readEntry("GamerName", "");

	solvedWords++;
	write_scores();
	QString justtext=i18n("Name: %1\n").arg(shareLoginName) + i18n("Solved: %1\n").arg(solvedWords)
		+ i18n ("Rounds: %1\n").arg(messups);
	KMessageBox::information(this,justtext);
	close();
}

void MainWindow::theReply()
{
	solvedWords++;
	guesses=0;
	guessedText->setText("");
	slot_messup();
}

void MainWindow::sillyMess()
{
	silly->loadFile(newCfg->globalSillyFile); //now the file is set....

	int row=randomRow.getLong(silly->rows()); //oh, yeah :) Much simpler :)

	c_word = silly->getClean(row,"-");
	d_word= silly->makeMess(row,"-");
	mainScreen->setText(d_word);

	guessedText->setEnabled(true);
	txtGuess->setEnabled(true);
	btnTry->setEnabled(true);
	btnMess->setDefault(false);
	guessedText->setFocus();
}
