/*******************************************************************************
***  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/>.    ***
*******************************************************************************/
#include "BudgetItemTypes.h"
using std::array;
using std::type_index;
using drn::budgeting::BudgetItemTypes;
using drn::budgeting::numberBudgetItemTypes;

#include <QString>
using ::QString;

#include <ostream>
using std::ostream;

#include "Bill.h"
using drn::budgeting::Bill;
#include "Debt.h"
using drn::budgeting::Debt;
#include <foundation/EnumMacros.hpp>
// using BEGIN_ENUMERATION_TO_OTHER
// using BEGIN_OTHER_TO_ENUMERATION
// using MAP_ENUMERATION_TO_OTHER
// uisng MAP_OTHER_TO_ENUMERATION
// using END_OTHER_TO_ENUMERATION
// using END_OTHER_TO_ENUMERATION
#include "Goal.h"
using drn::budgeting::Goal;
#include "Nontrack.h"
using drn::budgeting::Nontrack;
#include "Wage.h"
using drn::budgeting::Wage;


ostream& drn::budgeting::operator<<(ostream& o, const BudgetItemTypes& bit)
{
	return o << "Value ("<< presentationText(bit).toStdString() << ')';
}

QString drn::budgeting::presentationText(const BudgetItemTypes& bit)
{
	BEGIN_ENUMERATION_TO_OTHER(bit);
		MAP_ENUMERATION_TO_OTHER(BudgetItemTypes::Unknown, "Unknown");
		MAP_ENUMERATION_TO_OTHER(BudgetItemTypes::Bill, "Bill");
		MAP_ENUMERATION_TO_OTHER(BudgetItemTypes::Debt, "Debt");
		MAP_ENUMERATION_TO_OTHER(BudgetItemTypes::Goal, "Goal");
		MAP_ENUMERATION_TO_OTHER(BudgetItemTypes::Nontrack, "Nontrack");
		MAP_ENUMERATION_TO_OTHER(BudgetItemTypes::Wage, "Wage");
	END_ENUMERATION_TO_OTHER(bit, BudgetItemTypes);
}

BudgetItemTypes drn::budgeting::toBudgetItemTypes(const QString& raw)
{
	BEGIN_OTHER_TO_ENUMERATION(BudgetItemTypes);
		MAP_OTHER_TO_ENUMERATION(raw, "Unknown", BudgetItemTypes::Unknown);
		MAP_OTHER_TO_ENUMERATION(raw, "Bill", BudgetItemTypes::Bill);
		MAP_OTHER_TO_ENUMERATION(raw, "Debt", BudgetItemTypes::Debt);
		MAP_OTHER_TO_ENUMERATION(raw, "Goal", BudgetItemTypes::Goal);
		MAP_OTHER_TO_ENUMERATION(raw, "Nontrack", BudgetItemTypes::Nontrack);
		MAP_OTHER_TO_ENUMERATION(raw, "Wage", BudgetItemTypes::Wage);
	END_OTHER_TO_ENUMERATION(raw, BudgetItemTypes);
}

BudgetItemTypes drn::budgeting::toBudgetItemTypes(const type_index& type)
{
	BEGIN_OTHER_TO_ENUMERATION(BudgetItemTypes);
		// N.B. Unknown is explicitly not handled as it cannot be a budget item type.
		MAP_OTHER_TO_ENUMERATION(type, typeid(Bill), BudgetItemTypes::Bill);
		MAP_OTHER_TO_ENUMERATION(type, typeid(Debt), BudgetItemTypes::Debt);
		MAP_OTHER_TO_ENUMERATION(type, typeid(Goal), BudgetItemTypes::Goal);
		MAP_OTHER_TO_ENUMERATION(type, typeid(Nontrack), BudgetItemTypes::Nontrack);
		MAP_OTHER_TO_ENUMERATION(type, typeid(Wage), BudgetItemTypes::Wage);
	END_OTHER_TO_ENUMERATION(QString::fromStdString(type.name()), BudgetItemTypes);
}

const array<BudgetItemTypes, numberBudgetItemTypes> drn::budgeting::allBudgetItemTypes{
	BudgetItemTypes::Unknown,
	BudgetItemTypes::Bill,
	BudgetItemTypes::Debt,
	BudgetItemTypes::Goal,
	BudgetItemTypes::Nontrack,
	BudgetItemTypes::Wage
};
