/*******************************************************************************
***  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_DESKTOP_UI_INTERNAL_WAGESWIDGET_H_
#define DRN_DESKTOP_UI_INTERNAL_WAGESWIDGET_H_

#include <pecunia/Codes.h>
#include <QString>
#include <QWidget>

#include <chrono>
#include <functional>
#include <set>

#include <foundation/CalendarTime.hpp>
#include <foundation/Optional.hpp>
#include <foundation/ObserverPtr.hpp>
#include <ui_WagesWidget.h>


class QAbstractButton;
class QPushButton;

namespace drn
{
namespace budgeting
{

class BudgetSource;
struct Wage;
struct WageMap;

}
namespace desktop_ui
{
namespace internal
{

class WageEntryWidget;

/**
 * A Qt Widget that displays all the sources of wage. This object deletes itself when it closes.
 */
class WagesWidget : public ::QWidget, Ui::WagesWdgt
{
	Q_OBJECT

	foundation::Optional<foundation::ObserverPtr<internal::WageEntryWidget>> findWage(
		const std::function<bool(const internal::WageEntryWidget&)>& isMatch
	);
	void addWage(const budgeting::Wage& wage, const bool isNew);
	bool anyWageDirty() const;

	const std::chrono::hours hrInWeek_;
	const foundation::Days dayInWeek_;
	const pecunia::currency::Iso4217Codes preferred_;
	const std::set<pecunia::currency::Iso4217Codes> usableCurrencies_;
	foundation::ObserverPtr<::QPushButton> addPshbttn_;

signals:
	/// @brief Triggered when a new wage is entered.
	void added(const budgeting::Wage& wage);
	/// @brief Triggered when the name of a wage changes.
	void renamed(const budgeting::BudgetSource& original, const budgeting::BudgetSource& changed);
	/// @brief Triggered when the values of an wage changes.
	void updated(const budgeting::Wage& wage);
	/// @brief Triggered when a source of wage is removed.
	void removed(const budgeting::BudgetSource& source);
	/// @brief Triggered when the widget is in the process of being closed.
	void closing();

private slots:
	void addEntry();
	void saveWages();
	void updateTotal();
	void onClicked(foundation::ObserverPtr<::QAbstractButton> button);

public slots:
	bool close();
	void onSaveSucceeded(const budgeting::BudgetSource& source);
	void onSaveFailed(
		const foundation::Optional<budgeting::BudgetSource>& original,
		const ::QString& errorMessage,
		const foundation::Optional<budgeting::BudgetSource>& displayed
	);

public:
	WagesWidget(
		const budgeting::WageMap& wages,
		const std::chrono::hours& hrInWeek,
		const foundation::Days& dayInWeek,
		const pecunia::currency::Iso4217Codes& preferred,
		const std::set<pecunia::currency::Iso4217Codes>& usableCurrencies,
		const foundation::ObserverPtr<::QWidget>& parent
	);
};

}}}

#endif
