#ifndef GERMANAIRLINESVA_FILE_SIMDATA_GATE_H
#define GERMANAIRLINESVA_FILE_SIMDATA_GATE_H

#include <cstdint>
#include <fstream>
#include <iostream>
#include <sstream>
#include <streambuf>
#include <string>
#include <utility>
#include <vector>

#include "geodata.hpp"
#include "helpers.hpp"

namespace germanairlinesva
{
namespace file
{
  namespace simdata
  {
    /*
     * Representation of gate
     * Center in lat/lon degrees
     * Radius in metres
     *
     * UINT8  | CHAR[]     | POINT  | UINT8
     * -------+------------+--------+-------
     * STRLEN | DESIGNATOR | CENTER | RADIUS
     */
    class Gate
    {
      private:
        std::string designator;
        struct geodata::point center;
        std::uint8_t radius;

      public:
        // From X-Plane or MakeRwys
        inline Gate(std::string designator,
                    double latitude,
                    double longitude,
                    std::uint8_t radius)
            : designator(designator), center({latitude, longitude}),
              radius(radius){};
        // From Database
        inline Gate(std::string designator,
                    struct geodata::point center,
                    std::uint8_t radius)
            : designator(designator), center(center), radius(radius){};

        inline void toFile(std::ofstream &out) const
        {
          writeString(out, this->designator);
          write<decltype(this->center)>(out, this->center);
          write<decltype(this->radius)>(out, this->radius);
        }

        inline bool contains(geodata::point coordinates) const
        {
          return geodata::distanceEarthP(this->center, coordinates);
        }

        inline const std::string to_string() const
        {
          std::ostringstream str;
          str << "Gate " << this->designator << " at " << this->center.latitude
              << "N " << this->center.longitude << "E, Radius "
              << (int)this->radius << "m";
          return str.str();
        }

        friend inline std::ostream &operator<<(std::ostream &os,
                                               const Gate &gate)
        {
          return os << gate.to_string();
        }
    };
  } // namespace simdata
} // namespace file
} // namespace germanairlinesva

#endif