//
// Created by Tristan on 11/6/2025.
//

#ifndef UTIL_H
#define UTIL_H

#include <stdint.h>
#include "StormLib.h"
#include "mpq/mpq.h"
#include "wmo/wmo_structs.h"

#ifdef _WIN32
    #include <direct.h> // _mkdir
    //#define dwError GetLastError()
    #define MAKE_DIR(path) _mkdir(path)
#else
    #include <sys/stat.h>
    #include <errno.h>
    #define dwError errno
    #define MAKE_DIR(path) mkdir(path, 0777)
#endif

#define DEV_MODE
#define PATH_SEPARATOR '\\'

// Root Chunks
#define MVER 0x4d564552
#define MOTX 0x4d4f5458
#define MOMT 0x4d4f4d54
#define MOHD 0x4d4f4844
#define MOGN 0x4d4f474e
#define MOGI 0x4d4f4749
#define MOSB 0x4d4f5342
#define MOPV 0x4d4f5056
#define MOPT 0x4d4f5054
#define MOPR 0x4d4f5052
#define MOVV 0x4d4f5656
#define MOVB 0x4d4f5642
#define MOLT 0x4d4f4c54
#define MODS 0x4d4f4453
#define MODN 0x4d4f444e
#define MODD 0x4d4f4444
#define MFOG 0x4d464f47

// Group Chunks
#define MOGP 0x4d4f4750
#define MOGX 0x4d4f4758
#define MOPY 0x4d4f5059
#define MPY2 0x4d505932
#define MOVI 0x4d4f5649
#define MOVT 0x4d4f5654
#define MONR 0x4d4f4e52
#define MOTV 0x4d4f5456
#define MOBA 0x4d4f4241
#define MOQG 0x4d4f4747
#define MOLR 0x4d4f4c52
#define MODR 0x4d4f4452
#define MOBN 0x4d4f424e
#define MOBR 0x4d4f4252
#define MOCV 0x4d4f4356
#define MOC2 0x4d4f4332
#define MLIQ 0x4d4c4951
#define MORI 0x4d4f5249

#define INIT_CAPACITY 19



typedef struct {
    uint32_t chunk_name;            // FourCC
    uint32_t chunk_size;            // in bytes
} WMOChunkHeader;

typedef struct {
    char *data;
    DWORD size;
} WMOData;

typedef struct {
    ArchiveEntry* entries;
    int count;
    int capacity;
} PathList;

WMOData load_wmo_data(ArchiveManager *archives, const char *wmoFileName);
WMOData load_wmo_data_from_file(FILE **file_ptr_in);
// HANDLE get_file_in_mpq(HANDLE hMPQ, const char *file_in_mpq_name);
HANDLE get_file_in_archives(ArchiveManager *archives, const char *file_in_mpq_name);
uint32_t get_file_size_in_mpq(HANDLE hFileInArchive, const char *file_in_mpq_name);
size_t get_wmo_base_name(char *dest, size_t dest_size, const char *full_path);
int load_wmo_file(const char *filename, FILE **file_ptr_out);
void get_mpq_file_path(char *buffer, size_t buffer_size);
void get_wmo_file_path(char *buffer, size_t buffer_size);
void parse_wmo_chunks(ArchiveManager *archives, const char *wmo_buffer, DWORD total_size,  WMORootData *out_wmo_data,
    const char *wmo_file_path);
void parse_momt_and_extract_textures(ArchiveManager *archives, const WMORootData *wmo_data);
void get_data_dir(char *buffer, size_t buffer_size);

void init_archive_manager (ArchiveManager *manager, const char *root_path);
void init_path_list(PathList *list);
void expand_path_list(PathList* list);
void recursively_scan_directory(const char *current_dir, PathList* list);
void free_path_list(PathList* list);
int assign_score(const char *filename);
int archive_comparator(const void *a, const void *b);
void expand_archive_manager(ArchiveManager *manager);

char *get_file_contents(const char *filename);

#endif //UTIL_H
