/***************************************************************************
 *   Copyright (C) 2011-2014 by Tomasz Bojczuk                             *
 *   tomaszbojczuk@gmail.com                                               *
 *                                                                         *
 *   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 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *  You should have received a copy of the GNU General Public License      *
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
 ***************************************************************************/


#include "tstartexamdlg.h"
#include "texamparams.h"
#include "texam.h"
#include "tlevelselector.h"
#include "levelsettings.h"
#include <widgets/troundedlabel.h>
#include <thelpdialogbase.h>
#include <tpixmaker.h>
#include <tmainhelp.h>
#include <texamhelp.h>
#include <QtGui>
#include <stdlib.h> // for getenv()

QString TstartExamDlg::systemUserName() {
#if defined(Q_OS_WIN32)
        return QString::fromLocal8Bit(getenv("USERNAME"));
#else
        return QString::fromLocal8Bit(getenv("USER"));
#endif
}


QString statusTipText;
TstartExamDlg::TstartExamDlg(QString& nick, QString &path, TexamParams *examParams, QWidget *parent) :
    QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint),
    m_Acction(e_none),
    m_examParams(examParams),
    m_path(path),
    m_selectedExamFile("")
{
    setWindowTitle(tr("Start exercises or an exam"));

    QVBoxLayout *levLay = new QVBoxLayout;
    QHBoxLayout *nameLay = new QHBoxLayout;
    QLabel *nameLab = new QLabel(tr("student name:"), this);
    nameLay->addWidget(nameLab);
    m_nameEdit = new QLineEdit(nick, this);
    if (nick == "")
      m_nameEdit->setText(systemUserName());
    m_nameEdit->setMaxLength(30);
			m_nameEdit->setStatusTip(tr("Enter your name or nick-name."));
			nameLay->addWidget(m_nameEdit);
    levLay->addLayout(nameLay);
    m_levelsView = new TlevelSelector(this);
		m_levelsView->disableNotSuitable();
    levLay->addWidget(m_levelsView);
    QLabel *moreLab = new QLabel(levelSettings::moreLevelLinkTxt(), this);
			moreLab->setOpenExternalLinks(true);
			levLay->addWidget(moreLab, 0, Qt::AlignCenter);
		levelGr = new QGroupBox(this);
			levelGr->setStatusTip(tr("Select a level suitable for you<br>or create new one."));
			levelGr->setLayout(levLay);
			
		m_createLevelButt = new QPushButton(this);
			m_createLevelButt->setStatusTip(tr("Dialog window for creating new level<br>will be opened."));
			m_createLevelButt->setIcon(QIcon(path + "picts/levelCreator.png"));
			setIconSize(m_createLevelButt);
		QLabel *newLevelLab = new QLabel(tr("Create new level").replace(" ", "<br>"), this);
			newLevelLab->setAlignment(Qt::AlignCenter);
			newLevelLab->setStatusTip(m_createLevelButt->statusTip());

		m_exerciseButt = new QPushButton(tr("exercises"));
			m_exerciseButt->setIcon(QIcon(path + "picts/practice.png"));
			setIconSize(m_exerciseButt);
		
		m_examMenu = new QMenu("open exam file", this);
		m_newExamButt = new QPushButton(tr("pass new exam"), this);
			m_newExamButt->setIcon(QIcon(path + "picts/nootka-exam.png"));
			setIconSize(m_newExamButt);
		m_contExamButt = new QPushButton(tr("continue exam"), this);
			m_contExamButt->setIcon(QIcon(path + "picts/nootka-exam.png"));
			setIconSize(m_contExamButt);
			m_contExamButt->setStatusTip(tr("Click and select an exam to continue"));
			m_contExamButt->setMenu(m_examMenu);
		m_lastExamButt = new QPushButton(QIcon(path + "picts/nootka-exam.png"), "", this);
			setIconSize(m_lastExamButt);
			m_lastExamButt->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    
		m_helpButt = new QPushButton(this);
			m_helpButt->setIcon(QIcon(path + "picts/help.png"));
			m_helpButt->setStatusTip(tr("Help"));
			m_helpButt->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
			setIconSize(m_helpButt);
    m_cancelBut = new QPushButton(this);
			m_cancelBut->setIcon(QIcon(style()->standardIcon(QStyle::SP_DialogCloseButton)));
			m_cancelBut->setStatusTip(tr("Discard"));
			m_cancelBut->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
			setIconSize(m_cancelBut);

    m_hintLabel = new TroundedLabel(this);
    m_hintLabel->setFixedHeight(70);
    m_hintLabel->setWordWrap(true);
		
		
		QHBoxLayout *upperLay = new QHBoxLayout;
			upperLay->addWidget(levelGr);
			QVBoxLayout *helpLevelLay = new QVBoxLayout;
				helpLevelLay->addWidget(m_helpButt);
				helpLevelLay->addStretch(1);
				helpLevelLay->addWidget(m_createLevelButt);
				helpLevelLay->addWidget(newLevelLab);
				helpLevelLay->addStretch(1);
				helpLevelLay->addWidget(m_cancelBut);
			upperLay->addLayout(helpLevelLay);
		QVBoxLayout *mainLay = new QVBoxLayout;
			mainLay->addLayout(upperLay);
			QHBoxLayout *exerciseLay = new QHBoxLayout;
				exerciseLay->addSpacing(40);
				exerciseLay->addWidget(m_exerciseButt);
				exerciseLay->addSpacing(40);
			mainLay->addLayout(exerciseLay);
		QHBoxLayout *examLay = new QHBoxLayout;
			examLay->addWidget(m_newExamButt);
			examLay->addWidget(m_contExamButt);
			examLay->addWidget(m_lastExamButt);
		mainLay->addLayout(examLay);
		mainLay->addWidget(m_hintLabel);
			
    setLayout(mainLay);
    
		statusTipText = tr("To start exercising or to pass new exam put in your name and select a level. To continue the previous exam, select it from the list or load from file." );
    m_hintLabel->setStatusTip("<b>" + statusTipText + "</b>");

#if defined(Q_OS_WIN32) // I hate mess in Win registry
    QSettings sett(QSettings::IniFormat, QSettings::UserScope, "Nootka", "Nootka");
#else
    QSettings sett;
#endif
		QAction *loadExamAct = new QAction(loadExamFileTxt(), this);
			loadExamAct->setIcon(QIcon(path + "picts/nootka-exam.png"));
			connect(loadExamAct, SIGNAL(triggered(bool)), this, SLOT(examFromFileDialog()));
		m_examMenu->addAction(loadExamAct);
		m_examMenu->addSeparator();
		m_examMenu->addAction(tr("recent opened exams:"));
		
    m_recentExams = sett.value("recentExams").toStringList();
    for (int i = 0; i < m_recentExams.size(); i++) {
        QFileInfo fi(m_recentExams[i]);
        if (fi.exists()) {
						QAction *recentAct = m_examMenu->addAction(m_recentExams[i]);
						connect(recentAct, SIGNAL(triggered(bool)), this, SLOT(continuePrevExam()));
        }
        else
            m_recentExams.removeAt(i);
    }
    if (m_recentExams.size()) {
        sett.setValue("recentExams", m_recentExams);
    }
		
		updateButtonStatusText("");
		QString exerciseFile = QDir::toNativeSeparators(QFileInfo(sett.fileName()).absolutePath() + "/exercise.noo");
		m_prevExerciseLevel.name = ""; // empty means - no previous level
		if (QFileInfo(exerciseFile).exists()) {
				Texam exam(&m_prevExerciseLevel, "");
        Texam::EerrorType err = exam.loadFromFile(exerciseFile);
        if (err != Texam::e_file_OK && err != Texam::e_file_corrupted) {
						qDebug() << "exercise file was corrupted... and deleted...";
						QFile::remove(exerciseFile);
				}
		}
		if (TlevelSelector::checkLevel(m_prevExerciseLevel) != "")
				m_prevExerciseLevel.name = ""; // Returned string means that the level doesn't match to current settings
		if (m_prevExerciseLevel.name != "")
			 m_exerciseButt->setStatusTip(tr("Start exercise on level:") + "<br><b>" + m_prevExerciseLevel.name + "</b>");
		
		if (m_recentExams.size())
				m_lastExamButt->setStatusTip(tr("Continue the latest exam:") + "<br><b>" + m_recentExams.at(0) + "</b>");
		else
				m_lastExamButt->hide();
		
    connect(m_levelsView, SIGNAL(levelToLoad()), this, SLOT(levelToLoad()));
    connect(m_cancelBut, SIGNAL(clicked()), this, SLOT(reject()));
    connect(m_createLevelButt, SIGNAL(clicked()), this, SLOT(createLevel()));
    connect(m_newExamButt, SIGNAL(clicked()), this, SLOT(startAccepted()));
    connect(m_contExamButt, SIGNAL(clicked()), this, SLOT(startAccepted()));
		connect(m_lastExamButt, SIGNAL(clicked()), this, SLOT(continueTheLast()));
		connect(m_exerciseButt, SIGNAL(clicked()), this, SLOT(startAccepted()));
    connect(m_levelsView, SIGNAL(levelChanged(Tlevel)), this, SLOT(levelWasSelected(Tlevel)));
		connect(m_helpButt,  SIGNAL(clicked()), this, SLOT(helpSelected()));
		
		if (m_examParams->showVeryBeginHelp)
				QTimer::singleShot(10, this, SLOT(helpSelected()));
}


TstartExamDlg::Eactions TstartExamDlg::showDialog(QString &txt, Tlevel &lev) {
    exec();
    if (result() == QDialog::Accepted) {
        if (m_Acction == e_newExam || m_Acction == e_runExercise) {
            txt = m_nameEdit->text();
						if (m_prevExerciseLevel.name == "")
								lev = m_levelsView->getSelectedLevel();
						else
								lev = m_prevExerciseLevel;
            return m_Acction;
        } else if (m_Acction == e_contExam) {
            if (m_selectedExamFile != "") {
                txt = m_selectedExamFile;
                return e_contExam;
            } else
								return e_none;
					}
    } else if (m_Acction == e_levelCreator)
						return e_levelCreator;
		return e_none;
}


void TstartExamDlg::levelToLoad() {
    m_levelsView->loadFromFile();
}


bool TstartExamDlg::event(QEvent *event) {
    if (event->type() == QEvent::StatusTip) {
        QStatusTipEvent *se = static_cast<QStatusTipEvent *>(event);
        m_hintLabel->setText("<center>" + se->tip() + "</center>");
    }
    return QDialog::event(event);
}


void TstartExamDlg::continueTheLast() {
		if (m_recentExams.size()) {
				examToContSelected(m_recentExams[0]);
		}
}


bool TstartExamDlg::isAnyLevelSelected() {
	Tlevel l = m_levelsView->getSelectedLevel();
	if (l.name == "") { // nothing selected
			QMessageBox::warning(this, "Nootka", tr("No level was selected!"));
			return false;
	}
	return true;
}


void TstartExamDlg::startAccepted() {
    if (sender() == m_newExamButt) { // new exam on selected level
        if (!isAnyLevelSelected())
            return;
				if (m_nameEdit->text() == "") {
						QMessageBox::warning(this, "", tr("Give a user name!"));
						return;
				}
				m_Acction = e_newExam;
				accept();
    } else if (sender() == m_exerciseButt) { // exercise on selected level or previous one
				if (m_prevExerciseLevel.name == "" && !isAnyLevelSelected())
					return;
				if (m_nameEdit->text() == "") {
						QMessageBox::warning(this, "", tr("Give a user name!"));
						return;
				}
				m_Acction = e_runExercise;
				accept();
    } else { // exam to continue
				if (m_selectedExamFile != "")    {
					m_Acction = e_contExam;
					accept();
			}
    }
}


TstartExamDlg::Eactions TstartExamDlg::createLevel() {
    m_Acction = e_levelCreator;
    close();
    return e_levelCreator;
}


void TstartExamDlg::continuePrevExam() {
	QAction *action = qobject_cast<QAction *>(sender());
	if (action)
			examToContSelected(action->text());
}


void TstartExamDlg::examFromFileDialog() {
    QString fileName = QFileDialog::getOpenFileName(this, loadExamFileTxt(),
                               m_examParams->examsDir, examFilterTxt(), 0, QFileDialog::DontUseNativeDialog);
    if (fileName != "") {
				examToContSelected(fileName);
    }
}


void TstartExamDlg::examToContSelected(QString eFile) {
		if (eFile != "") {
				m_examParams->examsDir = QFileInfo(eFile).absoluteDir().absolutePath();
        m_recentExams.prepend(eFile);
				m_selectedExamFile = eFile;
				m_Acction = e_contExam;
        accept();
		}
}


void TstartExamDlg::updateButtonStatusText(const QString& levelName) {
	QString statusText;
	if (levelName == "") {
			statusText += tr("No level was selected!");
	}	else {
			statusText += levelName;
	}
	statusText.prepend("<br><b>");
	statusText.append("</b>");
	m_newExamButt->setStatusTip(tr("Pass new exam on level:") + statusText);
	m_exerciseButt->setStatusTip(tr("Start exercise on level:") + statusText);
}


void TstartExamDlg::levelWasSelected(Tlevel level) {
	m_prevExerciseLevel.name = ""; // Reset the name - now level is taken from selection 
	updateButtonStatusText(level.name);		
}


void TstartExamDlg::helpSelected() {
		ThelpDialogBase *help = new ThelpDialogBase(this);
		help->setFixedSize(width(), height() * 0.8);
		QString ht = "<center><h2>" + help->pix("practice", 64) + " " + tr("To exercise or to pass an exam?") + " " + 
		help->pix("nootka-exam", 64) + "</h2>" +
		TmainHelp::youWillLearnText() + "<br><br>" +
		"</center><table><tr><td style=\"padding: 10px;\" align=\"center\">" + 
		TmainHelp::duringExercisingText(m_path) + "<br>" + TexamHelp::exerciseFeaturesText() +
		"</td></tr><tr><td style=\"padding: 10px;\" align=\"center\">" + 
		TmainHelp::duringExamsText(m_path) + "<br>" + TexamHelp::examFeaturesText() + "</td></tr></table>";
		
		help->helpText()->setHtml(ht);
		help->showCheckBox(&m_examParams->showVeryBeginHelp);
// 		qDebug() << help->helpText()->toHtml();
		help->exec();
		delete help;
}


void TstartExamDlg::setIconSize(QPushButton* button) {
	button->setIconSize(QSize(48, 48));
}








