#include #include "puzzle.h" #include "../resources/resources.h" #include "../ui_elements/UI.h" #include #include #include #include #include #include "../utils/arena.h" #include static const char *IMAGE_NAME = "icon.png"; CollectionElementType getTypeFromPath(char *fullPath) { struct stat st; if (stat(fullPath, &st) != 0) return COLLECTION_ELEMENT_UNKNOWN; if (S_ISDIR(st.st_mode)) { return COLLECTION_ELEMENT_COLLECTION; } else if (S_ISREG(st.st_mode)) { return COLLECTION_ELEMENT_PUZZLE; } return COLLECTION_ELEMENT_UNKNOWN; } bool isIcon(struct dirent *entry) { return strncmp(entry->d_name, IMAGE_NAME, strlen(IMAGE_NAME)) == 0; } void addIcon(CollectionElement *el, struct dirent *entry) { if (el == NULL || entry == NULL) return; char fullPath[1024]; snprintf(fullPath, sizeof(fullPath), "%s/%s", el->path, entry->d_name); } bool isPuzzle(char *path) { size_t entry_name_len = strlen(path); if (entry_name_len < 4) return false; char *last_bytes = path + entry_name_len - 3; if (strncmp(last_bytes, ".pz", 3) != 0) return false; return true; } bool isElement(struct dirent *entry, char *basePath) { if (entry == NULL) return false; if (strncmp(".", entry->d_name, 1) == 0) return false; if (isIcon(entry)) return false; char full_path_buf[1024]; snprintf(full_path_buf, sizeof(full_path_buf), "%s/%s", basePath, entry->d_name); struct stat st; if (stat(full_path_buf, &st) != 0) return false; if (S_ISDIR(st.st_mode)) return true; return isPuzzle(entry->d_name); } char *getName(char *name) { char buf[1024]; strncpy(buf, name, sizeof(buf)); size_t len = strlen(name); // Cutting a file extention for (size_t i = 0; i < len; ++i) { if (buf[i] == '.') { buf[i] = 0x0; break; } } return strdup(buf); } size_t getElementCount(DIR *dir, CollectionElement *el) { struct dirent *entry; size_t outp = 0; while ((entry = readdir(dir)) != NULL) { if (isElement(entry, el->path)) outp += 1; } rewinddir(dir); return outp; } void initCollectionFromDir(CollectionElement *el) { if (el == NULL) return; TraceLog(LOG_INFO, "Initializing a collection element from %s/", el->path); DIR *dir = opendir(el->path); if (dir == NULL) { TraceLog(LOG_ERROR, "Failed to open the directory"); return; } el->childCount = getElementCount(dir, el); el->children = malloc(sizeof(CollectionElement) * el->childCount); // printf("element count: %zu\n", el->childCount); if (el->children == NULL) { TraceLog(LOG_ERROR, "Failed to allocate the collection element children array"); closedir(dir); return; } struct dirent *entry; char full_path_buf[1024]; size_t idx = 0; while ((entry = readdir(dir)) != NULL) { if (isIcon(entry)) { addIcon(el, entry); continue; } if (!isElement(entry, el->path)) continue; snprintf(full_path_buf, sizeof(full_path_buf), "%s/%s", el->path, entry->d_name); struct stat st; if (stat(full_path_buf, &st) != 0) continue; CollectionElement *read_el = &el->children[idx]; // printf("idx = %zu\n", idx); if (S_ISDIR(st.st_mode)) { read_el->type = COLLECTION_ELEMENT_COLLECTION; } else if (S_ISREG(st.st_mode)) { read_el->type = COLLECTION_ELEMENT_PUZZLE; } read_el->IsInitialized = false; read_el->path = strdup(full_path_buf); read_el->name = getName(entry->d_name); read_el->icon = NULL; idx += 1; } closedir(dir); } void InitializeCollection(CollectionElement *el) { if (el == NULL) { TraceLog(LOG_ERROR, "Failed to initialize collection element: the element is NULL"); return; } switch (el->type) { case COLLECTION_ELEMENT_PUZZLE: break; case COLLECTION_ELEMENT_COLLECTION: initCollectionFromDir(el); break; default: TraceLog(LOG_WARNING, "Invalid CollectionElement type"); break; } } void DrawCollectionElement(CollectionElement *el, Rectangle rec) { if (el == NULL) return; if (el->icon != NULL) { printf("xdx\n"); DrawTexturePro(*el->icon, (Rectangle) { .x = 0, .y = 0, .width = el->icon->width, .height = el->icon->height, }, rec, (Vector2) { .x = 0, .y = 0 }, 0, WHITE); } else { DrawRecBordered(rec, COLORSCHEME_WHITE, COLORSCHEME_ORANGE, BORDER); } int scroll = 0; DrawTextInRec(rec, el->name, GetMainFont(), 20, COLORSCHEME_BROWN, 1, &scroll); }