//
// C++ Implementation: Training
//
// Description: 
//
//
// Author: Muylkens Toon <toon.muylkens@student.kuleuven.be>, (C) 2007
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "BodyPart.h"
//    #include <stdio.h>
//    #include <iostream>
//    using namespace std;

/**
*constructs a new Body Part
*@param unit fe cm,kg,%, ...
*@param object fe arm, weight, fat
*@param index uniqe ID
*@param parent parent widget
*/
BodyPart::BodyPart(QString unit, QString object, int index, QWidget *parent):Measurable(index, parent)
 {
	this->bodyPart = true;
	this->unit=unit;
	this->object=object;
	this->mostRecentMeasurement = QDate(1000,10,10); ///long time ago :-)
	this->nbPointsToPlot = 0;
	this->plotMethodList << "Bevier";
 }

// void BodyPart::setExplanation(QString explanation){
// this->explanation=explanation;
// }
// 
// void BodyPart::setName(QString name){
// this->object=name;
// }

void BodyPart::setUnit(QString unit){
this->unit=unit;
}

/**
*the 'number' most recent points will be plotted
*The information set here will be saved into the profile upun next savedata
*/
// void BodyPart::setNbOfPointsToPlot(int number){
// this->nbPointsToPlot = number;
// }

/**
*which method to use for plotting: Bevier (idd it should be bezier), line and spline
*/
// void BodyPart::setPlotMethod(QStringList plotMethodList){
// this->plotMethodList = plotMethodList;
// }


// QStringList BodyPart::getPlotMethod(){
// return this->plotMethodList;
// }

/**
*Returns true if one of the plotmethods is bezier
*/
// bool BodyPart::getBezier(){
// return this->plotMethodList.contains("Bevier");
// }

/**
*Returns true if one of the plotmethods is line
*/
// bool BodyPart::getLine(){
// return this->plotMethodList.contains("Line");
// }

/**
*Returns true if one of the plotmethods is spline
*/
// bool BodyPart::getSpline(){
// return this->plotMethodList.contains("Spline");
// }

// int BodyPart::getNbPointsToPlot(){
// return this->nbPointsToPlot;
// }


// QString BodyPart::getExplanation(){
// return this->explanation;
// }

/**
*returns object!unit!explanation!;
*/ 
QString BodyPart::toString(){
QString result;
result=objectName()+"!"+unitName()+"!"+getExplanation()+"!";
return result;
}


/**
*returns objectName
*/ 
QString BodyPart::objectName() const{
QString temp =  Measurable::getName();
return temp;
}

/**
*returns unit
*/ 
QString BodyPart::unitName() const{
return unit;
}

/**
*Link a bodyMeasurement, which belongs to this BodyPart to this BodyPart.
*It is added to the list of Measurements of this bodyMeasurement
*\note When the measurement doesn't link to those bodypart, it isn't added
*\note The number of points to plot is increased by one:
* 	| new->getNbPointsToPlot() = getNbPointsToPlot()+1
*@param withsave: by default: true. This bodypart is saved into the profile when true
*	The saveBodyPart() signal is emitted
*\note when another measurement with the same date is already inserted. It is overridden
*/
void BodyPart::linkMeasurement(BodyMeasurement *measurement, bool withsave){
if(measurement->getDate().getQDate() > mostRecentMeasurement){
	///new most recent measurement
	mostRecentMeasurement = measurement->getDate().getQDate();
	}


if(!measurementMap.contains(measurement->getDate())){
	setNbOfPointsToPlot(getNbOfPointsToPlot()+1);
	}
measurementMap.insert(measurement->getDate(),measurement);


if(withsave) {emit saveBodyPart();}

}

/**
*Return a QDate with a value of the most recent body measurment from thos part
* or some random early date when no measurements are set.
*/
QDate BodyPart::getDateLatestMeasurement(){
return this->mostRecentMeasurement;
}

/**
*Returns the Measurement from the given date
*Make sure the measurements exists! use hasMeasurment(QDate)
*/
BodyMeasurement *BodyPart::getMeasurement(QDate date){
return measurementMap.value(date);
}

/**
*returns true when this BodyPart has a measurement on the given date
*/
bool BodyPart::hasMeasurement(QDate date){
return measurementMap.contains(date);
}

/**
*Returns a list with all the measurments from this BodyPart
* From QtDocs: With QMap, the items are always sorted by key
* From QtDocs: .value() function: Returns a list containing all the values in the map, 
* in ascending order of their key (datum loopt op met index)
*/
QList<BodyMeasurement*> BodyPart::getMeasurements(){
return measurementMap.values();
}

/**
*Returns a QVector with the first points the most recent one. 
*The other points are ordered by the day they where entered.
*X-coordinate is the number of days ago the data was entered.
*Y-coordinate is the corresponding value
*/
QVector<QPointF> BodyPart::getVector(){
QVector<QPointF> data;
for (int i=0;i<getMeasurements().size();i++){
	QDate dateOfMeasurement = getMeasurements().at(i)->getDate().getQDate();
	QPointF pointf;
	pointf.setX(dateOfMeasurement.daysTo(QDate::currentDate()));
	pointf.setY(getMeasurements().at(i)->getValue());
	data.prepend(pointf);	
	}
return data;

}

/**
*Returns true if a measurement with date = mes->getDate() exists and when
*mes->getBodyPart() == this
*/
bool BodyPart::isdatealreadystored(BodyMeasurement *mes){
return (mes->getBodyPart() == this && this->measurementMap.contains(mes->getDate()));
}

/**
*Two bodyparts are equal when they have the same objectname and unitName!!
*/
bool BodyPart::operator==( const BodyPart &s1 ) const{
return (s1.objectName() == objectName() && s1.unitName() == unitName());
}