/***************************************************************************
 *   Copyright (C) 2010 by Volker Lanz <vl@fidra.de>                       *
 *                                                                         *
 *   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.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
 ***************************************************************************/

#if !defined(ACTIVITY__H)

#define ACTIVITY__H

#include "core/types.h"
#include "core/dbitem.h"

#include "util/weather.h"

#include <QList>
#include <QString>
#include <QDateTime>

class Equipment;
class Category;
class Lap;
class Profile;

class QSqlQuery;
class QDate;

class Activity : public DbItem
{
	Q_DISABLE_COPY(Activity);

	friend class Lap;
	friend class Profile;

	public:
		Activity();
		Activity(Profile* p, const QSqlQuery& q);
		~Activity();

	public:
		bool serialize();
		static bool list(Profile* profile, Activities& result);

		const QString& name() const { return m_Name; }
		const QDateTime& timeStamp() const { return m_TimeStamp; }
		qint32 temperature() const { return m_Temperature; }
		Weather::Condition weather() const { return m_Weather; }
		const QString& weatherDescription() const { return m_WeatherDescription; }
		const QString& notes() const { return m_Notes; }

		const Category* category() const { return m_Category; }
		Category* category() { return m_Category; }

		const Equipment* equipment() const { return m_Equipment; }
		Equipment* equipment() { return m_Equipment; }

		quint32 totalDistance() const;
		quint32 totalDuration() const;
		quint32 averagePace() const;
		quint32 averageSpeed() const;
		quint32 maxSpeed() const;
		quint32 energyConsumption() const;
		quint32 averageHeartRate() const;
		quint32 maxHeartRate() const;
		quint32 averageCadence() const;
		quint32 totalAscent() const;
		quint32 totalDescent() const;
		bool calcBoundaries(double& minLat, double& minLon, double& maxLat, double& maxLon) const;

		static quint64 totalEquipmentDistance(const Activities& activities, const Equipment* e);
		static QDate equipmentLastused(const Activities& activities, const Equipment* e);
		static bool hasActivity(const Activities& haystack, const Activity& needle);
		static void calcTrackPointSpeed(Activities& acts);
		static void calcLapTotalAscentAndDescent(Activities& acts);

		void setName(const QString& n) { m_Name = n; setDirty(true); }
		void setTimeStamp(const QDateTime& ts) { m_TimeStamp = ts; setDirty(true); }
		void setTemperature(qint32 t) { m_Temperature = t; setDirty(true); }
		void setWeather(Weather::Condition w) { m_Weather = w; setDirty(true); }
		void setWeatherDescription(const QString& s) { m_WeatherDescription = s; setDirty(true); }
		void setNotes(const QString& s) { m_Notes = s; setDirty(true); }

		void setCategory(Category* c) { m_Category = c; setDirty(true); }
		void setEquipment(Equipment* e) { m_Equipment = e; setDirty(true); }

		void addLap(Lap* l) { m_Laps.append(l); }

		Laps& laps() { return m_Laps; }
		const Laps& laps() const { return m_Laps; }

	protected:
		const Profile* profile() const { return m_Profile; }
		void setProfile(Profile* p) { m_Profile = p; setDirty(true); }

		void clear();

	private:
		Profile* m_Profile;
		Category* m_Category;
		Equipment* m_Equipment;
		QString m_Name;
		QDateTime m_TimeStamp;
		qint32 m_Temperature; ///< in centi-degrees Celsius (315 for 31.5°C)
		Weather::Condition m_Weather;
		QString m_WeatherDescription;
		QString m_Notes;
		Laps m_Laps;
};

#endif
