#pragma once

#include <optional>
#include <vector>

#include <QRect>

#include "entt/entity/entity.hpp"

#include "BuildingId.h"

class EntityAdmin;
class Simulation;
class WorldCoordinates;
struct FactoryState;

// Where selectable objects are on the screen. The world renderer draws every selection
// outline from these rectangles, and the selection panel is placed beside the one that
// covers the whole selection (REQ-UI-SELECTION-PANEL).
//
// All of them are in the game world view's own widget coordinates, and all of them are
// only true for the WorldCoordinates they were asked for: the transform is a value built
// per frame or per event, so a rectangle does not survive a scroll or a resize.

// The footprint of a building or of a construction site (REQ-UI-SELECTION-CARD). Null
// when the id names neither, which is what a deconstruction under the caller looks like.
std::optional<QRectF> getBuildingWidgetRect(const FactoryState& state,
                                            const WorldCoordinates& coordinates,
                                            BuildingId id);

// The body of a ship or of a defence station (REQ-UI-ENTITY-CLICK-SELECT): a station's
// footprint, or the square the ship's triangle is drawn in.
std::optional<QRectF> getActorWidgetRect(const EntityAdmin& admin,
                                         const WorldCoordinates& coordinates,
                                         entt::entity actor);

// The circle a piece of debris is drawn as (REQ-UI-DEBRIS-CLICK-SELECT).
std::optional<QRectF> getDebrisWidgetRect(const EntityAdmin& admin,
                                          const WorldCoordinates& coordinates,
                                          entt::entity debris);

// The rectangle covering a whole selection -- one object, or the bounding box of all of
// them (REQ-UI-SELECTION-PANEL). Objects that no longer resolve are skipped; the result
// is null when none of them does.
QRect getSelectionWidgetRect(const Simulation& sim, const WorldCoordinates& coordinates,
                             const std::vector<BuildingId>& buildings,
                             const std::vector<entt::entity>& actors,
                             const std::vector<entt::entity>& debris);
