#pragma once
#include <initializer_list>
#include <span>
#include <string>
#include <string_view>
#include <vector>
#include <networktables/DoubleArrayTopic.h>
#include <units/length.h>
#include <wpi/SmallVector.h>
#include <wpi/mutex.h>
#include "frc/geometry/Pose2d.h"
#include "frc/geometry/Rotation2d.h"
namespace frc {
class Field2d;
class Trajectory;
class FieldObject2d {
friend class Field2d;
struct private_init {};
public:
FieldObject2d(std::string_view name, const private_init&) : m_name{name} {}
FieldObject2d(FieldObject2d&& rhs);
FieldObject2d& operator=(FieldObject2d&& rhs);
void SetPose(const Pose2d& pose);
void SetPose(units::meter_t x, units::meter_t y, Rotation2d rotation);
Pose2d GetPose() const;
void SetPoses(std::span<const Pose2d> poses);
void SetPoses(std::initializer_list<Pose2d> poses);
void SetTrajectory(const Trajectory& trajectory);
std::vector<Pose2d> GetPoses() const;
std::span<const Pose2d> GetPoses(wpi::SmallVectorImpl<Pose2d>& out) const;
private:
void UpdateEntry(bool setDefault = false);
void UpdateFromEntry() const;
mutable wpi::mutex m_mutex;
std::string m_name;
nt::DoubleArrayEntry m_entry;
mutable wpi::SmallVector<Pose2d, 1> m_poses;
};
}