#pragma once
#include <cstdint>
#include <string>
#include <unordered_map>
#include <variant>
#include <vector>
/// Supported storage and form behavior for a custom game field.
enum class GameFieldType
{
INTEGER,
STRING,
CHOICE
};
/// Application visibility assigned to a database-defined game.
enum class GameVisibility
{
PUBLIC = 0,
INTERNAL = 1
};
/// Visibility boundary for data derived from database-defined games.
enum class GameContentScope
{
PUBLIC_ONLY,
INCLUDE_INTERNAL
};
/// One database-defined game.
struct Game
{
/// Permanent lowercase public card-ID prefix.
std::string short_name;
/// Human-readable game name.
std::string display_name;
/// Markdown game description.
std::string description;
/// Application visibility for this game and its derived content.
GameVisibility visibility;
/// Aggregate optimistic-concurrency revision.
std::int64_t revision;
};
/// One allowed value for a choice field.
struct GameChoice
{
/// Exact stored and displayed choice text.
std::string value;
/// Zero-based display position.
std::int64_t position;
};
/// One ordered custom field belonging to a game.
struct GameField
{
/// Internal database identity.
std::int64_t id;
/// Permanent owning game short name.
std::string game_short_name;
/// Permanent key used in submitted form names.
std::string key;
/// Human-readable field label.
std::string label;
/// Field value type.
GameFieldType type;
/// Zero-based display position.
std::int64_t position;
/// Ordered allowed values, populated only for choice fields.
std::vector<GameChoice> choices;
};
/// Consistent owning snapshot of a game and all its field definitions.
struct GameDefinitionSnapshot
{
/// Database-defined game metadata.
Game game;
/// Fields ordered by position and stable identity.
std::vector<GameField> fields;
};
/// Decoded storage value for one custom field.
struct GameFieldValue
{
/// Referenced field identity.
std::int64_t field_id;
/// Field discriminator retained for database constraint checks.
GameFieldType type;
/// Parsed integer or exact string/choice text.
std::variant<std::int64_t, std::string> value;
};
/// One card's values paired with a consistent owning game definition.
struct CardGameFields
{
/// Definition used to interpret and present the stored values.
GameDefinitionSnapshot definition;
/// Set values ordered by their fields' display positions.
std::vector<GameFieldValue> values;
};
/// Counts that determine whether a database-defined game can be deleted.
struct GameUsage
{
/// Cards that use the game.
std::int64_t card_count;
/// Series that use the game.
std::int64_t series_count;
/// Highest public card number ever allocated for the game.
std::int64_t last_number;
};
/// Unique custom-field form values keyed by permanent field key.
using SubmittedGameFields =
std::unordered_map<std::string, std::string>;
/// Dynamic series metadata belonging to one database-defined game.
struct Series
{
/// Internal SQLite primary key, or zero before insertion.
std::int64_t id;
/// Lowercase short name of the owning database-defined game.
std::string game_short_name;
/// Series name, unique within its game.
std::string name;
/// Markdown series description.
std::string description;
};