/**
 * @file vulkan_image.h
 * @author Piotr Krygier (everyonecancode@gmail.com)
 * @brief Library for loading and handling textures
 * @version 0.1
 * @date 2023-09-27
 *
 * @copyright Copyright (c) 2023
 *
 */

#ifndef TEXTURE_H
#define TEXTURE_H

#include <stdint.h>

#include "graphics_context.h"
#include "utilities/commons.h"
#include "utilities/file_utils.h"
#include "vulkan/vulkan_core.h"

#define IMAGE_FORMAT VK_FORMAT_B8G8R8A8_SRGB;

/**
 * @brief Initialize vulkan with image views and stuff
 *
 * @param context Graphics context
 * @return rse_err_t RSE_ERROR_NO_ERROR on success
 */
rse_err_t init_vulkan_images(struct graphics_context_t* context);

/**
 * @brief Loads image from file, for later to be used as a texture
 *
 * @param context Graphics context handle
 * @param file_path Path to texture file
 * @param texture_id Texture ID will be set up here
 * @return rse_err_t RSE_ERROR_NO_ERROR on success
 */
rse_err_t load_texture_from_bitmat(struct graphics_context_t* context, const unsigned char* pixel_buffer, int width,
                                   int height, rse_id_t* texture_id, VkFormat color_format);

/**
 * @brief Loads image from file, for later to be used as a texture
 *
 * @param context Graphics context handle
 * @param file_path Path to texture file
 * @param texture_id Texture ID will be set up here
 * @return rse_err_t RSE_ERROR_NO_ERROR on success
 */
rse_err_t texture_load_from_file(struct graphics_context_t* context, const char* file_path, rse_id_t* texture_id);

rse_err_t texture_update_image(struct graphics_context_t* context,
                               const unsigned char* pixels,
                               int width,
                               int height,
                               rse_id_t texture_id,
                               VkFormat format);

/**
 * @brief Destroy all loaded textures. Usefull for closing application or just clearing.
 *
 * @param context Graphics context handle
 *
 */
void destroy_textures(struct graphics_context_t* context);

/**
 * @brief Checks if image exists for provided image ID.
 *
 * @param context Graphics context handle
 * @param image_id Image ID
 * @return uint8_t 1 on success, 0 on failure
 */
uint8_t image_exists(struct graphics_context_t* context, rse_id_t image_id);

/**
 * @brief Returns number of loaded texture
 *
 * @param context Graphics context handle
 * @return size_t Texture count
 */
size_t get_textures_count(struct graphics_context_t* context);

rse_err_t find_depth_format(struct graphics_context_t* context, VkFormat* found_format);

rse_err_t create_color_resource(struct graphics_context_t* context);
void destroy_color_resource(struct graphics_context_t* context);

rse_err_t create_depth_resources(struct graphics_context_t* context);
void destroy_depth_resource(struct graphics_context_t* context);

/**
 * @brief Create a sampler object for texture sampling
 *
 * @param[in/out] context Graphics context to create sampler in
 * @return RSE_ERROR_NO_ERROR on success, error code otherwise
 */
rse_err_t sampler_create(struct graphics_context_t* context, VkSampler* sampler);

#endif /* TEXTURE_H */
