/***************************************************************************
 *   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 "ExerciseHandler.h"
// #include <stdio.h>
// #include <iostream>
// using namespace std;

ExerciseHandler::ExerciseHandler(QObject *parent) : QObject(parent)
{
this->defaultValueForRepetitions = 10;
///NORMALIZE_FACTOR =  -0.035714285; ///-> oude factor berekend via originele plots, bleek iets te groot
this->NORMALIZE_FACTOR =  -0.023256;
fillPossibleMusclesList();
}

/*QList<QStringList> ExerciseHandler::plotMethodList= QList<QStringList>();
QList<QString> ExerciseHandler::nameList= QList<QString>();
QList<QString> ExerciseHandler::explainationList= QList<QString>();
QList<QPixmap> ExerciseHandler::pictureList= QList<QPixmap>();
QList<QStringList> ExerciseHandler::muscleList= QList<QStringList>();
QList<QString> ExerciseHandler::tagList= QList<QString>();*/
QList<QString> ExerciseHandler::possibleMusclesList= QList<QString>(); ///special list with all men's muscles
//int ExerciseHandler::NumberOfHardCodedExercises=0; ///some value, for initialisation, gets owerwritten

/**
 * Some exercises are hard coded into Qtrainer, other are addable by the user.
 * @return 
 */
// int ExerciseHandler::getHardCoded()
// {
// return NumberOfHardCodedExercises;
// }

/**
*Returns true when an exercise with the same index is already stored
*see also isAlreadyStored
*/
bool ExerciseHandler::contains(int index){
return exerciseIndexMap.contains(index);
}

/**
*Returns true when an exercise with the same name is already stored
*/
bool ExerciseHandler::isAlreadyStored(QString name)
{
return exerciseNameMap.contains(name);
/*
bool alreadyStored=false;
for(int i=0;i<ExerciseHandler::nameList.size();i++)
{
if(name==ExerciseHandler::nameList.at(i)){alreadyStored=true;}
}
return alreadyStored;*/
}

/**
*Returns a list containing a pointer to every stored exercise
*/
QList<Exercise*> ExerciseHandler::getExercises(){
return exerciseIndexMap.values();
}

/**
*new.isAlreadyStored(name) == true
*/
void ExerciseHandler::addExercise(QString name, QString explanation, QStringList muscleList, QString tag)
{
int index = getNbOfExercises();
QStringList plotMethodList;
plotMethodList<<"Bevier";
Exercise *myExercise = new Exercise(index, name, explanation, 0, plotMethodList, muscleList, tag, this);
QObject::connect(myExercise,SIGNAL(measurementChanged()),this,SLOT(someMeasurementChanged()));
exerciseNameMap.insert(name, myExercise);
exerciseIndexMap.insert(index, myExercise);
emit saveDataRequest();
///appends adds the thing at the end of the  QList
// ExerciseHandler::nameList.append(name);
// ExerciseHandler::explainationList.append(explaination);
// ExerciseHandler::muscleList.append(musclelist);
// ExerciseHandler::tagList.append(tag);
// ExerciseHandler::plotMethodList.append(QStringList() << "Bevier" << "NotLine" << "NotSpline");
}

/**
*SLOT: emits the saveDataRequest signal
*/
void ExerciseHandler::someMeasurementChanged(){
emit saveDataRequest();
}

/**
 * Adds an exercisetag to the profile and saves the profile.
 * @param tag string: tagname
 */
void ExerciseHandler::addExerciseTag(QString tag)
{
if(!tag.contains("!") && !possibleExerciseTagList.contains(tag)){
	possibleExerciseTagList.append(tag);	
	emit saveDataRequest();
	QStringList newList = QStringList(this->possibleExerciseTagList);
	emit exerciseTagListChanged(newList);
	emit exerciseTagListChanged();
}
}

/**
*returns a list with all the tags for exercises that are saved into this profile
*/
QStringList ExerciseHandler::getPossibleExerciseTagList(){
return QStringList(possibleExerciseTagList);
}

/**
*new.getPossibleExerciseTagList() == list;
*/
void ExerciseHandler::setPossibleExerciseTagList(QStringList list){
this->possibleExerciseTagList = list;
emit saveDataRequest();
}



/**
*Returns the current number of exercises in this ExerciseHandler
*/
int ExerciseHandler::getNbOfExercises(){
return exerciseNameMap.size();
}

/**
 * Hard coded muscle-groups (hard coded into Qtrainer source)
 */
void ExerciseHandler::fillPossibleMusclesList()
{
ExerciseHandler::possibleMusclesList.insert(0,"Pectoralis Major "+tr("(Chest)"));
ExerciseHandler::possibleMusclesList.insert(1,"Trapezius "+tr("(Back - Upper)"));
ExerciseHandler::possibleMusclesList.insert(2,"Erector Spinae "+tr("(Back - Below)"));
ExerciseHandler::possibleMusclesList.insert(3,"Latissimus Dorsi "+tr("(Shoulder)"));
ExerciseHandler::possibleMusclesList.insert(4,"Romboidei "+tr("(Shoulder)"));
ExerciseHandler::possibleMusclesList.insert(5,"Biceps "+tr("(Upper Arm)"));
ExerciseHandler::possibleMusclesList.insert(6,"Triceps "+tr("(Upper Arm)"));
ExerciseHandler::possibleMusclesList.insert(7,"Rectus Abdominis "+tr("(Belly)"));
ExerciseHandler::possibleMusclesList.insert(8,tr("Hip Bender (Hip/Belly)"));
ExerciseHandler::possibleMusclesList.insert(9,tr("Hip Extender (Hipp/Belly)"));
ExerciseHandler::possibleMusclesList.insert(10,"Quadriceps "+tr("(Knee Extender)"));
ExerciseHandler::possibleMusclesList.insert(11,"Hamstrings "+tr("(Knee)"));
ExerciseHandler::possibleMusclesList.insert(12,tr("Ankle muscles"));
ExerciseHandler::possibleMusclesList.insert(13,"Deltoid"+tr("(Chest - upper)"));
ExerciseHandler::possibleMusclesList.insert(14,"Brachialis"+tr("(Biceps - Lower)"));
ExerciseHandler::possibleMusclesList.insert(15,"Brachioradialis"+tr("(Arm - Lower)"));
ExerciseHandler::possibleMusclesList.insert(16,"Serratus Anterior"+tr("(Chest - Ribs)"));
ExerciseHandler::possibleMusclesList.insert(17,tr("Other muscle"));
}


/**
*A list that conains the plotMethod (bevier, spine,line) for every exercise
*/
// QList<QStringList> ExerciseHandler::getPlotMethodList(){
// return ExerciseHandler::plotMethodList;
// }
// 
// QList<QString> ExerciseHandler::getNameList()
// {
// return ExerciseHandler::nameList;
// }
// 
// QList<QString> ExerciseHandler::getExplainationList()
// {
// return ExerciseHandler::explainationList;
// }
// 
// QList<QPixmap> ExerciseHandler::getPictureList()
// {
// return ExerciseHandler::pictureList;
// }

QList<QString> ExerciseHandler::getPossibleMuscleList()
{
return ExerciseHandler::possibleMusclesList;
}

/*
QList<QStringList> ExerciseHandler::getMuscleList()
{
return ExerciseHandler::muscleList;
}

QList<QString> ExerciseHandler::getTagList()
{
return ExerciseHandler::tagList;
}
*/

/**
*Returns the Name of the exercise with the given index
*If no exercise with index index exists: Not Found is returned
*/
QString ExerciseHandler::getName(int index){
if(exerciseIndexMap.contains(index)){
return exerciseIndexMap.value(index)->getName();
}
else{
return tr("Not Found");
}

}


/**
*Returns a list containing all the unique ID's of exercises.
*/
QList<int> ExerciseHandler::getIndexes(){
	return exerciseIndexMap.keys();
}


/**
 * returns the index the information about exercise with name <exercisename> is stored
 * @param exercisename 
 * @return -1 when exercisename is not a known name!
 */
int ExerciseHandler::getindex(QString exercisename)
{
if(exerciseNameMap.contains(exercisename)){
return exerciseNameMap.value(exercisename)->getIndex();
}
else{
return -1;
}/*
int indexinhashesOfExerciseHandlers=-1;
for(int i = 0; i<getNameList().size(); i++)
	{
	if(getNameList().at(i)==exercisename) {indexinhashesOfExerciseHandlers=i;}
	}
return indexinhashesOfExerciseHandlers;*/
}

/**
*Returns the default nb of repetitions. This is the nb of repetitions the user can do when
*using the normalizes weight.
*/
int ExerciseHandler::getDefaultValueForRepetitions()
{
return defaultValueForRepetitions;
}

/**
*Returns the factor used for normalisation (weight to use when doing Default nb of reps instead of other nb 
*/
float ExerciseHandler::getNormaliseFactor(){
return NORMALIZE_FACTOR;
}

/**
 * Clear all lists, fe when we load or start a new profile, the exercises of the old one need to be deleted
 */
void ExerciseHandler::clear()
{
exerciseNameMap.clear();
exerciseIndexMap.clear();
possibleExerciseTagList.clear();
/*ExerciseHandler::nameList.clear();
ExerciseHandler::plotMethodList.clear();
ExerciseHandler::explainationList.clear();
ExerciseHandler::pictureList.clear();
ExerciseHandler::muscleList.clear();
ExerciseHandler::tagList.clear();*/
}

/**
*Returns the exercise with the given index or something useless when no exercise is found with
*the given index
*/
Exercise *ExerciseHandler::getExercise(int index){
return exerciseIndexMap.value(index);
}

/**
*Returns the exercise with the given name or something useless when no exercise is found with
*the given name
*Make sure the exercise with name 'name' exists! (use isAlreadyStored)
*/
Exercise *ExerciseHandler::getExercise(QString name){
QList<Exercise*> list = exerciseNameMap.values();
return exerciseNameMap.value(name);
}



/**
 * replace the name of an exercise with another name
 * @param newname 
 * @param index 
 */
void ExerciseHandler::replaceName(QString newname, int index)
{
if(exerciseIndexMap.contains(index)){
	Exercise *ex = getExercise(index);
	exerciseNameMap.take(ex->getName());
	ex->setName(newname);
	exerciseNameMap.insert(newname,ex);
	}
emit saveDataRequest();
}

/**
 * Sets the plotmethod of the exercise
 * @param newPlotmethod
 * @param index 
 */
void ExerciseHandler::setPlotMethod(QStringList newplotmethods, int index)
{
if(exerciseIndexMap.contains(index)){
	Exercise *ex = getExercise(index);
	ex->setPlotMethod(newplotmethods);	
	}
emit saveDataRequest();
}


/**
 * replace the explaination of an exercise with another exercise
 * @param newname 
 * @param index 
 */
void ExerciseHandler::replaceExplaination(QString newexplaination, int index)
{
if(exerciseIndexMap.contains(index)){
	Exercise *ex = getExercise(index);
	ex->setExplanation(newexplaination);
	}
emit saveDataRequest();
}

void ExerciseHandler::replaceMuscle(QStringList newMuscleList, int index)
{
if(exerciseIndexMap.contains(index)){
	Exercise *ex =getExercise(index);
	ex->setMuscleList(newMuscleList);
	}
emit saveDataRequest();

}

void ExerciseHandler::replaceTag(QString newTag, int index){
if(exerciseIndexMap.contains(index)){
	Exercise *ex = getExercise(index);
	ex->setTag(newTag);
	}
emit saveDataRequest();
}


/**
 * we remove the exercise from the Lists
 * @param index 
 */
void ExerciseHandler::deleteExercise(int index)
{
///TODO call destructor
Exercise *ex = exerciseIndexMap.take(index);
exerciseNameMap.take(ex->getName());
emit saveDataRequest();
}



