#pragma once
#include "mp4.h"
#include <stdint.h>

namespace MP4{
  // class Box;

  struct afrt_runtable{
    uint32_t firstFragment;
    uint64_t firstTimestamp;
    uint32_t duration;
    uint32_t discontinuity;
  };
  // fragmentRun

  /// AFRT Box class
  class AFRT : public Box{
  public:
    AFRT();
    void setVersion(char newVersion);
    uint32_t getVersion();
    void setUpdate(uint32_t newUpdate);
    uint32_t getUpdate();
    void setTimeScale(uint32_t newScale);
    uint32_t getTimeScale();
    uint32_t getQualityEntryCount();
    void setQualityEntry(std::string &newQuality, uint32_t no);
    const char *getQualityEntry(uint32_t no);
    uint32_t getFragmentRunCount();
    void setFragmentRun(afrt_runtable newRun, uint32_t no);
    afrt_runtable getFragmentRun(uint32_t no);
    std::string toPrettyString(uint32_t indent = 0);
  };
  // AFRT Box

  struct asrt_runtable{
    uint32_t firstSegment;
    uint32_t fragmentsPerSegment;
  };

  /// ASRT Box class
  class ASRT : public Box{
  public:
    ASRT();
    void setVersion(char newVersion);
    uint32_t getVersion();
    void setUpdate(uint32_t newUpdate);
    uint32_t getUpdate();
    uint32_t getQualityEntryCount();
    void setQualityEntry(std::string &newQuality, uint32_t no);
    const char *getQualityEntry(uint32_t no);
    uint32_t getSegmentRunEntryCount();
    void setSegmentRun(uint32_t firstSegment, uint32_t fragmentsPerSegment, uint32_t no);
    asrt_runtable getSegmentRun(uint32_t no);
    std::string toPrettyString(uint32_t indent = 0);
  };
  // ASRT Box

  /// ABST Box class
  class ABST : public Box{
  public:
    ABST();
    void setVersion(char newVersion);
    char getVersion();
    void setFlags(uint32_t newFlags);
    uint32_t getFlags();
    void setBootstrapinfoVersion(uint32_t newVersion);
    uint32_t getBootstrapinfoVersion();
    void setProfile(char newProfile);
    char getProfile();
    void setLive(bool newLive);
    bool getLive();
    void setUpdate(bool newUpdate);
    bool getUpdate();
    void setTimeScale(uint32_t newTimeScale);
    uint32_t getTimeScale();
    void setCurrentMediaTime(uint64_t newTime);
    uint64_t getCurrentMediaTime();
    void setSmpteTimeCodeOffset(uint64_t newTime);
    uint64_t getSmpteTimeCodeOffset();
    void setMovieIdentifier(std::string &newIdentifier);
    char *getMovieIdentifier();
    uint32_t getServerEntryCount();
    void setServerEntry(std::string &entry, uint32_t no);
    const char *getServerEntry(uint32_t no);
    uint32_t getQualityEntryCount();
    void setQualityEntry(std::string &entry, uint32_t no);
    const char *getQualityEntry(uint32_t no);
    void setDrmData(std::string newDrm);
    char *getDrmData();
    void setMetaData(std::string newMetaData);
    char *getMetaData();
    uint32_t getSegmentRunTableCount();
    void setSegmentRunTable(ASRT &table, uint32_t no);
    ASRT &getSegmentRunTable(uint32_t no);
    uint32_t getFragmentRunTableCount();
    void setFragmentRunTable(AFRT &table, uint32_t no);
    AFRT &getFragmentRunTable(uint32_t no);
    std::string toPrettyString(uint32_t indent = 0);
  };
  // ABST Box

  struct afraentry{
    uint64_t time;
    uint64_t offset;
  };
  struct globalafraentry{
    uint64_t time;
    uint32_t segment;
    uint32_t fragment;
    uint64_t afraoffset;
    uint64_t offsetfromafra;
  };
  class AFRA : public Box{
  public:
    AFRA();
    void setVersion(uint32_t newVersion);
    uint32_t getVersion();
    void setFlags(uint32_t newFlags);
    uint32_t getFlags();
    void setLongIDs(bool newVal);
    bool getLongIDs();
    void setLongOffsets(bool newVal);
    bool getLongOffsets();
    void setGlobalEntries(bool newVal);
    bool getGlobalEntries();
    void setTimeScale(uint32_t newVal);
    uint32_t getTimeScale();
    uint32_t getEntryCount();
    void setEntry(afraentry newEntry, uint32_t no);
    afraentry getEntry(uint32_t no);
    uint32_t getGlobalEntryCount();
    void setGlobalEntry(globalafraentry newEntry, uint32_t no);
    globalafraentry getGlobalEntry(uint32_t no);
    std::string toPrettyString(uint32_t indent = 0);
  };

}// namespace MP4