/***************************************************************************
                             exercisecompare.cpp
                             -------------------
    begin                : 2004/06/03
    copyright            : (C) 2004 by Sebastian Stein
    email                : seb.kde@hpfsc.de

    copyright            : (C) 2008 by Tadeu Araujo, tadeu.araujo@ltia.fc.unesp.br
    copyright            : (C) 2008 by Danilo Balzaque, danilo.balzaque@ltia.fc.unesp.br
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 "exercisecompare.h"
#include "exercisecompare.moc"

/* these includes are needed for KDE support */
#include <klocale.h>

/* these includes are needed for Qt support */
#include <qapplication.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qpushbutton.h>

//Added by qt3to4:
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>

/* standard C++ library includes */
#include <stdlib.h>

#include "settingsclass.h"

/* ----- public member functions ----- */

/* constructor */
ExerciseCompare::ExerciseCompare(QWidget * parent):
		ExerciseBase(parent)
{
#ifdef DEBUG
	kDebug() << "constructor ExerciseCompare()";
#endif

	QApplication::setOverrideCursor(Qt::WaitCursor); /* show the sand clock */
	createTask();
	QApplication::restoreOverrideCursor(); /* show the normal cursor */

	m_currentState = _CHECK_TASK;

	QFont defaultFont = SettingsClass::taskFont();
	defaultFont.setBold( true );
	defaultFont.setPointSize(12);

	// Create layout
	taskWidget = new QWidget(this);
	taskWidget->setObjectName("taskWidget");
	checkWidget = new QWidget(this);
	checkWidget->setObjectName("checkWidget");
	
	baseGrid = new QGridLayout(this);
	baseGrid->setObjectName( "baseGrid" );
	baseGrid->setColumnStretch(0,1);

	baseGrid->addWidget(taskWidget, 0, 0);
	baseGrid->addWidget(checkWidget, 0, 1);
	
	taskLayout = new QGridLayout(this);
	taskLayout->setObjectName( "taskLayout" );
	taskLayout->setRowStretch(0,1);
	taskLayout->setRowStretch(4,1);
	taskLayout->setColumnStretch(0,1);
	taskLayout->setColumnStretch(4,1);

	checkLayout = new QGridLayout(this);
	checkLayout->setObjectName( "checkLayout" );
	
	// first the first ratio widget
	m_firstRatioWidget = new RatioWidget(taskWidget, m_firstRatio);
	m_firstRatioWidget->setObjectName("m_firstRatioWidget");
	taskLayout->addWidget(m_firstRatioWidget, 1, 1, 3, 1);

	// now the second ratio widget
	m_secondRatioWidget = new RatioWidget(taskWidget, m_secondRatio);
	m_secondRatioWidget->setObjectName("m_secondRatioWidget");	
	taskLayout->addWidget(m_secondRatioWidget, 1, 3, 3, 1);

	// Create compare buttons
	m_moreButton = new QPushButton(taskWidget);
	m_moreButton->setObjectName("m_moreButton");
	m_moreButton->setText(i18n(">"));
	m_moreButton->setFixedSize(74,30);
	m_moreButton->setFont(defaultFont);	
	QObject::connect(m_moreButton, SIGNAL(clicked()), this, SLOT(slotMoreButtonClicked()));
	m_moreButton->setToolTip(i18n("Click on this button to select the more sign."));
	taskLayout->addWidget(m_moreButton, 1, 2);
	
	m_minorButton = new QPushButton(taskWidget);
	m_minorButton->setObjectName("m_minorButton");
	m_minorButton->setText(i18n("<"));
	m_minorButton->setFixedSize(74,30);	
	m_minorButton->setFont(defaultFont);		
	QObject::connect(m_minorButton, SIGNAL(clicked()), this, SLOT(slotMinorButtonClicked()));
	m_minorButton->setToolTip(i18n("Click on this button to select the minor sign."));
	taskLayout->addWidget(m_minorButton, 2, 2);
	
	m_equalButton = new QPushButton(taskWidget);
	m_equalButton->setObjectName("m_equalButton");
	m_equalButton->setText(i18n("="));
	m_equalButton->setFixedSize(74,30);
	m_equalButton->setFont(defaultFont);			
	QObject::connect(m_equalButton, SIGNAL(clicked()), this, SLOT(slotEqualButtonClicked()));
	m_equalButton->setToolTip(i18n("Click on this button to select the equal sign."));
	taskLayout->addWidget(m_equalButton, 3, 2);

	// Create Skip and Check buttons
	m_resultWidget = new ResultWidget(checkWidget);
	m_resultWidget->setObjectName("m_resultWidget");
	checkLayout->addWidget(m_resultWidget, 0, 0);

	defaultFont.setPointSize(10);

	m_skipButton = new QPushButton( checkWidget );
	m_skipButton->setObjectName( "m_skipButton" );
	m_skipButton->setText(i18n("&Skip"));
	m_skipButton->setToolTip(i18n("Click on this button to skip this question."));
	m_skipButton->setFont(defaultFont);		
	QObject::connect(m_skipButton, SIGNAL(clicked()), this, SLOT(slotSkipButtonClicked()));
	checkLayout->addWidget(m_skipButton, 1, 0);	
	
	m_equalButton->setFocusPolicy( Qt::NoFocus );
	m_moreButton->setFocusPolicy( Qt::NoFocus );
	m_minorButton->setFocusPolicy( Qt::NoFocus );
	m_skipButton->setFocusPolicy( Qt::NoFocus );

	setLayout(baseGrid);
	taskWidget->setLayout(taskLayout);
  	checkWidget->setLayout(checkLayout);

	// add tooltip and qwhatsthis help to the widget
	setToolTip(i18n("In this exercise you have to compare 2 given fractions."));
	setWhatsThis( i18n("In this exercise you have to compare 2 given fractions by choosing the correct comparison sign. You can change the comparison sign by just clicking on the button showing the sign."));

	// that the user can start typing without moving the focus
	m_equalButton->setFocus();
}

/* destructor */
ExerciseCompare::~ExerciseCompare()
{
#ifdef DEBUG
	kDebug() << "destructor ExerciseCompare()";
#endif

	/* no need to delete any child widgets, Qt does it by itself */
}

/** resets the current state, creates a new task and count the last task as
 * wrong, if it wasn't solved (in _NEXT_TASK state) yet
 * mainly used after changing the task parameters */
void ExerciseCompare::forceNewTask()
{
#ifdef DEBUG
	kDebug() << "forceNewTask ExerciseCompare()";
#endif

	if (m_currentState == _CHECK_TASK)
	{
		// emit the signal for skipped
		signalExerciseSkipped();
	}
	m_currentState = _CHECK_TASK;

	// generate next task
	(void) nextTask();
}

void ExerciseCompare::setQuestionMixed(bool value)
{
	m_firstRatioWidget->setQuestionMixed(value);
	m_secondRatioWidget->setQuestionMixed(value);
}

/* ------ public slots ------ */

void ExerciseCompare::update()
{
	// call update of components
	m_firstRatioWidget->updateAndRepaint();
	m_secondRatioWidget->updateAndRepaint();

	// update for itself
	((QWidget *) this)->update();
}


/* ------ private member functions ------ */

void ExerciseCompare::createTask()
{
	// generate the first ratio
	m_firstRatio = ratio(int((double(rand()) / RAND_MAX) * 10 + 1), int((double(rand()) / RAND_MAX) * 10 + 1));

	// now the second ratio, but make sure, the second ratio is different from
	// the first one
	do
	{
		m_secondRatio = ratio(int((double(rand()) / RAND_MAX) * 10 + 1), int((double(rand()) / RAND_MAX) * 10 + 1));
	} while (m_firstRatio == m_secondRatio);

	return;
}

/**	- checks, if the user solved the task correctly
		- emits signals if task was solved correctly or wrong */
void ExerciseCompare::showResult()
{
	QPalette pal;
	SignButtonState result;
	
	if ( m_firstRatio < m_secondRatio )
		result = lessThen;
	else if ( m_firstRatio > m_secondRatio )
		result = greaterThen;	
	else
		result = equalTo;		


	// disable sign button
	m_minorButton->setEnabled(false);
	m_moreButton->setEnabled(false);
	m_equalButton->setEnabled(false);
	
	if ( m_signButtonState == result )
	{
		// emit the signal for correct
		signalExerciseSolvedCorrect();

		/* yes, the user entered the correct result */
		m_resultWidget->setResult(1);
	} else {
		// emit the signal for wrong
		signalExerciseSolvedWrong();

		/* no, the user entered the wrong result */
		
		m_resultWidget->setResult(2);
	} /* if (entered_result == result) */

	return;
}

/** generate the next task and show it to the user */
void ExerciseCompare::nextTask()
{
	// change the tooltip of the check button
	m_equalButton->setToolTip(i18n("Click on this button to check your result."));
	m_moreButton->setToolTip(i18n("Click on this button to check your result."));
	m_minorButton->setToolTip(i18n("Click on this button to check your result."));
	// enable sign button
	m_equalButton->setEnabled(true);
	m_minorButton->setEnabled(true);
	m_moreButton->setEnabled(true);
	
	// reset the signButton
	m_signButtonState = lessThen;

	/* create a new task */
	QApplication::setOverrideCursor(Qt::WaitCursor); /* show the sand clock */
	createTask();
	QApplication::restoreOverrideCursor(); /* show the normal cursor */

	// set the ratio widgets with the new ratios
	m_firstRatioWidget->setRatio(m_firstRatio);
	m_secondRatioWidget->setRatio(m_secondRatio);

	return;
}

/* ------ private slots ------ */

void ExerciseCompare::slotSkipButtonClicked()
{
#ifdef DEBUG
	kDebug() << "ExerciseCompare::slotSkipButtonClicked()";
#endif
	if (m_currentState == _CHECK_TASK)
	{
		forceNewTask();		
	} else {
		m_currentState = _CHECK_TASK;
		m_skipButton->setText(i18n("&Skip"));		
		m_resultWidget->setResult( m_firstRatio, -1);		
		nextTask();
	}

	return;
}

void ExerciseCompare::slotMinorButtonClicked()
{
#ifdef DEBUG
	kDebug() << "ExerciseCompare::slotMinorButtonClicked()";
#endif
	
	m_currentState = _NEXT_TASK;
	m_skipButton->setText(i18n("&Next"));	
	m_signButtonState = lessThen;
	showResult();

	return;
}

void ExerciseCompare::slotMoreButtonClicked()
{
#ifdef DEBUG
	kDebug() << "ExerciseCompare::slotMoreButtonClicked()";
#endif

	m_currentState = _NEXT_TASK;
	m_skipButton->setText(i18n("&Next"));		
	m_signButtonState = greaterThen;
	showResult();

	return;
}

void ExerciseCompare::slotEqualButtonClicked()
{
#ifdef DEBUG
	kDebug() << "ExerciseCompare::slotEqualButtonClicked()";
#endif

	m_currentState = _NEXT_TASK;
	m_skipButton->setText(i18n("&Next"));	
	m_signButtonState = equalTo;
	showResult();

	return;
}
