// Copyright (c) 2012 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
#ifndef MKVPARSER_MKVPARSER_H_
#define MKVPARSER_MKVPARSER_H_

#include <cstddef>

namespace mkvparser {

const int E_PARSE_FAILED = -1;
const int E_FILE_FORMAT_INVALID = -2;
const int E_BUFFER_NOT_FULL = -3;

class IMkvReader {
 public:
  virtual int Read(long long pos, long len, unsigned char* buf) = 0;
  virtual int Length(long long* total, long long* available) = 0;

 protected:
  virtual ~IMkvReader() {}
};

template <typename Type>
Type* SafeArrayAlloc(unsigned long long num_elements, unsigned long long element_size);
long long GetUIntLength(IMkvReader*, long long, long&);
long long ReadUInt(IMkvReader*, long long, long&);
long long ReadID(IMkvReader* pReader, long long pos, long& len);
long long UnserializeUInt(IMkvReader*, long long pos, long long size);

long UnserializeFloat(IMkvReader*, long long pos, long long size, double&);
long UnserializeInt(IMkvReader*, long long pos, long long size, long long& result);

long UnserializeString(IMkvReader*, long long pos, long long size, char*& str);

long ParseElementHeader(IMkvReader* pReader,
                        long long& pos,  // consume id and size fields
                        long long stop,  // if you know size of element's parent
                        long long& id, long long& size);

bool Match(IMkvReader*, long long&, unsigned long, long long&);
bool Match(IMkvReader*, long long&, unsigned long, unsigned char*&, size_t&);

void GetVersion(int& major, int& minor, int& build, int& revision);

struct EBMLHeader {
  EBMLHeader();
  ~EBMLHeader();
  long long m_version;
  long long m_readVersion;
  long long m_maxIdLength;
  long long m_maxSizeLength;
  char* m_docType;
  long long m_docTypeVersion;
  long long m_docTypeReadVersion;

  long long Parse(IMkvReader*, long long&);
  void Init();
};

class Segment;
class Track;
class Cluster;

class Block {
  Block(const Block&);
  Block& operator=(const Block&);

 public:
  const long long m_start;
  const long long m_size;

  Block(long long start, long long size, long long discard_padding);
  ~Block();

  long Parse(const Cluster*);

  long long GetTrackNumber() const;
  long long GetTimeCode(const Cluster*) const;  // absolute, but not scaled
  long long GetTime(const Cluster*) const;      // absolute, and scaled (ns)
  bool IsKey() const;
  void SetKey(bool);
  bool IsInvisible() const;

  enum Lacing { kLacingNone, kLacingXiph, kLacingFixed, kLacingEbml };
  Lacing GetLacing() const;

  int GetFrameCount() const;  // to index frames: [0, count)

  struct Frame {
    long long pos;  // absolute offset
    long len;

    long Read(IMkvReader*, unsigned char*) const;
  };

  const Frame& GetFrame(int frame_index) const;

  long long GetDiscardPadding() const;

 private:
  long long m_track;  // Track::Number()
  short m_timecode;   // relative to cluster
  unsigned char m_flags;

  Frame* m_frames;
  int m_frame_count;

 protected:
  const long long m_discard_padding;
};

class BlockEntry {
  BlockEntry(const BlockEntry&);
  BlockEntry& operator=(const BlockEntry&);

 protected:
  BlockEntry(Cluster*, long index);

 public:
  virtual ~BlockEntry();

  bool EOS() const { return (GetKind() == kBlockEOS); }
  const Cluster* GetCluster() const;
  long GetIndex() const;
  virtual const Block* GetBlock() const = 0;

  enum Kind { kBlockEOS, kBlockSimple, kBlockGroup };
  virtual Kind GetKind() const = 0;

 protected:
  Cluster* const m_pCluster;
  const long m_index;
};

class SimpleBlock : public BlockEntry {
  SimpleBlock(const SimpleBlock&);
  SimpleBlock& operator=(const SimpleBlock&);

 public:
  SimpleBlock(Cluster*, long index, long long start, long long size);
  long Parse();

  Kind GetKind() const;
  const Block* GetBlock() const;

 protected:
  Block m_block;
};

class BlockGroup : public BlockEntry {
  BlockGroup(const BlockGroup&);
  BlockGroup& operator=(const BlockGroup&);

 public:
  BlockGroup(Cluster*, long index,
             long long block_start,  // absolute pos of block's payload
             long long block_size,   // size of block's payload
             long long prev, long long next, long long duration, long long discard_padding);

  long Parse();

  Kind GetKind() const;
  const Block* GetBlock() const;

  long long GetPrevTimeCode() const;  // relative to block's time
  long long GetNextTimeCode() const;  // as above
  long long GetDurationTimeCode() const;

 private:
  Block m_block;
  const long long m_prev;
  const long long m_next;
  const long long m_duration;
};

///////////////////////////////////////////////////////////////
// ContentEncoding element
// Elements used to describe if the track data has been encrypted or
// compressed with zlib or header stripping.
class ContentEncoding {
 public:
  enum { kCTR = 1 };

  ContentEncoding();
  ~ContentEncoding();

  // ContentCompression element names
  struct ContentCompression {
    ContentCompression();
    ~ContentCompression();

    unsigned long long algo;
    unsigned char* settings;
    long long settings_len;
  };

  // ContentEncAESSettings element names
  struct ContentEncAESSettings {
    ContentEncAESSettings() : cipher_mode(kCTR) {}
    ~ContentEncAESSettings() {}

    unsigned long long cipher_mode;
  };

  // ContentEncryption element names
  struct ContentEncryption {
    ContentEncryption();
    ~ContentEncryption();

    unsigned long long algo;
    unsigned char* key_id;
    long long key_id_len;
    unsigned char* signature;
    long long signature_len;
    unsigned char* sig_key_id;
    long long sig_key_id_len;
    unsigned long long sig_algo;
    unsigned long long sig_hash_algo;

    ContentEncAESSettings aes_settings;
  };

  // Returns ContentCompression represented by |idx|. Returns NULL if |idx|
  // is out of bounds.
  const ContentCompression* GetCompressionByIndex(unsigned long idx) const;

  // Returns number of ContentCompression elements in this ContentEncoding
  // element.
  unsigned long GetCompressionCount() const;

  // Parses the ContentCompression element from |pReader|. |start| is the
  // starting offset of the ContentCompression payload. |size| is the size in
  // bytes of the ContentCompression payload. |compression| is where the parsed
  // values will be stored.
  long ParseCompressionEntry(long long start, long long size, IMkvReader* pReader, ContentCompression* compression);

  // Returns ContentEncryption represented by |idx|. Returns NULL if |idx|
  // is out of bounds.
  const ContentEncryption* GetEncryptionByIndex(unsigned long idx) const;

  // Returns number of ContentEncryption elements in this ContentEncoding
  // element.
  unsigned long GetEncryptionCount() const;

  // Parses the ContentEncAESSettings element from |pReader|. |start| is the
  // starting offset of the ContentEncAESSettings payload. |size| is the
  // size in bytes of the ContentEncAESSettings payload. |encryption| is
  // where the parsed values will be stored.
  long ParseContentEncAESSettingsEntry(long long start, long long size, IMkvReader* pReader,
                                       ContentEncAESSettings* aes);

  // Parses the ContentEncoding element from |pReader|. |start| is the
  // starting offset of the ContentEncoding payload. |size| is the size in
  // bytes of the ContentEncoding payload. Returns true on success.
  long ParseContentEncodingEntry(long long start, long long size, IMkvReader* pReader);

  // Parses the ContentEncryption element from |pReader|. |start| is the
  // starting offset of the ContentEncryption payload. |size| is the size in
  // bytes of the ContentEncryption payload. |encryption| is where the parsed
  // values will be stored.
  long ParseEncryptionEntry(long long start, long long size, IMkvReader* pReader, ContentEncryption* encryption);

  unsigned long long encoding_order() const { return encoding_order_; }
  unsigned long long encoding_scope() const { return encoding_scope_; }
  unsigned long long encoding_type() const { return encoding_type_; }

 private:
  // Member variables for list of ContentCompression elements.
  ContentCompression** compression_entries_;
  ContentCompression** compression_entries_end_;

  // Member variables for list of ContentEncryption elements.
  ContentEncryption** encryption_entries_;
  ContentEncryption** encryption_entries_end_;

  // ContentEncoding element names
  unsigned long long encoding_order_;
  unsigned long long encoding_scope_;
  unsigned long long encoding_type_;

  // LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding);
  ContentEncoding(const ContentEncoding&);
  ContentEncoding& operator=(const ContentEncoding&);
};

class Track {
  Track(const Track&);
  Track& operator=(const Track&);

 public:
  class Info;
  static long Create(Segment*, const Info&, long long element_start, long long element_size, Track*&);

  enum Type { kVideo = 1, kAudio = 2, kSubtitle = 0x11, kMetadata = 0x21 };

  Segment* const m_pSegment;
  const long long m_element_start;
  const long long m_element_size;
  virtual ~Track();

  long GetType() const;
  long GetNumber() const;
  unsigned long long GetUid() const;
  const char* GetNameAsUTF8() const;
  const char* GetLanguage() const;
  const char* GetCodecNameAsUTF8() const;
  const char* GetCodecId() const;
  const unsigned char* GetCodecPrivate(size_t&) const;
  bool GetLacing() const;
  unsigned long long GetDefaultDuration() const;
  unsigned long long GetCodecDelay() const;
  unsigned long long GetSeekPreRoll() const;

  const BlockEntry* GetEOS() const;

  struct Settings {
    long long start;
    long long size;
  };

  class Info {
   public:
    Info();
    ~Info();
    int Copy(Info&) const;
    void Clear();
    long type;
    long number;
    unsigned long long uid;
    unsigned long long defaultDuration;
    unsigned long long codecDelay;
    unsigned long long seekPreRoll;
    char* nameAsUTF8;
    char* language;
    char* codecId;
    char* codecNameAsUTF8;
    unsigned char* codecPrivate;
    size_t codecPrivateSize;
    bool lacing;
    Settings settings;

   private:
    Info(const Info&);
    Info& operator=(const Info&);
    int CopyStr(char* Info::*str, Info&) const;
  };

  long GetFirst(const BlockEntry*&) const;
  long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const;
  virtual bool VetEntry(const BlockEntry*) const;
  virtual long Seek(long long time_ns, const BlockEntry*&) const;

  const ContentEncoding* GetContentEncodingByIndex(unsigned long idx) const;
  unsigned long GetContentEncodingCount() const;

  long ParseContentEncodingsEntry(long long start, long long size);

 protected:
  Track(Segment*, long long element_start, long long element_size);

  Info m_info;

  class EOSBlock : public BlockEntry {
   public:
    EOSBlock();

    Kind GetKind() const;
    const Block* GetBlock() const;
  };

  EOSBlock m_eos;

 private:
  ContentEncoding** content_encoding_entries_;
  ContentEncoding** content_encoding_entries_end_;
};

struct PrimaryChromaticity {
  PrimaryChromaticity() : x(0), y(0) {}
  ~PrimaryChromaticity() {}
  static bool Parse(IMkvReader* reader, long long read_pos, long long value_size, bool is_x,
                    PrimaryChromaticity** chromaticity);
  float x;
  float y;
};

struct MasteringMetadata {
  static const float kValueNotPresent;

  MasteringMetadata()
      : r(NULL),
        g(NULL),
        b(NULL),
        white_point(NULL),
        luminance_max(kValueNotPresent),
        luminance_min(kValueNotPresent) {}
  ~MasteringMetadata() {
    delete r;
    delete g;
    delete b;
    delete white_point;
  }

  static bool Parse(IMkvReader* reader, long long element_start, long long element_size,
                    MasteringMetadata** mastering_metadata);

  PrimaryChromaticity* r;
  PrimaryChromaticity* g;
  PrimaryChromaticity* b;
  PrimaryChromaticity* white_point;
  float luminance_max;
  float luminance_min;
};

struct Colour {
  static const long long kValueNotPresent;

  // Unless otherwise noted all values assigned upon construction are the
  // equivalent of unspecified/default.
  Colour()
      : matrix_coefficients(kValueNotPresent),
        bits_per_channel(kValueNotPresent),
        chroma_subsampling_horz(kValueNotPresent),
        chroma_subsampling_vert(kValueNotPresent),
        cb_subsampling_horz(kValueNotPresent),
        cb_subsampling_vert(kValueNotPresent),
        chroma_siting_horz(kValueNotPresent),
        chroma_siting_vert(kValueNotPresent),
        range(kValueNotPresent),
        transfer_characteristics(kValueNotPresent),
        primaries(kValueNotPresent),
        max_cll(kValueNotPresent),
        max_fall(kValueNotPresent),
        mastering_metadata(NULL) {}
  ~Colour() {
    delete mastering_metadata;
    mastering_metadata = NULL;
  }

  static bool Parse(IMkvReader* reader, long long element_start, long long element_size, Colour** colour);

  long long matrix_coefficients;
  long long bits_per_channel;
  long long chroma_subsampling_horz;
  long long chroma_subsampling_vert;
  long long cb_subsampling_horz;
  long long cb_subsampling_vert;
  long long chroma_siting_horz;
  long long chroma_siting_vert;
  long long range;
  long long transfer_characteristics;
  long long primaries;
  long long max_cll;
  long long max_fall;

  MasteringMetadata* mastering_metadata;
};

struct Projection {
  enum ProjectionType {
    kTypeNotPresent = -1,
    kRectangular = 0,
    kEquirectangular = 1,
    kCubeMap = 2,
    kMesh = 3,
  };
  static const float kValueNotPresent;
  Projection()
      : type(kTypeNotPresent),
        private_data(NULL),
        private_data_length(0),
        pose_yaw(kValueNotPresent),
        pose_pitch(kValueNotPresent),
        pose_roll(kValueNotPresent) {}
  ~Projection() { delete[] private_data; }
  static bool Parse(IMkvReader* reader, long long element_start, long long element_size, Projection** projection);

  ProjectionType type;
  unsigned char* private_data;
  size_t private_data_length;
  float pose_yaw;
  float pose_pitch;
  float pose_roll;
};

class VideoTrack : public Track {
  VideoTrack(const VideoTrack&);
  VideoTrack& operator=(const VideoTrack&);

  VideoTrack(Segment*, long long element_start, long long element_size);

 public:
  virtual ~VideoTrack();
  static long Parse(Segment*, const Info&, long long element_start, long long element_size, VideoTrack*&);

  long long GetWidth() const;
  long long GetHeight() const;
  long long GetDisplayWidth() const;
  long long GetDisplayHeight() const;
  long long GetDisplayUnit() const;
  long long GetStereoMode() const;
  double GetFrameRate() const;

  bool VetEntry(const BlockEntry*) const;
  long Seek(long long time_ns, const BlockEntry*&) const;

  Colour* GetColour() const;

  Projection* GetProjection() const;

  const char* GetColourSpace() const { return m_colour_space; }

 private:
  long long m_width;
  long long m_height;
  long long m_display_width;
  long long m_display_height;
  long long m_display_unit;
  long long m_stereo_mode;
  char* m_colour_space;
  double m_rate;

  Colour* m_colour;
  Projection* m_projection;
};

class AudioTrack : public Track {
  AudioTrack(const AudioTrack&);
  AudioTrack& operator=(const AudioTrack&);

  AudioTrack(Segment*, long long element_start, long long element_size);

 public:
  static long Parse(Segment*, const Info&, long long element_start, long long element_size, AudioTrack*&);

  double GetSamplingRate() const;
  long long GetChannels() const;
  long long GetBitDepth() const;

 private:
  double m_rate;
  long long m_channels;
  long long m_bitDepth;
};

class Tracks {
  Tracks(const Tracks&);
  Tracks& operator=(const Tracks&);

 public:
  Segment* const m_pSegment;
  const long long m_start;
  const long long m_size;
  const long long m_element_start;
  const long long m_element_size;

  Tracks(Segment*, long long start, long long size, long long element_start, long long element_size);

  ~Tracks();

  long Parse();

  unsigned long GetTracksCount() const;

  const Track* GetTrackByNumber(long tn) const;
  const Track* GetTrackByIndex(unsigned long idx) const;

 private:
  Track** m_trackEntries;
  Track** m_trackEntriesEnd;

  long ParseTrackEntry(long long payload_start, long long payload_size, long long element_start, long long element_size,
                       Track*&) const;
};

class Chapters {
  Chapters(const Chapters&);
  Chapters& operator=(const Chapters&);

 public:
  Segment* const m_pSegment;
  const long long m_start;
  const long long m_size;
  const long long m_element_start;
  const long long m_element_size;

  Chapters(Segment*, long long payload_start, long long payload_size, long long element_start, long long element_size);

  ~Chapters();

  long Parse();

  class Atom;
  class Edition;

  class Display {
    friend class Atom;
    Display();
    Display(const Display&);
    ~Display();
    Display& operator=(const Display&);

   public:
    const char* GetString() const;
    const char* GetLanguage() const;
    const char* GetCountry() const;

   private:
    void Init();
    void ShallowCopy(Display&) const;
    void Clear();
    long Parse(IMkvReader*, long long pos, long long size);

    char* m_string;
    char* m_language;
    char* m_country;
  };

  class Atom {
    friend class Edition;
    Atom();
    Atom(const Atom&);
    ~Atom();
    Atom& operator=(const Atom&);

   public:
    unsigned long long GetUID() const;
    const char* GetStringUID() const;

    long long GetStartTimecode() const;
    long long GetStopTimecode() const;

    long long GetStartTime(const Chapters*) const;
    long long GetStopTime(const Chapters*) const;

    int GetDisplayCount() const;
    const Display* GetDisplay(int index) const;

   private:
    void Init();
    void ShallowCopy(Atom&) const;
    void Clear();
    long Parse(IMkvReader*, long long pos, long long size);
    static long long GetTime(const Chapters*, long long timecode);

    long ParseDisplay(IMkvReader*, long long pos, long long size);
    bool ExpandDisplaysArray();

    char* m_string_uid;
    unsigned long long m_uid;
    long long m_start_timecode;
    long long m_stop_timecode;

    Display* m_displays;
    int m_displays_size;
    int m_displays_count;
  };

  class Edition {
    friend class Chapters;
    Edition();
    Edition(const Edition&);
    ~Edition();
    Edition& operator=(const Edition&);

   public:
    int GetAtomCount() const;
    const Atom* GetAtom(int index) const;

   private:
    void Init();
    void ShallowCopy(Edition&) const;
    void Clear();
    long Parse(IMkvReader*, long long pos, long long size);

    long ParseAtom(IMkvReader*, long long pos, long long size);
    bool ExpandAtomsArray();

    Atom* m_atoms;
    int m_atoms_size;
    int m_atoms_count;
  };

  int GetEditionCount() const;
  const Edition* GetEdition(int index) const;

 private:
  long ParseEdition(long long pos, long long size);
  bool ExpandEditionsArray();

  Edition* m_editions;
  int m_editions_size;
  int m_editions_count;
};

class Tags {
  Tags(const Tags&);
  Tags& operator=(const Tags&);

 public:
  Segment* const m_pSegment;
  const long long m_start;
  const long long m_size;
  const long long m_element_start;
  const long long m_element_size;

  Tags(Segment*, long long payload_start, long long payload_size, long long element_start, long long element_size);

  ~Tags();

  long Parse();

  class Tag;
  class SimpleTag;

  class SimpleTag {
    friend class Tag;
    SimpleTag();
    SimpleTag(const SimpleTag&);
    ~SimpleTag();
    SimpleTag& operator=(const SimpleTag&);

   public:
    const char* GetTagName() const;
    const char* GetTagString() const;

   private:
    void Init();
    void ShallowCopy(SimpleTag&) const;
    void Clear();
    long Parse(IMkvReader*, long long pos, long long size);

    char* m_tag_name;
    char* m_tag_string;
  };

  class Tag {
    friend class Tags;
    Tag();
    Tag(const Tag&);
    ~Tag();
    Tag& operator=(const Tag&);

   public:
    int GetSimpleTagCount() const;
    const SimpleTag* GetSimpleTag(int index) const;

   private:
    void Init();
    void ShallowCopy(Tag&) const;
    void Clear();
    long Parse(IMkvReader*, long long pos, long long size);

    long ParseSimpleTag(IMkvReader*, long long pos, long long size);
    bool ExpandSimpleTagsArray();

    SimpleTag* m_simple_tags;
    int m_simple_tags_size;
    int m_simple_tags_count;
  };

  int GetTagCount() const;
  const Tag* GetTag(int index) const;

 private:
  long ParseTag(long long pos, long long size);
  bool ExpandTagsArray();

  Tag* m_tags;
  int m_tags_size;
  int m_tags_count;
};

class SegmentInfo {
  SegmentInfo(const SegmentInfo&);
  SegmentInfo& operator=(const SegmentInfo&);

 public:
  Segment* const m_pSegment;
  const long long m_start;
  const long long m_size;
  const long long m_element_start;
  const long long m_element_size;

  SegmentInfo(Segment*, long long start, long long size, long long element_start, long long element_size);

  ~SegmentInfo();

  long Parse();

  long long GetTimeCodeScale() const;
  long long GetDuration() const;  // scaled
  const char* GetMuxingAppAsUTF8() const;
  const char* GetWritingAppAsUTF8() const;
  const char* GetTitleAsUTF8() const;

 private:
  long long m_timecodeScale;
  double m_duration;
  char* m_pMuxingAppAsUTF8;
  char* m_pWritingAppAsUTF8;
  char* m_pTitleAsUTF8;
};

class SeekHead {
  SeekHead(const SeekHead&);
  SeekHead& operator=(const SeekHead&);

 public:
  Segment* const m_pSegment;
  const long long m_start;
  const long long m_size;
  const long long m_element_start;
  const long long m_element_size;

  SeekHead(Segment*, long long start, long long size, long long element_start, long long element_size);

  ~SeekHead();

  long Parse();

  struct Entry {
    Entry();

    // the SeekHead entry payload
    long long id;
    long long pos;

    // absolute pos of SeekEntry ID
    long long element_start;

    // SeekEntry ID size + size size + payload
    long long element_size;
  };

  int GetCount() const;
  const Entry* GetEntry(int idx) const;

  struct VoidElement {
    // absolute pos of Void ID
    long long element_start;

    // ID size + size size + payload size
    long long element_size;
  };

  int GetVoidElementCount() const;
  const VoidElement* GetVoidElement(int idx) const;

 private:
  Entry* m_entries;
  int m_entry_count;

  VoidElement* m_void_elements;
  int m_void_element_count;

  static bool ParseEntry(IMkvReader*,
                         long long pos,  // payload
                         long long size, Entry*);
};

class Cues;
class CuePoint {
  friend class Cues;

  CuePoint(long, long long);
  ~CuePoint();

  CuePoint(const CuePoint&);
  CuePoint& operator=(const CuePoint&);

 public:
  long long m_element_start;
  long long m_element_size;

  bool Load(IMkvReader*);

  long long GetTimeCode() const;            // absolute but unscaled
  long long GetTime(const Segment*) const;  // absolute and scaled (ns units)

  struct TrackPosition {
    long long m_track;
    long long m_pos;  // of cluster
    long long m_block;
    // codec_state  //defaults to 0
    // reference = clusters containing req'd referenced blocks
    //  reftime = timecode of the referenced block

    bool Parse(IMkvReader*, long long, long long);
  };

  const TrackPosition* Find(const Track*) const;

 private:
  const long m_index;
  long long m_timecode;
  TrackPosition* m_track_positions;
  size_t m_track_positions_count;
};

class Cues {
  friend class Segment;

  Cues(Segment*, long long start, long long size, long long element_start, long long element_size);
  ~Cues();

  Cues(const Cues&);
  Cues& operator=(const Cues&);

 public:
  Segment* const m_pSegment;
  const long long m_start;
  const long long m_size;
  const long long m_element_start;
  const long long m_element_size;

  bool Find(  // lower bound of time_ns
      long long time_ns, const Track*, const CuePoint*&, const CuePoint::TrackPosition*&) const;

  const CuePoint* GetFirst() const;
  const CuePoint* GetLast() const;
  const CuePoint* GetNext(const CuePoint*) const;

  const BlockEntry* GetBlock(const CuePoint*, const CuePoint::TrackPosition*) const;

  bool LoadCuePoint() const;
  long GetCount() const;  // loaded only
  // long GetTotal() const;  //loaded + preloaded
  bool DoneParsing() const;

 private:
  bool Init() const;
  bool PreloadCuePoint(long&, long long) const;

  mutable CuePoint** m_cue_points;
  mutable long m_count;
  mutable long m_preload_count;
  mutable long long m_pos;
};

class Cluster {
  friend class Segment;

  Cluster(const Cluster&);
  Cluster& operator=(const Cluster&);

 public:
  Segment* const m_pSegment;

 public:
  static Cluster* Create(Segment*,
                         long index,      // index in segment
                         long long off);  // offset relative to segment
  // long long element_size);

  Cluster();  // EndOfStream
  ~Cluster();

  bool EOS() const;

  long long GetTimeCode() const;   // absolute, but not scaled
  long long GetTime() const;       // absolute, and scaled (nanosecond units)
  long long GetFirstTime() const;  // time (ns) of first (earliest) block
  long long GetLastTime() const;   // time (ns) of last (latest) block

  long GetFirst(const BlockEntry*&) const;
  long GetLast(const BlockEntry*&) const;
  long GetNext(const BlockEntry* curr, const BlockEntry*& next) const;

  const BlockEntry* GetEntry(const Track*, long long ns = -1) const;
  const BlockEntry* GetEntry(const CuePoint&, const CuePoint::TrackPosition&) const;
  // const BlockEntry* GetMaxKey(const VideoTrack*) const;

  //    static bool HasBlockEntries(const Segment*, long long);

  static long HasBlockEntries(const Segment*, long long idoff, long long& pos, long& size);

  long GetEntryCount() const;

  long Load(long long& pos, long& size) const;

  long Parse(long long& pos, long& size) const;
  long GetEntry(long index, const mkvparser::BlockEntry*&) const;

 protected:
  Cluster(Segment*, long index, long long element_start);
  // long long element_size);

 public:
  const long long m_element_start;
  long long GetPosition() const;  // offset relative to segment

  long GetIndex() const;
  long long GetElementSize() const;
  // long long GetPayloadSize() const;

  // long long Unparsed() const;

 private:
  long m_index;
  mutable long long m_pos;
  // mutable long long m_size;
  mutable long long m_element_size;
  mutable long long m_timecode;
  mutable BlockEntry** m_entries;
  mutable long m_entries_size;
  mutable long m_entries_count;

  long ParseSimpleBlock(long long, long long&, long&);
  long ParseBlockGroup(long long, long long&, long&);

  long CreateBlock(long long id, long long pos, long long size, long long discard_padding);
  long CreateBlockGroup(long long start_offset, long long size, long long discard_padding);
  long CreateSimpleBlock(long long, long long);
};

class Segment {
  friend class Cues;
  friend class Track;
  friend class VideoTrack;

  Segment(const Segment&);
  Segment& operator=(const Segment&);

 private:
  Segment(IMkvReader*, long long elem_start,
          // long long elem_size,
          long long pos, long long size);

 public:
  IMkvReader* const m_pReader;
  const long long m_element_start;
  // const long long m_element_size;
  const long long m_start;  // posn of segment payload
  const long long m_size;   // size of segment payload
  Cluster m_eos;            // TODO: make private?

  static long long CreateInstance(IMkvReader*, long long, Segment*&);
  ~Segment();

  long Load();  // loads headers and all clusters

  // for incremental loading
  // long long Unparsed() const;
  bool DoneParsing() const;
  long long ParseHeaders();  // stops when first cluster is found
  // long FindNextCluster(long long& pos, long& size) const;
  long LoadCluster(long long& pos, long& size);  // load one cluster
  long LoadCluster();

  long ParseNext(const Cluster* pCurr, const Cluster*& pNext, long long& pos, long& size);

  const SeekHead* GetSeekHead() const;
  const Tracks* GetTracks() const;
  const SegmentInfo* GetInfo() const;
  const Cues* GetCues() const;
  const Chapters* GetChapters() const;
  const Tags* GetTags() const;

  long long GetDuration() const;

  unsigned long GetCount() const;
  const Cluster* GetFirst() const;
  const Cluster* GetLast() const;
  const Cluster* GetNext(const Cluster*);

  const Cluster* FindCluster(long long time_nanoseconds) const;
  // const BlockEntry* Seek(long long time_nanoseconds, const Track*) const;

  const Cluster* FindOrPreloadCluster(long long pos);

  long ParseCues(long long cues_off,  // offset relative to start of segment
                 long long& parse_pos, long& parse_len);

 private:
  long long m_pos;  // absolute file posn; what has been consumed so far
  Cluster* m_pUnknownSize;

  SeekHead* m_pSeekHead;
  SegmentInfo* m_pInfo;
  Tracks* m_pTracks;
  Cues* m_pCues;
  Chapters* m_pChapters;
  Tags* m_pTags;
  Cluster** m_clusters;
  long m_clusterCount;         // number of entries for which m_index >= 0
  long m_clusterPreloadCount;  // number of entries for which m_index < 0
  long m_clusterSize;          // array size

  long DoLoadCluster(long long&, long&);
  long DoLoadClusterUnknownSize(long long&, long&);
  long DoParseNext(const Cluster*&, long long&, long&);

  bool AppendCluster(Cluster*);
  bool PreloadCluster(Cluster*, ptrdiff_t);

  // void ParseSeekHead(long long pos, long long size);
  // void ParseSeekEntry(long long pos, long long size);
  // void ParseCues(long long);

  const BlockEntry* GetBlock(const CuePoint&, const CuePoint::TrackPosition&);
};

}  // namespace mkvparser

inline long mkvparser::Segment::LoadCluster() {
  long long pos;
  long size;

  return LoadCluster(pos, size);
}

#endif  // MKVPARSER_MKVPARSER_H_
