#ifndef GERMANAIRLINESVA_GACONNECTOR_RUNWAY_H
#define GERMANAIRLINESVA_GACONNECTOR_RUNWAY_H

#include <iomanip>
#include <iostream>
#include <regex>
#include <sstream>
#include <string>
#include <utility>

#include "geodata.h"
#include "util.hpp"

namespace germanairlinesva_simdata
{
  /*
   * Representation of one runway with supplementary information
   * Heading in degrees (0...360) true
   * Width and length in meters
   *
   * Designator must be null terminated
   *
   * UINT8  | CHAR[]     | BOX    | UINT8 | UINT16 | UINT16
   * -------+------------+--------+-------+--------+-------
   * STRLEN | DESIGNATOR | BOUNDS | WIDTH | LENGTH | TRUHDG
   */
  class Runway
  {
    private:
      std::string designator;
      struct germanairlinesva_geodata::box bounds;
      std::uint8_t width;
      std::uint16_t length;
      std::uint16_t trueHeading;
      std::vector<std::uint8_t> file;

    public:
      // From X-Plane or MakeRwys
      Runway(std::string designator,
             double latitudeStart,
             double longitudeStart,
             double latitudeEnd,
             double longitudeEnd,
             double width);
      // From database
      Runway(std::string designator,
             struct germanairlinesva_geodata::box bounds,
             std::uint8_t width,
             std::uint16_t length,
             std::uint16_t trueHeading);

      inline std::uint8_t *getBinaryData() { return file.data(); }
      inline std::size_t getBinaryLength() { return file.size(); }

      std::string to_string() const
      {
        std::ostringstream str;
        str << "Runway " << this->designator << " with bounds "
            << this->bounds.topLeft.latitude << "N "
            << this->bounds.topLeft.longitude << "E, "
            << this->bounds.topRight.latitude << "N "
            << this->bounds.topRight.longitude << "E, "
            << this->bounds.bottomRight.latitude << "N "
            << this->bounds.bottomRight.longitude << "E, "
            << this->bounds.bottomLeft.latitude << "N "
            << this->bounds.bottomLeft.longitude << "E, "
            << "Width " << (int)this->width << "m, Length " << this->length
            << "m, True Heading " << this->trueHeading << "°";
        return str.str();
      }

      friend inline std::ostream &operator<<(std::ostream &os,
                                             const Runway &runway)
      {
        return os << runway.to_string();
      }
  };


} // namespace germanairlinesva_simdata

#endif