/**
 * Copyright (c) 2021 Dominic Masters
 * 
 * This software is released under the MIT License.
 * https://opensource.org/licenses/MIT
 */

#include "file.h"

void fileNormalizeSlashes(char *string) {
  char c;
  int i = 0;

  while(c = string[i++]) {
    if(c != '\\' && c != '/') continue;
    string[i-1] = FILE_PATH_SEP;
  }
}

void fileMkdirp(char *path) {
  char buffer[FILENAME_MAX];
  char c;
  int i = 0;
  bool inFile;
  bool hasMore;

  inFile = false;
  hasMore = false;
  while(c = path[i]) {
    if((c == '\\' || c == '/') && i > 0) {
      buffer[i] = '\0';
      fileMkdir(buffer, 0755);
      inFile = false;
      hasMore = false;
      buffer[i] = FILE_PATH_SEP;
      i++;
      continue;
    }

    if(c == '.') inFile = true;
    hasMore = true;
    buffer[i] = c;
    i++;
  }

  if(!inFile && hasMore) {
    buffer[i] = '\0';
    fileMkdir(buffer, 0755);
  }
}

void assetReadString(FILE *file, char *buffer) {
  size_t length;
  fseek(file, 0, SEEK_END);// Seek to the end
  length = ftell(file);// Get our current position (the end)
  fseek(file, 0, SEEK_SET);// Reset the seek 
  fread(buffer, 1, length, file);// Read all the bytes
}

void fileGetDirectory(char *file, char* buffer) {
  char *c, *p;
  int32_t i;
  p = strrchr(file, FILE_PATH_SEP);
  c = file;
  i = 0;
  do {
    buffer[i++] = *c;
  } while(++c < p);
  buffer[i] = '\0';
}

bool fileListChildren(
  char *directory,
  char *buffer,
  int32_t *count,
  uint8_t *types,
  char **children
) {
  #if defined(_MSC_VER)
    WIN32_FIND_DATA fdFile;
    HANDLE hFind = NULL;
    char sPath[2048];
    int32_t i;

    // Append wildcard
    sprintf(sPath, "%s\\*.*", directory);

    // Scan first
    if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE) {
      printf("Path not found: [%s]\n", directory);
      return false;
    }

    // Iterate
    i = 0;
    do {
      if(
        strcmp(fdFile.cFileName, ".") == 0 ||
        strcmp(fdFile.cFileName, "..") == 0
      ) continue;

      // Get Full path.
      sprintf(sPath, "%s\\%s", directory, fdFile.cFileName);

      //Is the entity a File or Folder?
      if(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
        types[i] = FILE_CHILD_TYPE_DIR;
      } else {
        types[i] = FILE_CHILD_TYPE_FILE;
      }

      children[i] = buffer + (i * FILE_CHILD_NAME_MAX);
      strcpy(children[i], fdFile.cFileName);
      i++;
    } while(FindNextFile(hFind, &fdFile));

    *count = i;
    return true;
  #else
    struct dirent *de;
    DIR *dr;
    int32_t i;

    // Open Dir
    dr = opendir(directory);
    if(dr == NULL) {
      printf("Could not open directory");
      return false;
    }


    // Iterate
    i = 0;
    while ((de = readdir(dr)) != NULL) {
      // File or folder?
      if(de->d_type != DT_REG) continue;

      // Copy into child buffer
      children[i] = buffer + (i * FILE_CHILD_NAME_MAX);
      strcpy(children[i], de->d_name);
      i++;
    }
    if(closedir(dr)) return false;
  
    *count = i;
    return true;
  #endif
}