#ifndef ARC_STD_HANDLER_H_
#define ARC_STD_HANDLER_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "arc/std/bool.h"
#include <stdint.h>

/**
 * @brief a handler type
 */
typedef struct ARC_Handler ARC_Handler;

/**
 * @brief data comparison function ptr
 *
 * @note this is used for comparison within vectors
 * 
 * @param a first data struct
 * @param b second data struct
 *
 * @return 0 when a == b
 */
typedef ARC_Bool (* ARC_Handler_CompareDataFn)(void *a, void *b);

/**
 * @brief a function that will take iterated data
 *
 * @param data iterated data from ARC_Handler_Iterate
 */
typedef void (* ARC_Handler_DataFn)(void *data);

/**
 * @brief a function that will be used during destruction of trash vector
 *
 * @param data data that is being destroyed from trash
 */
typedef void (* ARC_Handler_CleanDataFn)(void *data);

/**
 * @brief creates ARC_Handler type
 *
 * @param config    ARC_Handler to initialize
 * @param compareFn function to remove handler data
 * @param cleanFn   function to clean data in handler
 *                  can be null
 */
void ARC_Handler_Create(ARC_Handler **handler, ARC_Handler_CompareDataFn *compareFn, ARC_Handler_CleanDataFn cleanFn);

/**
 * @brief destroyes ARC_Handler type
 *
 * @param handler ARC_Handler to destory
 */
void ARC_Handler_Destroy(ARC_Handler *handler);

/**
 * @brief adds data to handler
 *
 * @param handler ARC_Handler to add to
 * @param data    data that is being added
 */
void ARC_Handler_Add(ARC_Handler *handler, void *data);

/**
 * @brief remove from handler
 *
 * @note the data that is removed is stored in a trash vector
 *       the ARC_Handler_Clean function must be called clean the trash vector
 *       the trash vector is to make sure a state is not deleted while being run
 *
 * @param handler ARC_Handler to remove from
 * @param data    data that is being removed
 */
void ARC_Handler_Remove(ARC_Handler *handler, void *data);

/**
 * @brief remove from handler
 *
 * @note the data that is removed is stored in a trash vector
 *       the ARC_Handler_Clean function must be called clean the trash vector
 *       the trash vector is to make sure a state is not deleted while being run
 *
 * @param handler ARC_Handler to remove from
 * @param index   index of data that is being removed
 */
void ARC_Handler_RemoveIndex(ARC_Handler *handler, uint32_t index);

/**
 * @brief calls provided function on each element in handler
 *
 * @param handler ARC_Handler to iterate through
 * @param datafn  function that will be called on each element of data
 */
void ARC_Handler_Iterate(ARC_Handler *handler, ARC_Handler_DataFn datafn);

/**
 * @brief clears all data from handler and puts it in trash vector
 *
 * @param handler ARC_Handler to clear data from
 */
void ARC_Handler_Clear(ARC_Handler *handler);

/**
 * @brief clears trash from handler
 *
 * @note cleanfn's main purpose is to help manage memory
 *
 * @param handler ARC_Handler to remove trash from
 */
void ARC_Handler_Clean(ARC_Handler *handler);

/**
 * @brief gets size of vector
 *
 * @param handler ARC_handler to get size from
 */
uint32_t ARC_Handler_GetSize(ARC_Handler *handler);

#ifdef __cplusplus
}
#endif

#endif //ARC_STD_HANDLER_H_