//
// C++ Implementation: ConfigFileHandlerBodyMeasurements
//
// Description: 
//
//
// Author: Muylkens Toon <toon.muylkens@student.kuleuven.be>, (C) 2007
//
// Copyright: See COPYING file that comes with this distribution
//
//

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

ConfigFileHandlerBodyMeasurements::ConfigFileHandlerBodyMeasurements(QString profilename, QObject *parent) : ConfigFileHandler(profilename,parent){
sport = tr("Body Measurements");
// measurementsList = QMap<QString, QList<BodyMeasurement*> >();
this->age =  new Age(-1);
this->bmi =  new Bmi(-2);
setprofilename(profilename);

}


void ConfigFileHandlerBodyMeasurements::logout(){

}

/**
*Adds the bodypart 'part' to the list of bodypart, when it isn't already added previously.
*Two BodyParts are equal when they have the same objectName and the same UnitName
*/
void ConfigFileHandlerBodyMeasurements::addBodyPart(BodyPart *part, bool withsave){
bool contains = false;
for(int i=0;i<bodyPartList.size();i++){
	if(bodyPartList.at(i)->objectName() == part->objectName() && bodyPartList.at(i)->unitName() == part->unitName()){
		contains = true;
		}
	}
if(!contains){
	bodyPartList.append(part);
	}
if(withsave){savedata();}
QObject::connect(part, SIGNAL(saveBodyPart()), this, SLOT(savedata()));
}

/**
*Deletes the bodyPart wich has index 'index' in getBodyParts()
*all its measurements are also deleted!
*/
void ConfigFileHandlerBodyMeasurements::deleteBodyPart(int index){
if(getBodyParts().size()-1>=index && index>=0){
	BodyPart *part = getBodyParts().at(index);
	part->getMeasurements().clear();
	bodyPartList.removeAt(index);
	savedata();
	emit bodyPartIndexingChanged();
	}
}

/**
*index is index in getBodyParts()
*save the BodyPart with index 'index'
*profile is saved
*signal is emitted
*/
void ConfigFileHandlerBodyMeasurements::saveBodyPart(QString newname, QString newexplanation, QString newunit, int index){
if(getBodyParts().size()-1>=index && index>=0){
	BodyPart *part = getBodyParts().at(index);
	part->setExplanation(newexplanation);
	part->setUnit(newunit);
	part->setName(newname);
	savedata();
	emit bodyPartChanged();
	emit bodyPartChanged(index);
	}
}


// void ConfigFileHandlerBodyMeasurements::addDatapoint(BodyMeasurement *measurement, bool withsave){
// QList<BodyMeasurement*> list;
// 
// if(measurementsList.contains(measurement->getBodyPart()->objectName())){
// 	list = QList<BodyMeasurement*>(measurementsList.value(measurement->getBodyPart()->objectName()));
// 	}
// list.append(measurement);
// measurementsList.insert(measurement->getBodyPart()->objectName(), list);
// if(withsave){savedata();}
// }

void ConfigFileHandlerBodyMeasurements::loaddata(QString profilename){
///remove all data from Hashes because we only add/insert things.
///we don't want to keep old data from old profile when opening a new one.
clearalldatahashes();
	QFile file;
	QSettings settings("ToonSoft", "Qtrainer");
	settings.beginGroup("ProgramSettings");
	QString profilePath=(settings.value("Profile_Path")).toString();
	settings.endGroup();
	QDir::setCurrent(profilePath);
	file.setFileName((profilename).append(".QProfile"));
	file.open(QIODevice::ReadOnly);
     	QTextStream in(&file);
int i=1;
while (!in.atEnd()) {
       	QString line = in.readLine();
        processline(line);
	i++;
	}
}

void ConfigFileHandlerBodyMeasurements::processline(QString line){
QString name;

name="<BodyPart>";
if(line.startsWith(name)){
	QString object = line.section('!', 1, 1);
	QString unit = line.section('!', 2, 2);
	QString explanation = line.section('!', 3, 3);
	int index = getMeasurables().size();
	BodyPart *part = new BodyPart(unit,object,index);
	part->setExplanation(explanation);
	addBodyPart(part,false);
	}

name="<BodyMeasurement>";
if(line.startsWith(name)){
	QString object = line.section('!', 1, 1);
	QString unit = line.section('!', 2, 2);
	BodyPart *part = getBodyPart(unit,object);
	StringDate date = StringDate(line.section('!',3,3));
	QString valueS = line.section('!',4,4);
	int value  = valueS.toInt();
	BodyMeasurement *body = new BodyMeasurement(part,date,value);
	part->linkMeasurement(body,false);
	//addDatapoint(body);
	}

name="<Age>";
if(line.startsWith(name)){
	QString bdate = line.section('!', 1, 1);
	StringDate b = StringDate(QDate::currentDate());
	if(bdate.size()>=8){
		b = StringDate(bdate);
		}
	getAge()->setBDate(b);
	}

name="<Bmi>";
if(line.startsWith(name)){
	QString heightname = line.section('!', 1, 1);
	QString weightname = line.section('!', 2, 2);
	for (int i=0; i<getBodyParts().size();i++){
		BodyPart *part = getBodyParts().at(i);
		if(part->objectName() == heightname){
			getBmi()->setHeight(part);
			}
		if(part->objectName() == weightname){
			getBmi()->setWeight(part);
			}

		}
	}

///NUMBER of POINTS to PLOT
///and
///PLOT METHODS
	for(int i=0;i<getMeasurables().size();i++)
	{
	///number of points to plot
	name="<NumberOf";
	name.append(getMeasurables().at(i)->getName());
	name.append("PointsToPlot>");
	if(line.startsWith(name)){
		QString str = line.section('!', 1, 1);int intvalue=str.toInt();getMeasurables().at(i)->setNbOfPointsToPlot(intvalue);
		}
	///plot method
	name="<PlotMethodFor";
	name.append(getMeasurables().at(i)->getName());
	if(line.startsWith(name)){
		QString first = line.section('!', 1, 1);
		QString second = line.section('!', 2, 2);
		QString third = line.section('!', 3, 3);
		QStringList tempList = QStringList();
		if(first=="Bevier" || second=="Bevier" || third=="Bevier") {tempList<<"Bevier";}
		if(first=="Spline" || second=="Spline" || third=="Spline") {tempList<<"Spline";}
		if(first=="Line" || second=="Line" || third=="Line") {tempList<<"Line";}
		getMeasurables().at(i)->setPlotMethod(tempList);
		}
	}

}

/**
*Returns the BodyPart with the given unit and object.
*When no bodypart exists with the given unit and object, one is constructed (and added to the list of bodyParts)
*/
BodyPart *ConfigFileHandlerBodyMeasurements::getBodyPart(QString unit, QString object){
for(int i=0;i<bodyPartList.size();i++){
	if(bodyPartList.at(i)->objectName() == object && bodyPartList.at(i)->unitName() == unit){
		return bodyPartList.at(i);
		}
	}
int index = getMeasurables().size();
BodyPart *part = new BodyPart(unit, object,index);
addBodyPart(part);
return part;
}

/**
*Returns a QList with pointers to all the current BodyParts
*WARNING: indexing can change, but when this happend bodyPartIndexingChanged() signal will be emitted!
*/
QList<BodyPart*> ConfigFileHandlerBodyMeasurements::getBodyParts(){
return QList<BodyPart*>(this->bodyPartList);
}

/**
*Returns a QList with pointers to all the current Measurbale objects (BodyParts, Bmi, ...)
*WARNING: indexing can change, but when this happend bodyPartIndexingChanged() signal will be emitted!
*/
QList<Measurable*> ConfigFileHandlerBodyMeasurements::getMeasurables(){
QList<Measurable*> list;
QList<BodyPart*> listB = getBodyParts();
for(int i=0;i<listB.size();i++){
	list.append(listB.at(i));
	}
list.append(getBmi());
return list;
}

void ConfigFileHandlerBodyMeasurements::clearalldatahashes(){
this->bodyPartList.clear();
}

/**
*return the Age object
*/
Age *ConfigFileHandlerBodyMeasurements::getAge(){
return this->age;
}

/**
*return the Bmi object
*/
Bmi *ConfigFileHandlerBodyMeasurements::getBmi(){
return this->bmi;
}


void ConfigFileHandlerBodyMeasurements::setprofilename(QString profilename){
this->profilename=profilename;
loaddata(profilename);
}

void ConfigFileHandlerBodyMeasurements::savedata(){
ConfigFileHandler::savedata();
if(getSaveEnable()){
	///PROFILE-SETTINGS
	QString name;
	QList<int> values;
	QString str(this->profilename);
		QSettings settings("ToonSoft", "Qtrainer");
		settings.beginGroup("ProgramSettings");
		QString profilePath=(settings.value("Profile_Path")).toString();
		settings.endGroup();
	QDir::setCurrent(profilePath);
	QFile file((str).append(".QProfile"));
     	if (!file.open(QIODevice::WriteOnly | QIODevice::Text)){/*cout<<"fault"<<endl;*/   return;}

     	QTextStream out(&file);
	out << "PROFILE INFORMATION: \n";
     	out << "<ProfileName> !" <<(this->profilename)<< "! \n";
	out << "THE FOLLOWING 3 CAN CHANGE BUT ONLY ONE OF THEM CAN BE TRUE: \n";
 	out << "<BodyMeasurements> !true! \n";

	///BODYPARTS
	out<< "BODYPARTS:  !Objectname!measureUnit!Explanation! \n";	
	for(int i=0;i<bodyPartList.size();i++){
		name="<BodyPart> !";
		name.append(bodyPartList.at(i)->toString());
		out<<name<<"\n";
	}

	///BODYMEASUREMENTS
	out<< "BODYMEASUREMENT:  !bodyPart->object!bodypart->unit!date.getQString()!value! \n";
	for(int i=0;i<bodyPartList.size();i++){
		QList<BodyMeasurement*> list = bodyPartList.at(i)->getMeasurements();
		for(int j=0; j<list.size(); j++){
			name="<BodyMeasurement> !";
			name.append(list.at(j)->toString());
			out<<name<<"\n";
			}
	}

	///Age
	out<<"AGE: !BirthDate!\n";
	out<<"<Age> !"<<getAge()->toString()<<"\n";
	

	///Bmi
	if(getBmi()->allDependenciesSet()){
	out<<"BMI: !Heightname!weightName!\n";
	out<<"<Bmi> !"<<getBmi()->toString()<<"\n"; 
	}
	
	///PlotMethods and numberOfPointsToPlot
	out << "PLOTWIDGET INFORMATION: When saving plotmethods: 3 possible ones: Bevier, Line and Spline\n";
	for(int i=0;i<getMeasurables().size();i++)
		{
		///Number Of Points To Plot	
		name="<NumberOf";
		name.append(getMeasurables().at(i)->getName());
		name.append("PointsToPlot> !");
		out <<name<<getMeasurables().at(i)->getNbOfPointsToPlot()<<"! \n";
		///Plot Method (bevier, splines, lines)
		name="<PlotMethodFor";
		name.append(getMeasurables().at(i)->getName());
		name.append("> !");
		QStringList temp = getMeasurables().at(i)->getPlotMethod();
		QString writeString="";
		for(int k=0;k<temp.size();k++){
			writeString.append(temp.at(k));
			writeString.append("!");
			}
		out<<name<<writeString<<"\n";
		}
}///if(getSaveEnable()))
}

/**
*Returns the value of the most recent measurement of the given BodyPart
*/
int ConfigFileHandlerBodyMeasurements::getLatestValue(BodyPart* part){
QDate date = part->getDateLatestMeasurement();
if(part->hasMeasurement(date)){
	return part->getMeasurement(date)->getValue();
	}
return 10;
}


