#include "datexportapi.h"

DatExportApi::DatExportApi() {
  datexport_dll_ = LoadLibraryA("datexport");

  /* get pointer to the function in the dll*/ 
  open_dat_file_addr_ = GetProcAddress(datexport_dll_, "OpenDatFileEx2"); 
  open_dat_file_func_ = DatExportApiPrivate::OpenDatFileFunc(open_dat_file_addr_); 
  
  get_num_subfiles_addr_ = GetProcAddress(datexport_dll_, "GetNumSubfiles"); 
  get_num_subfiles_func_ = DatExportApiPrivate::GetNumSubfilesFunc(get_num_subfiles_addr_); 
  
  get_subfile_sizes_addr_ = GetProcAddress(datexport_dll_, "GetSubfileSizes"); 
  get_subfile_sizes_func_ = DatExportApiPrivate::GetSubFileSizesFunc(get_subfile_sizes_addr_); 
  
  get_subfile_version_addr_ = GetProcAddress(datexport_dll_, "GetSubfileVersion"); 
  get_subfile_version_func_ = DatExportApiPrivate::GetSubFileVersionFunc(get_subfile_version_addr_); 
  
  get_subfile_data_addr_ = GetProcAddress(datexport_dll_, "GetSubfileData"); 
  get_subfile_data_func_ = DatExportApiPrivate::GetSubfileDataFunc(get_subfile_data_addr_); 
  
  close_dat_file_addr_ = GetProcAddress(datexport_dll_, "CloseDatFile"); 
  close_dat_file_func_ = DatExportApiPrivate::CloseDatFileFunc(close_dat_file_addr_); 
  
  purge_subfile_data_addr_ = GetProcAddress(datexport_dll_, "PurgeSubfileData"); 
  purge_subfile_data_func_ = DatExportApiPrivate::PurgeSubFileDataFunc(purge_subfile_data_addr_);

  put_subfile_data_addr_ = GetProcAddress(datexport_dll_, "PutSubfileData"); 
  put_subfile_data_func_ = DatExportApiPrivate::PutSubFileDataFunc(put_subfile_data_addr_); 
  
  flush_addr_ = GetProcAddress(datexport_dll_, "Flush"); 
  flush_func_ = DatExportApiPrivate::FlushFunc(flush_func_);
}

int DatExportApi::OpenDatFile(int handle, const char* filename, unsigned int flags) {
  int did_master_map = 0;
  int block_size = 0;
  int vnum_dat_file = 0;
  int vnum_game_data = 0;
  unsigned long dat_file_id = 0;
  void* dat_id_stamp = malloc(64);
  void* first_iter_guid = malloc(64);

  int result = open_dat_file_func_(handle, filename, flags, &did_master_map, &block_size,
      &vnum_dat_file, &vnum_game_data, &dat_file_id, dat_id_stamp, first_iter_guid);

  free(dat_id_stamp);
  free(first_iter_guid);
  return result;
}

int DatExportApi::GetNumSubfiles(int handle) {
  return get_num_subfiles_func_(handle);
}

void DatExportApi::GetSubfileSizes(int handle, int* file_ids, int* size, int* iteration, int offset, int count) {
  get_subfile_sizes_func_(handle, file_ids, size, iteration, offset, count);
}

int DatExportApi::GetSubfileVersion(int handle, int file_id) {
  return get_subfile_version_func_(handle, file_id);
}

int DatExportApi::GetSubfileData(int handle, int file_id, void* target_buf, int& version) {
  return get_subfile_data_func_(handle, file_id, target_buf, 0, &version); // returns size of file in bytes
}

void DatExportApi::CloseDatFile(int handle) {
  close_dat_file_func_(handle);
}

int DatExportApi::PurgeSubfileData(int handle, int file_id) {
  return purge_subfile_data_func_(handle, file_id); // returns 0 on successfull
}

int DatExportApi::PutSubfileData(int handle, int file_id, void* data, int offset, int size, int version, int iteration, bool compress) {
  return put_subfile_data_func_(handle, file_id, data, offset, size, version, iteration, 0);
}

void DatExportApi::Flush(int handle) {
  flush_func_(handle);
}

DatExportApi::~DatExportApi() {
  FreeLibrary(datexport_dll_);
}