#ifndef GERMANAIRLINESVA_FILE_LOGBOOK_LOGBOOKENTRY_H
#define GERMANAIRLINESVA_FILE_LOGBOOK_LOGBOOKENTRY_H

#include <cstdint>
#include <fstream>
#include <string>
#include <vector>

#include "helpers.hpp"

namespace germanairlinesva
{
namespace file
{
  namespace logbook
  {
    /*
     * Preamble (25)
     * CHAR[10] | CHAR[1]     | CHAR[4]       | CHAR[4]  | CHAR[6]
     * ---------+-------------+---------------+----------+-------------
     * DATE     | FLIGHT TYPE | FLIGHT NUMBER | AIRCRAFT | REGISTRATION

     * Departure Airport Name (1...257)
     * UINT8  | CHAR[]
     * -------+-------
     * STRLEN | STRING

     * Departure Gate Name (1...257)
     * UINT8  | CHAR[]
     * -------+-------
     * STRLEN | STRING

     * Departure Runway Name (1...257)
     * UINT8  | CHAR[]
     * -------+-------
     * STRLEN | STRING

     * Arrival Airport Name (1...257)
     * UINT8  | CHAR[]
     * -------+-------
     * STRLEN | STRING

     * Arrival Gate Name (1...257)
     * UINT8  | CHAR[]
     * -------+-------
     * STRLEN | STRING

     * Arrival Runway Name (1...257)
     * UINT8  | CHAR[]
     * -------+-------
     * STRLEN | STRING

     * Times (24)
     * CHAR[5]   | CHAR[5]       | CHAR[5]      | CHAR[5]       | FLOAT
     * ----------+---------------+--------------+---------------+------
     * OFF BLOCK | TAKEOFF (OUT) | LANDING (ON) | ON BLOCK (IN) | TOTAL

     * Fuels (16)
     * FLOAT    | FLOAT     | FLOAT   | FLOAT
     * ---------+-----------+---------+------
     * TAXI OUT | IN FLIGHT | TAXI IN | TOTAL

     * Distances (16)
     * FLOAT    | FLOAT     | FLOAT   |FLOAT
     * ---------+-----------+---------+-----
     * TAXI OUT | IN FLIGHT | TAXI IN |TOTAL

     * Landing (9)
     * FLOAT    | CHAR       | FLOAT
     * ---------+----------  +------------
     * MAX RATE | TOUCHDOWNS | MAX G-FORCE

     * Recording Filename (1...257)
     * UINT8  | CHAR[]
     * -------+-------
     * STRLEN | STRING

     * Postamble (5)
     * FLOAT  | BITFIELD
     * -------+---------
     * POINTS | FLAGS

     * Flags Bitfield
     * 7   | 6   | 5   | 4   | 3    | 2    | 1      | 0
     * ----+-----+-----+-----+------+------+--------+------
     * NIL | NIL | NIL | NIL | SYNC | IVAO | VATSIM | FILED
     */
    class LogbookEntry
    {
      private:
        std::string date;
        std::string flightType;
        std::string flightNumber;
        std::string aircraftType;
        std::string aircraftRegistration;
        std::string departureAirport;
        std::string departureGate;
        std::string departureRunway;
        std::string arrivalAirport;
        std::string arrivalGate;
        std::string arrivalRunway;
        std::string offBlockTime;
        std::string outTime;
        std::string onTime;
        std::string onBlockTime;
        float totalFlightTime;
        float taxiOutFuel;
        float inFlightFuel;
        float taxiInFuel;
        float totalFuel;
        float taxiOutDistance;
        float inFlightDistance;
        float taxiInDistance;
        float totalDistance;
        float maxLandingRate;
        std::uint8_t touchdowns;
        float maxLandingGees;
        std::string recordingFilename;
        float points;
        std::uint8_t flags;

      public:
        inline LogbookEntry(std::string date,
                            std::string flightType,
                            std::string flightNumber,
                            std::string aircraftType,
                            std::string aircraftRegistration,
                            std::string departureAirport,
                            std::string departureGate,
                            std::string departureRunway,
                            std::string arrivalAirport,
                            std::string arrivalGate,
                            std::string arrivalRunway,
                            std::string offBlockTime,
                            std::string outTime,
                            std::string onTime,
                            std::string onBlockTime,
                            float totalFlightTime,
                            float taxiOutFuel,
                            float inFlightFuel,
                            float taxiInFuel,
                            float totalFuel,
                            float taxiOutDistance,
                            float inFlightDistance,
                            float taxiInDistance,
                            float totalDistance,
                            float maxLandingRate,
                            std::uint8_t touchdowns,
                            float maxLandingGees,
                            std::string recordingFilename,
                            float points,
                            std::uint8_t flags)
            : date(date), flightType(flightType), flightNumber(flightNumber),
              aircraftType(aircraftType),
              aircraftRegistration(aircraftRegistration),
              departureAirport(departureAirport), departureGate(departureGate),
              departureRunway(departureRunway), arrivalAirport(arrivalAirport),
              arrivalGate(arrivalGate), arrivalRunway(arrivalRunway),
              offBlockTime(offBlockTime), outTime(outTime), onTime(onTime),
              onBlockTime(onBlockTime), totalFlightTime(totalFlightTime),
              taxiOutFuel(taxiOutFuel), inFlightFuel(inFlightFuel),
              taxiInFuel(taxiInFuel), totalFuel(totalFuel),
              taxiOutDistance(taxiOutDistance),
              inFlightDistance(inFlightDistance),
              taxiInDistance(taxiInDistance), totalDistance(totalDistance),
              maxLandingRate(maxLandingRate), touchdowns(touchdowns),
              maxLandingGees(maxLandingGees),
              recordingFilename(recordingFilename), points(points), flags(flags)
        {
        }

        inline void toFile(std::ofstream &out) const
        {
          writeString(out, this->date, 10);
          writeString(out, this->flightType, 1);
          writeString(out, this->flightNumber, 4);
          writeString(out, this->aircraftType, 4);
          writeString(out, this->aircraftRegistration, 6);
          writeString(out, this->departureAirport);
          writeString(out, this->departureGate);
          writeString(out, this->departureRunway);
          writeString(out, this->arrivalAirport);
          writeString(out, this->arrivalGate);
          writeString(out, this->arrivalRunway);
          writeString(out, this->offBlockTime, 5);
          writeString(out, this->outTime, 5);
          writeString(out, this->onTime, 5);
          writeString(out, this->onBlockTime, 5);
          write<decltype(this->totalFlightTime)>(out, this->totalFlightTime);
          write<decltype(this->taxiOutFuel)>(out, this->taxiOutFuel);
          write<decltype(this->inFlightFuel)>(out, this->inFlightFuel);
          write<decltype(this->taxiInFuel)>(out, this->taxiInFuel);
          write<decltype(this->totalFuel)>(out, this->totalFuel);
          write<decltype(this->taxiOutDistance)>(out, this->taxiOutDistance);
          write<decltype(this->inFlightDistance)>(out, this->inFlightDistance);
          write<decltype(this->taxiInDistance)>(out, this->taxiInDistance);
          write<decltype(this->totalDistance)>(out, this->totalDistance);
          write<decltype(this->maxLandingRate)>(out, this->maxLandingRate);
          write<decltype(this->touchdowns)>(out, this->touchdowns);
          write<decltype(this->maxLandingGees)>(out, this->maxLandingGees);
          writeString(out, this->recordingFilename);
          write<decltype(this->points)>(out, this->points);
          write<decltype(this->flags)>(out, this->flags);
        }
    };
  } // namespace logbook
} // namespace file
} // namespace germanairlinesva

#endif