/***************************************************************************
 *   Copyright (C) 2007 by Muylkens Toon   *
 *   toon.muylkens@student.kuleuven.be   *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "OneExercise.h"
//  #include <stdio.h>
//  #include <iostream>
//  using namespace std;

OneExercise::OneExercise(QWidget *parent, int index, QList<QString> muscleList, QStringList taglist)
     : QWidget(parent)
 {
	newExerciseMode = false;
     	ui.setupUi(this);
	ui.listWidget->setSelectionMode(QAbstractItemView::SingleSelection);
	QObject::connect(ui.saveButton,SIGNAL(pressed()),this,SLOT(save()));
	QObject::connect(ui.deleteButton,SIGNAL(pressed()),this,SLOT(deleteExercise()));
	QObject::connect(ui.uploadButton,SIGNAL(pressed()),this,SLOT(uploadExercise()));
	QObject::connect(ui.addTagButton,SIGNAL(pressed()),this,SLOT(addTag()));

/**TO SLOW => save manually
// 	QObject::connect(ui.textEditExplaination,SIGNAL(textChanged()),this,SLOT(save()));
// 	QObject::connect(ui.lineEditName1,SIGNAL(textChanged(QString)),this,SLOT(currentNameChanged(QString)));
*/
	this->index=index;
	this->muscleList = muscleList;
	this->tagList = taglist;
	fillComboBox();
}

/**
*after calling this method the exercise is saved automaticly when adding muscles,
*removing muscles, adding tags
*\note when we are in newExerciseMode this method has no effect.
*\note changing the title and the explanation arn't auto-saved
*/
void OneExercise::setAutoSaveFunctionOn(){
///note: we don't set these connections in constructor because at that time the title, .. isn't set yet, and the autosaver will complain about bad string.
QObject::connect(ui.removeMuscleButton,SIGNAL(pressed()),this,SLOT(removeMuscleButtonPressed()));
QObject::connect(ui.addMuscleButton,SIGNAL(pressed()),this,SLOT(addMuscleButtonPressed()));
QObject::connect(ui.comboBox_tag,SIGNAL(currentIndexChanged(int)),this,SLOT(currentTagChanged(int)));
}

/**
*other tag was selected. We save the Qprofile when we are not in newExercise Mode
*/
void OneExercise::currentTagChanged(int newindex){
if(!newExerciseMode){
	save();
	}
}


/**
*other Name was chosen => save when we are not in newExercise Mode
*/
void OneExercise::currentNameChanged(QString newName){
if(!newExerciseMode){
	save();
	}
}

/**
*This method adds an exercsisetag to the QProfile and sets that tag as 'tag' for this exercise
*/
void OneExercise::addTag(){
bool ok;
QString text = QInputDialog::getText(this, tr("Make a new Tag"),
                                          tr("Enter a name for the new tag name:"), QLineEdit::Normal,tr("New Tag"), &ok);
bool nameOK = StringCheck::check(text,false,tr("The name you entered has illegal\n characters in it or is empty."));

if (ok && nameOK){
	///add tag
	emit addTag(text);
	//ui.comboBox_tag->addItem(text);
	ui.comboBox_tag->setCurrentIndex(ui.comboBox_tag->count()-1);
	}

}

/**
 * slot is called when we hit the save button, we emit a signal to the parent widget with the new exercisename,
* and new explainations to be saved
* We also emit the index of this exercise so we can lookup the old name of this exercise.
 */
void OneExercise::save()
{
///check data
bool nameOK = StringCheck::check(ui.lineEditName1->text(),false,tr("The name you entered has illegal\n characters in it or is empty."));
bool explanationOK = StringCheck::check(ui.textEditExplaination->toPlainText(),true,tr("The explanation you entered has illegal characters in it."));


if(explanationOK && nameOK){
	QStringList stringlist = QStringList();
	for(int i =0;i<ui.listWidget->count();i++){
		stringlist << ui.listWidget->item(i)->text();
		}
	QString explanation = ui.textEditExplaination->toPlainText();
	explanation.replace(QString("\n"), "  ");
	emit saveExercise(ui.lineEditName1->text(),explanation,stringlist,ui.comboBox_tag->currentText());
	emit saveExercise(ui.lineEditName1->text(),explanation,stringlist,ui.comboBox_tag->currentText(), index);
	setTitle(ui.lineEditName1->text());
	}

}
/**
*slot triggered when pressing delete button. Emits deleteExercise with the index of this exercise.
*/
void OneExercise::deleteExercise()
{
emit deleteExercise(index);
}

/**
 * set the title of the exercise (groupbox)
 * @param title Qstring
 */
void OneExercise::setTitle(QString title)
{
if(newExerciseMode){
///add exercise mode
ui.groupBox->setTitle(QString("                                                                                                                                                                                                                                                                               "));
///this was the most nasty hack ever :-)
///i set the title to a lot of white space and the style to flat => the groupBox disapears but is still theire
///TODO: do it in a better way :-)
}
///modify mode
else{
ui.groupBox->setTitle(title);}
}

/**
*only effects the GUI. Sets tag to tag.
*/
void OneExercise::setTag(QString tag){
this->tag=tag;
int index = ui.comboBox_tag->findText(tag,Qt::MatchExactly);
if(index==-1){
	///not found
	ui.comboBox_tag->setCurrentIndex(0);
	}
else{
	ui.comboBox_tag->setCurrentIndex(index);
	}

}

/**
 * set the exercisename of the exercise lineedit
 * @param title Qstring
 */
void OneExercise::setExerciseName(QString name)
{
ui.lineEditName1->setText(name);
}

/**
 * set the explaination QTextEdit
 * @param str 
 */
void OneExercise::setExerciseExplaination(QString str)
{
ui.textEditExplaination->setText(str);
}

/**
*Add a muscle to the list of muscles this exercise is for.
*Returns true if succesfull, otherwise (str not a legal muscle) false
*/
bool OneExercise::addMuscle(QString str)
{
if (muscleList.contains(str)){
	if(ui.listWidget->findItems(str,Qt::MatchExactly).size()==0){
	ui.listWidget->addItem(str);
	}
return true;
}
return false;
}

/**
*sets this QWidget into 'new exercise mode' this means
*Sets the GroupBox (there is only one) to flat
*No Save button but a: Add button
*No delete button
*/
void OneExercise::setNewExercise(bool var){
	ui.groupBox->setFlat(var);
	if(var){
	newExerciseMode=true;
	ui.deleteButton->hide();
	ui.uploadButton->show();
	ui.uploadButton->setText(tr("Close"));
	ui.uploadButton->disconnect(SIGNAL(pressed()));
	QObject::connect(ui.uploadButton,SIGNAL(pressed()),this,SLOT(closeParent()));
	ui.uploadButton->setToolTip(QApplication::translate("OneExercise", "Close this widget", 0, QApplication::UnicodeUTF8));
	ui.saveButton->setText(tr("Add Exercise"));
	setTitle("doesn't matter");
	}
	if(!var){
	newExerciseMode=false;
	ui.deleteButton->show();
	ui.uploadButton->show();
	ui.uploadButton->disconnect(SIGNAL(pressed()));
	QObject::connect(ui.uploadButton,SIGNAL(pressed()),this,SLOT(uploadExercise()));
	ui.uploadButton->setToolTip(QApplication::translate("OneExercise", "Upload this exercise to the online Qtrainer-database", 0, QApplication::UnicodeUTF8));
	ui.uploadButton->setText(tr("Upload"));
	ui.saveButton->setText(tr("Save"));
	}
}

/**
*emits the closeParent2 signal
*/
void OneExercise::closeParent(){
emit closeParent2();
}

/**
*Add all the  muscles to the list of muscles this exercise is for.
*Returns true if succesfull, otherwise (list contains a non-legal muscle) false
*/
bool OneExercise::addMuscles(QStringList list)
{
bool succes = true;
	for (int i=0;i<list.size();i++){	
	bool result = addMuscle(list.at(i));
	if(result==false){succes = false;}
	}
}

/**
*SLOT: removes the muscle selected in the listWidget
*/
void OneExercise::removeMuscleButtonPressed(){
int row = ui.listWidget->currentRow(); ///-1 when none is selected
if(row!=-1){
	removeMuscle(ui.listWidget->item(row)->text());
	}
if(!newExerciseMode){
	save();
	}
}

/**
*SLOT: removes the muscle selected in the listWidget
*/
void OneExercise::addMuscleButtonPressed(){
addMuscle(ui.comboBox->currentText());
if(!newExerciseMode){
	save();
	}
}


/**
* assures the muscle: str isn't one of the muscles this exercise is for after execution
*/
void OneExercise::removeMuscle(QString str){
QListWidgetItem *item  = ui.listWidget->findItems(str,Qt::MatchExactly).at(0);
int i =0;
while(ui.listWidget->item(i)!=item && i < ui.listWidget->count()-1){i++;}
if(ui.listWidget->item(i)==item){ui.listWidget->takeItem(i);}
}

/**
 * Fill the comboBox with the hard coded muscles in Exercise
 */
void OneExercise::fillComboBox()
{
QStringList  list = QStringList(muscleList);
ui.comboBox->addItems(list);
ui.comboBox_tag->addItems(tagList);
}

/**
*refills the combobox containing the tags, with the new 'tags'
*/
void OneExercise::reloadTagList(QStringList tags){
this->tagList=tags;
ui.comboBox_tag->clear();
ui.comboBox_tag->addItems(tagList);

setTag(this->tag);
}

void OneExercise::uploadExercise(){
QSettings settings("ToonSoft", "Qtrainer");
settings.beginGroup("ProgramSettings");
QString url = settings.value("DatabaseURL").toString();
settings.endGroup();

myClient = new QxtXmlRpcClient(QUrl(url));

QObject::connect(myClient, SIGNAL(finished(int,QVariant)),this,SLOT(finished(int,QVariant)));
QObject::connect(myClient, SIGNAL(fault(int,int,QString)),this,SLOT(fault(int,int,QString)));
QObject::connect(myClient, SIGNAL(parseError(int,QString)),this,SLOT(parseError(int,QString)));
QObject::connect(myClient, SIGNAL(networkError(int,QString)),this,SLOT(networkError(int,QString)));
QList<QVariant> params;
params<<ui.lineEditName1->text()<<ui.textEditExplaination->toPlainText();
for(int i =0;i<ui.listWidget->count();i++){
	params<<ui.listWidget->item(i)->text();
	///add another muscle
	}
int i = myClient->call(QString("storeexercise"), params);
}


void OneExercise::fault(int callId, int faultCode, QString faultString){
	QMessageBox msgBox;
	msgBox.setStandardButtons(QMessageBox::Ok);
	msgBox.setText(tr("Exercise couldn't be uploaded to the online database.\n")+faultString);
	msgBox.exec();
// 	switch (msgBox.exec()) 
// 		{
// 		case QMessageBox::Ok:
// 		filehandler->deleteExercise(index);
// 		emit redrawNeeded();
// 		drawWidgets();
// 		break;
// 		default:
// 		// should never be reached
// 		break;
// 		}
}


void OneExercise::parseError(int callId, QString errorMsg){
QMessageBox msgBox;
	msgBox.setIcon(QMessageBox::Critical);
	msgBox.setStandardButtons(QMessageBox::Ok);
	msgBox.setText(tr("Exercise couldn't be uploaded. A parse error occured.\nThis is probably Qtrainers fault."));
	msgBox.exec();
}

void OneExercise::networkError(int callId, QString errorMsg){
	QMessageBox msgBox;
	msgBox.setIcon(QMessageBox::Critical);
	msgBox.setStandardButtons(QMessageBox::Ok);
	msgBox.setText(tr("Exercise couldn't be uploaded. A network error occured."));
	msgBox.exec();
}

void OneExercise::finished(int callId, QVariant retValue){
if(retValue.toString()=="exercise already in the database"){
	QMessageBox msgBox;
	msgBox.setIcon(QMessageBox::Warning);
	msgBox.setStandardButtons(QMessageBox::Ok);
	msgBox.setText(tr("Exercise couldn't be uploaded. Another exercise with the same name already existed.\nTry uploading using another name."));
	msgBox.exec();
}
if(retValue.toString()=="succes"){
 	QMessageBox msgBox;
 	msgBox.setIcon(QMessageBox::Information);
 	msgBox.setStandardButtons(QMessageBox::Ok);
 	msgBox.setText(tr("Exercise was uploaded to the online database.\nThanks for your contribution."));
 	msgBox.exec();
}
//QTextStream cout(stdout, QIODevice::WriteOnly);
//cout<<retValue.toString()<<endl;
}
