#ifndef RT_RENDERER_COMMAND_LIST_H
#define RT_RENDERER_COMMAND_LIST_H

#include <stdint.h>
#include <runtime/runtime.h>
#include "render_resource.h"

/* Types of render commands */
typedef enum {
    RT_RENDER_COMMAND_DRAW_INDIRECT,
} rt_render_command_type;

typedef enum {
    RT_RENDER_QUEUE_GRAPHICS,
    RT_RENDER_QUEUE_COMPUTE,
    RT_RENDER_QUEUE_TRANSFER,
} rt_render_queue;

/* Structures containing command parameters */

typedef struct {
    rt_render_buffer_handle buffer;
    uint32_t offset;
    uint32_t draw_count;
    uint32_t stride;
} rt_draw_indirect_data;

typedef struct {
    uint32_t type;
    uint32_t target_queue;
} rt_render_command_header;

typedef struct {
    rt_render_command_header *headers;
    void *data;
    /* Number of encoded commands */
    uint32_t length;

    /* Information used while encoding.
     * In the future, it would be possible to move this to another struct that is discarded after
     * encoding is finished.
     */

    size_t data_capacity;
    size_t data_end;
} rt_render_command_list;

#ifdef __cplusplus
extern "C" {
#endif

/* *** Encoding API *** */

typedef struct {
    rt_result result;
    rt_render_command_list list;
} rt_begin_render_command_list_result;

/* Get a new render command list. */
RT_DLLEXPORT rt_begin_render_command_list_result rtBeginRenderCommandList(void);

/* Lowlevel function that writes the data to the queue. */
RT_DLLEXPORT rt_result rtEncodeRenderCommand(rt_render_command_list *list, rt_render_command_type type, rt_render_queue queue, const void *data);

/* Helper functions for specific commands */
RT_INLINE rt_result rtEncodeDrawIndirect(rt_render_command_list *list, const rt_draw_indirect_data *draw_indirect_data) {
    return rtEncodeRenderCommand(list, RT_RENDER_COMMAND_DRAW_INDIRECT, RT_RENDER_QUEUE_GRAPHICS, draw_indirect_data);
}

/* *** Submission *** */

/* Submit a finished command list to the graphics device. The list will not be usable after this function is done. */
RT_DLLEXPORT rt_result rtSubmitCommandList(rt_render_command_list *list);


#ifdef __cplusplus
}
#endif


#endif
