/*******************************************************************************
***  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_ALGORITHM_H_
#define DRN_BUDGETING_ALGORITHM_H_

#include <QtGlobal>

#include <chrono>

#include "Constants.hpp"
#include "budgeting_export.h"
#include <foundation/CalendarTime.hpp>


namespace pecunia
{
namespace currency
{

class Money;

}}

namespace drn
{
namespace budgeting
{

enum class EventFrequency : quint8;

/**
 * @brief Calculates the conversion ration to get from one event frequency period to another with a
 * full year, 52 weeks, as a baseline. The "never" frequency conversion ratio is considered to be
 * zero.
 *
 * @exception Error When either the supplied from or two values are Unknown.
 * @exception logic_error When either the from or to values are not known.
 *
 * @param from The frequency period to convert from.
 * @param to The frequency period to convert to.
 * @param hrInWeek The number of hours considered in a full week.
 * @param dayInWeek The number of days considered in a full week.
 *
 * @return The ratio that when multiplying the "from" value by it will be equal to the "to" value.
 */
DRN_BUDGETING_EXPORT double convert(
	const EventFrequency from,
	const EventFrequency to,
	const std::chrono::hours& hrInWeek = std::chrono::hours{maximumHoursInAWeek},
	const foundation::Days& dayInWeek = foundation::Days{maximumDaysInAWeek}
);
/**
 * @brief Adjusts a given period amount of money to another periodic amount. When converting to
 * the "never" frequency, it is considered to be a zero amount, but when converting from the
 * "never" frequency, it is considered to be what ever the amount is plus the new non-"never"
 * frequency.
 *
 * @exception Error When either the supplied from or two values are Unknown.
 * @exception logic_error When either the from or to values are not known.
 *
 * @param period The frequency period to convert to.
 * @param amount The amount of money to convert.
 * @param amountPeriod The current frequency of the amount of money.
 * @param hrInWeek The number of hours considered in a full week.
 * @param dayInWeek The number of days considered in a full week.
 *
 * @return The amount of money converted to the new frequency period.
 */
DRN_BUDGETING_EXPORT pecunia::currency::Money adjustTo(
	const EventFrequency period,
	const pecunia::currency::Money& amount,
	const EventFrequency amountPeriod,
	const std::chrono::hours& hrInWeek = std::chrono::hours{maximumHoursInAWeek},
	const foundation::Days& dayInWeek = foundation::Days{maximumDaysInAWeek}
);

}}

#endif
