/*******************************************************************************
***  This file is part of Dux Rei Nummariae.                                 ***
***                                                                          ***
***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
***                                                                          ***
***  This program is free software: you can redistribute it and/or modify it ***
***  under the terms of the GNU Affero General Public License as published   ***
***  by the Free Software Foundation, either version 3 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 Affero General Public License for more details.             ***
***                                                                          ***
***  You should have received a copy of the GNU Affero General Public License***
***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
*******************************************************************************/
#ifndef DRN_BUDGETING_EVENTFREQUENCY_H_
#define DRN_BUDGETING_EVENTFREQUENCY_H_

#include <QtGlobal>

#include <array>
#include <ostream>

#include "budgeting_export.h"


class QDateTime;
class QString;

namespace drn
{
namespace budgeting
{

/**
 * @brief The available frequencies at which an event may regularly occur.
 */
enum class DRN_BUDGETING_EXPORT EventFrequency : quint8
{
	/// It is not known when the event will reoccur.
	Unknown,
	/// The event will happen every hour.
	Hourly,
	/// The event will happen every day, i.e. every 24 hours.
	Daily,
	/// The event will happen roughly twice a week, i.e. every 84 hours (3.5 days).
	SemiWeekly,
	/// The event will happen once a week, i.e. every 168 hours (7 days).
	Weekly,
	/// The event will happen every two weeks, i.e. every 336 hours (14 days).
	BiWeekly,
	/// The event will happen twice a month, i.e. every 360 hours (15 days).
	SemiMonthly,
	/// The event will happen once a month.
	Monthly,
	/// The event will happen every two months.
	BiMonthly,
	/// The event will happen every three months.
	Quarterly,
	/// The event will happen twice a year.
	SemiAnnually,
	/// The event will happen once a year.
	Annually,
	/// The event will happen every two years.
	Biannually,
	/// The event will happen every three years.
	Triannually,
	/// The event will never happen.
	Never,
};

DRN_BUDGETING_EXPORT quint8 toWeak(const EventFrequency strong);
DRN_BUDGETING_EXPORT EventFrequency toEventFrequency(const quint8 weak);
DRN_BUDGETING_EXPORT EventFrequency toEventFrequency(const ::QString& weak);
DRN_BUDGETING_EXPORT std::ostream& operator<<(std::ostream& o, const EventFrequency ef);
DRN_BUDGETING_EXPORT ::QString presentationText(const EventFrequency& ef);
/**
 * @brief Calculates the next time point from a given point using a specific event frequency.
 *
 * @exception Error When the event frequency is not known.
 * @exception Error When the current time point is not valid.
 *
 * @param current The current time point to calculate from.
 * @param ef The event frequency to calculate the next time point for.
 *
 * @return The calculated time point. If the event is never to happen, the largest possible point
 * in time is given.
 */
DRN_BUDGETING_EXPORT ::QDateTime nextTimePoint(
	const ::QDateTime& current,
	const EventFrequency& ef
);

constexpr quint8 numberOfEventFrequencies{15};
extern DRN_BUDGETING_EXPORT const std::array<
	EventFrequency,
	numberOfEventFrequencies
> allEventFrequencies;

}}

#endif
