/*
 * This file is part of OpenTTD.
 * OpenTTD 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, version 2.
 * OpenTTD 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 OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
 */

/** @file cargo_const.h Table of all default cargo types. */

#include "../table/sprites.h"
#ifndef CHECK_UNUSED_STRINGS
#include "table/strings.h"
#endif

/** Construction macros for the #CargoSpec StringID entries. */
#define MK_STR_CARGO_PLURAL(label_plural) STR_CARGO_PLURAL_ ## label_plural
#define MK_STR_CARGO_SINGULAR(label_singular) STR_CARGO_SINGULAR_ ## label_singular
#define MK_STR_QUANTITY(label_plural) STR_QUANTITY_ ## label_plural
#define MK_STR_ABBREV(label_plural) STR_ABBREV_ ## label_plural
/** Construction macros for the #CargoSpec SpriteID entry. */
#define MK_SPRITE(label_plural) SPR_CARGO_ ## label_plural

/**
 * Construction macro for a #CargoSpec structure.
 * The order of arguments matches the order in which they are defined in #CargoSpec.
 * Some macros are used to automatically expand to the correct StringID consts, this
 * means that adding/changing a cargo spec requires updating of the following strings:
 * - STR_CARGO_PLURAL_<str_plural>
 * - STR_CARGO_SINGULAR_<str_singular>
 * - STR_QUANTITY_<str_plural>
 * - STR_ABBREV_<str_plural>
 * And the following sprite:
 * - SPR_CARGO_<str_plural>
 *
 * @param bt           Cargo bit number, is #INVALID_CARGO_BITNUM for a non-used spec.
 * @param label        Unique label of the cargo type.
 * @param colour       CargoSpec->legend_colour and CargoSpec->rating_colour.
 * @param weight       Weight of a single unit of this cargo type in 1/16 ton (62.5 kg).
 * @param mult         Capacity multiplier for vehicles. (8 fractional bits).
 * @param ip           CargoSpec->initial_payment.
 * @param td1          CargoSpec->transit_periods[0].
 * @param td2          CargoSpec->transit_periods[1].
 * @param freight      Cargo type is considered to be freight (affects train freight multiplier).
 * @param tae          The effect that delivering this cargo type has on towns.
 * @param str_plural   The name suffix used to populate CargoSpec->name, CargoSpec->quantifier,
 *                     CargoSpec->abbrev and CargoSpec->sprite. See above for more detailed information.
 * @param str_singular The name suffix used to populate CargoSpec->name_single. See above for more information.
 * @param str_volume   Name of a single unit of cargo of this type.
 * @param classes      Classes of this cargo type. @see CargoClass
 */
#define MK(bt, label, colour, weight, mult, ip, td1, td2, freight, tae, str_plural, str_singular, str_volume, classes) \
		{label, bt, PixelColour{colour}, PixelColour{colour}, weight, mult, classes, ip, {td1, td2}, freight, tae, TownProductionEffect::Invalid, TOWN_PRODUCTION_DIVISOR, CargoCallbackMasks{}, \
		MK_STR_CARGO_PLURAL(str_plural), MK_STR_CARGO_SINGULAR(str_singular), str_volume, MK_STR_QUANTITY(str_plural), MK_STR_ABBREV(str_plural), \
		MK_SPRITE(str_plural), nullptr, nullptr, 0}

/** Cargo types available by default. */
static const CargoSpec _default_cargo[] = {
	MK(   0, CT_PASSENGERS,   152,  1, 0x400, 3185,  0,  24, false, TownAcceptanceEffect::Passengers,   PASSENGERS,    PASSENGER, STR_PASSENGERS, CargoClasses({CargoClass::Passengers})),
	MK(   1, CT_COAL,           6, 16, 0x100, 5916,  7, 255,  true,       TownAcceptanceEffect::None,         COAL,         COAL,       STR_TONS, CargoClasses({CargoClass::Bulk, CargoClass::NonPotable})),
	MK(   2, CT_MAIL,          15,  4, 0x200, 4550, 20,  90, false,       TownAcceptanceEffect::Mail,         MAIL,         MAIL,       STR_BAGS, CargoClasses({CargoClass::Mail})),
	/* Oil in temperate and arctic */
	MK(   3, CT_OIL,          174, 16, 0x100, 4437, 25, 255,  true,       TownAcceptanceEffect::None,          OIL,          OIL,     STR_LITERS, CargoClasses({CargoClass::Liquid, CargoClass::NonPotable})),
	/* Oil in subtropic */
	MK(   3, CT_OIL,          174, 16, 0x100, 4892, 25, 255,  true,       TownAcceptanceEffect::None,          OIL,          OIL,     STR_LITERS, CargoClasses({CargoClass::Liquid, CargoClass::NonPotable})),
	MK(   4, CT_LIVESTOCK,    208,  3, 0x100, 4322,  4,  18,  true,       TownAcceptanceEffect::None,    LIVESTOCK,    LIVESTOCK,      STR_ITEMS, CargoClasses({CargoClass::PieceGoods, CargoClass::NonPotable})),
	MK(   5, CT_GOODS,        194,  8, 0x200, 6144,  5,  28,  true,      TownAcceptanceEffect::Goods,        GOODS,        GOODS,     STR_CRATES, CargoClasses({CargoClass::Express})),
	MK(   6, CT_GRAIN,        191, 16, 0x100, 4778,  4,  40,  true,       TownAcceptanceEffect::None,        GRAIN,        GRAIN,       STR_TONS, CargoClasses({CargoClass::Bulk, CargoClass::Potable})),
	MK(   6, CT_WHEAT,        191, 16, 0x100, 4778,  4,  40,  true,       TownAcceptanceEffect::None,        WHEAT,        WHEAT,       STR_TONS, CargoClasses({CargoClass::Bulk, CargoClass::Potable})),
	MK(   6, CT_MAIZE,        191, 16, 0x100, 4322,  4,  40,  true,       TownAcceptanceEffect::None,        MAIZE,        MAIZE,       STR_TONS, CargoClasses({CargoClass::Bulk, CargoClass::Potable})),
	/* Wood in temperate and arctic */
	MK(   7, CT_WOOD,          84, 16, 0x100, 5005, 15, 255,  true,       TownAcceptanceEffect::None,         WOOD,         WOOD,       STR_TONS, CargoClasses({CargoClass::PieceGoods})),
	/* Wood in subtropic */
	MK(   7, CT_WOOD,          84, 16, 0x100, 7964, 15, 255,  true,       TownAcceptanceEffect::None,         WOOD,         WOOD,       STR_TONS, CargoClasses({CargoClass::PieceGoods})),
	MK(   8, CT_IRON_ORE,     184, 16, 0x100, 5120,  9, 255,  true,       TownAcceptanceEffect::None,     IRON_ORE,     IRON_ORE,       STR_TONS, CargoClasses({CargoClass::Bulk, CargoClass::NonPotable})),
	MK(   9, CT_STEEL,         10, 16, 0x100, 5688,  7, 255,  true,       TownAcceptanceEffect::None,        STEEL,        STEEL,       STR_TONS, CargoClasses({CargoClass::PieceGoods})),
	MK(  10, CT_VALUABLES,    202,  2, 0x100, 7509,  1,  32,  true,       TownAcceptanceEffect::None,    VALUABLES,    VALUABLES,       STR_BAGS, CargoClasses({CargoClass::Armoured})),
	MK(  10, CT_GOLD,         202,  8, 0x100, 5802, 10,  40,  true,       TownAcceptanceEffect::None,         GOLD,         GOLD,       STR_BAGS, CargoClasses({CargoClass::Armoured})),
	MK(  10, CT_DIAMONDS,     202,  2, 0x100, 5802, 10, 255,  true,       TownAcceptanceEffect::None,     DIAMONDS,      DIAMOND,       STR_BAGS, CargoClasses({CargoClass::Armoured})),
	MK(  11, CT_PAPER,         10, 16, 0x100, 5461,  7,  60,  true,       TownAcceptanceEffect::None,        PAPER,        PAPER,       STR_TONS, CargoClasses({CargoClass::PieceGoods})),
	MK(  12, CT_FOOD,          48, 16, 0x100, 5688,  0,  30,  true,       TownAcceptanceEffect::Food,         FOOD,         FOOD,       STR_TONS, CargoClasses({CargoClass::Express, CargoClass::Refrigerated, CargoClass::Potable})),
	MK(  13, CT_FRUIT,        208, 16, 0x100, 4209,  0,  15,  true,       TownAcceptanceEffect::None,        FRUIT,        FRUIT,       STR_TONS, CargoClasses({CargoClass::Bulk, CargoClass::Refrigerated, CargoClass::Potable})),
	MK(  14, CT_COPPER_ORE,   184, 16, 0x100, 4892, 12, 255,  true,       TownAcceptanceEffect::None,   COPPER_ORE,   COPPER_ORE,       STR_TONS, CargoClasses({CargoClass::Bulk, CargoClass::NonPotable})),
	MK(  15, CT_WATER,         10, 16, 0x100, 4664, 20,  80,  true,      TownAcceptanceEffect::Water,        WATER,        WATER,     STR_LITERS, CargoClasses({CargoClass::Liquid, CargoClass::Potable})),
	MK(  16, CT_RUBBER,         6, 16, 0x100, 4437,  2,  20,  true,       TownAcceptanceEffect::None,       RUBBER,       RUBBER,     STR_LITERS, CargoClasses({CargoClass::Liquid, CargoClass::NonPotable})),
	MK(  17, CT_SUGAR,          6, 16, 0x100, 4437, 20, 255,  true,       TownAcceptanceEffect::None,        SUGAR,        SUGAR,       STR_TONS, CargoClasses({CargoClass::Bulk, CargoClass::Potable})),
	MK(  18, CT_TOYS,         174,  2, 0x100, 5574, 25, 255,  true,       TownAcceptanceEffect::None,         TOYS,          TOY,      STR_ITEMS, CargoClasses({CargoClass::PieceGoods})),
	MK(  19, CT_BATTERIES,    208,  4, 0x100, 4322,  2,  30,  true,       TownAcceptanceEffect::None,    BATTERIES,      BATTERY,      STR_ITEMS, CargoClasses({CargoClass::PieceGoods})),
	MK(  20, CT_CANDY,        194,  5, 0x200, 6144,  8,  40,  true,      TownAcceptanceEffect::Goods,       SWEETS,       SWEETS,       STR_BAGS, CargoClasses({CargoClass::Express})),
	MK(  21, CT_TOFFEE,       191, 16, 0x100, 4778, 14,  60,  true,       TownAcceptanceEffect::None,       TOFFEE,       TOFFEE,       STR_TONS, CargoClasses({CargoClass::Bulk})),
	MK(  22, CT_COLA,          84, 16, 0x100, 4892,  5,  75,  true,       TownAcceptanceEffect::None,         COLA,         COLA,     STR_LITERS, CargoClasses({CargoClass::Liquid})),
	MK(  23, CT_COTTON_CANDY, 184, 16, 0x100, 5005, 10,  25,  true,       TownAcceptanceEffect::None,   CANDYFLOSS,   CANDYFLOSS,       STR_TONS, CargoClasses({CargoClass::Bulk})),
	MK(  24, CT_BUBBLES,       10,  1, 0x100, 5077, 20,  80,  true,       TownAcceptanceEffect::None,      BUBBLES,       BUBBLE,      STR_ITEMS, CargoClasses({CargoClass::PieceGoods})),
	MK(  25, CT_PLASTIC,      202, 16, 0x100, 4664, 30, 255,  true,       TownAcceptanceEffect::None,      PLASTIC,      PLASTIC,     STR_LITERS, CargoClasses({CargoClass::Liquid})),
	MK(  26, CT_FIZZY_DRINKS,  48,  2, 0x100, 6250, 30,  50,  true,       TownAcceptanceEffect::Food, FIZZY_DRINKS,  FIZZY_DRINK,      STR_ITEMS, CargoClasses({CargoClass::PieceGoods})),

	/* Void slot in temperate */
	MK(0xFF, CT_INVALID,        1,  0, 0x100, 5688,  0,  30,  true,       TownAcceptanceEffect::None,      NOTHING,      NOTHING,       STR_TONS, CargoClasses({})),
	/* Void slot in arctic */
	MK(0xFF, CT_INVALID,      184,  0, 0x100, 5120,  9, 255,  true,       TownAcceptanceEffect::None,      NOTHING,      NOTHING,       STR_TONS, CargoClasses({})),
};


/** Table of cargo types available in each climate, by default */
static const std::variant<CargoLabel, int> _default_climate_cargo[NUM_LANDSCAPE][NUM_ORIGINAL_CARGO] = {
	{ CT_PASSENGERS, CT_COAL,   CT_MAIL, CT_OIL,  CT_LIVESTOCK, CT_GOODS, CT_GRAIN,  CT_WOOD, CT_IRON_ORE,     CT_STEEL,   CT_VALUABLES, 33, },
	{ CT_PASSENGERS, CT_COAL,   CT_MAIL, CT_OIL,  CT_LIVESTOCK, CT_GOODS, CT_WHEAT,  CT_WOOD, 34,              CT_PAPER,   CT_GOLD,      CT_FOOD, },
	{ CT_PASSENGERS, CT_RUBBER, CT_MAIL, 4,       CT_FRUIT,     CT_GOODS, CT_MAIZE,  11,      CT_COPPER_ORE,   CT_WATER,   CT_DIAMONDS,  CT_FOOD, },
	{ CT_PASSENGERS, CT_SUGAR,  CT_MAIL, CT_TOYS, CT_BATTERIES, CT_CANDY, CT_TOFFEE, CT_COLA, CT_COTTON_CANDY, CT_BUBBLES, CT_PLASTIC,   CT_FIZZY_DRINKS, },
};

