#ifndef dvd_desc_h
#define dvd_desc_h

#include "dvd_ifo.h"
#include "dvd_css.h"
#include "ka_error.h"

#define DVD_IFOS_MAX 99
#define DVD_VOBS_MAX 9

typedef struct
{
  char name[13];
  uint64_t start;
  uint64_t end;
  uint64_t size;
} dvd_file_desc_t;

#define DVD_MenuId_Escape    0
#define DVD_MenuId_Root      2
#define DVD_MenuId_Title     3
#define DVD_MenuId_Subtitles 4
#define DVD_MenuId_Audio     5
#define DVD_MenuId_Angle     6
#define DVD_MenuId_Chapter   7

#define DVD_DOMAIN_FIRST_PLAY 0
#define DVD_DOMAIN_VMG_MENU   1
#define DVD_DOMAIN_VTS_MENU   2
#define DVD_DOMAIN_VTS_TITLE  3

typedef struct
{
  uint32_t domain;
  uint32_t vtsNr;      // VTS/IFO nr or 0 for VMG/IFO
  uint32_t vtsTitleNr; // VTS title nr or 0 for VTS menu
  uint32_t vtsChapterNr; // VTS title part nr or menu nr
  const dvd_pgc_lu_table_t* lut;
  const dvd_pgc_t* pgc;
  uint32_t programChainNr;
  uint32_t programNr;
  uint32_t cellNr;
  uint32_t nextCellNr; // next cell is cell+1 for normal cell cell+x in multi-angle block
  uint32_t lbCellStart;
  uint32_t lbCellEnd;
} dvd_pos_t;

// Chapter or menu info
typedef struct
{
  dvd_pos_t firstPos;
  dvd_pos_t lastPos;
} dvd_pos_range_t;

typedef struct
{
  dvd_vmg_ifo_t* vmg;
  dvd_vts_ifo_t* vts;
  uint32_t nr_vobs; // excluding menu
  uint64_t vob_menu_start;
  uint64_t vob_menu_end;
  uint64_t vob_menu_size;
  uint64_t vob_title_start;
  uint64_t vob_title_end;
  uint64_t vob_title_size;

  // CSS
  int title_key_known;
  dvd_key_t title_key;

  // Filenames for BUP, IFO, VOB (can be upper/lower/mixed case)
  dvd_file_desc_t bup;
  dvd_file_desc_t ifo;
  dvd_file_desc_t vobs[DVD_VOBS_MAX + 2];
} dvd_ifo_desc_t;

typedef struct
{
  uint32_t nr_ifos; // including VMG
  char* path_video;
  char* volume;

  dvd_ifo_desc_t ifos[DVD_IFOS_MAX + 1];
} dvd_desc_t;

void dvd_desc_stats(dvd_desc_t* dvd);
int dvd_desc_validate(ka_error_t* pErrorBlock, const dvd_desc_t* dvd);
const dvd_pgc_lu_table_t* dvd_desc_extractMenuLut(const dvd_desc_t* dvd, int ifoNr, const char* lang);
const dvd_pgc_lu_table_t* dvd_desc_extractMenu(dvd_pos_range_t* p, const dvd_desc_t* dvd, int ifoNr, const char* lang, int menuNr);
void dvd_desc_extractChapter(dvd_pos_range_t* p, const dvd_desc_t* dvd, int titleNr, int chapterNr);
void dvd_desc_free(dvd_desc_t** pdvd);

#endif
