#pragma once
#include <cmath>
#include <sys/types.h>
#include <stdint.h>
#include <string>
#include <deque>

namespace vorbis{
  struct mode{
    bool blockFlag;
    unsigned short windowType;
    unsigned short transformType;
    char mapping;
  };
  
  inline unsigned int ilog(unsigned int input){
    return (std::log(input))/(std::log(2))+1;
  }
  
  class header{
    public:
      header();
      bool read(char* newData, unsigned int length);
      int getHeaderType();
      long unsigned int getVorbisVersion();
      char getAudioChannels();
      long unsigned int getAudioSampleRate();
      long unsigned int getBitrateMaximum();
      long unsigned int getBitrateNominal();
      long unsigned int getBitrateMinimum();
      char getBlockSize0();
      char getBlockSize1();
      char getFramingFlag();
      std::string toPrettyString(size_t indent = 0);
      std::deque<mode> readModeDeque(char audioChannels);
    protected:
      uint32_t getInt32(size_t index);
      uint32_t getInt24(size_t index);
      uint16_t getInt16(size_t index);
    private:
      std::deque<mode> modes;
      char* data;
      unsigned int datasize;
      bool checkDataSize(unsigned int size);
      bool validate();
  };   
}