/**
 *   \file utilities.h
 *   \brief Déclaraction des structures de données et fonctions utilitaires.
 *
 *  Dans ce fichier sont déclarées et implémentées les structures qui serviront
 *  de conteneurs aux données manipulées. Sont également déclarées les fonctions
 *  utilitaires pour la manipulation de ces structures.
 */

#ifndef SRC_UTILITIES_H_
#define SRC_UTILITIES_H_

#include "darray.h"
#include <stdio.h>

/*****************************************************************************/
/*                             DEFINE DIRECTIVES                             */
/*****************************************************************************/

#ifdef Debug
#define DEBUG if (1)
#else
#define DEBUG if (0)
#endif

/*****************************************************************************/
/*                             STRUCT DECLARATION                            */
/*****************************************************************************/

struct Image;
typedef struct Image Image;
struct Pixel;
typedef struct Pixel Pixel;
struct Zone;
typedef struct Zone Zone;
struct Segment;
typedef struct Segment Segment;

/*****************************************************************************/
/*                           STRUCT IMPLEMENTATION                           */
/*****************************************************************************/

/**
 *  \brief Conteneur d’une image
 *
 *  Une image est une structure définie par ses dimensions verticales et
 *  horizontales x et y, et contenant pour chacune des coordonnées possibles
 *  selon ses dimensions un pixel de type \ref Pixel. Ces pixels sont stockés
 *  dans un tableau dynamique \ref darray.
 */
struct Image {
  uint64_t sizeX; /*!< Largeur de l’image */
  uint64_t sizeY; /*!< Hauteur de l’image */
  darray *pixels; /*!< Vecteur à une dimention de \ref Pixel */
};

/**
 *  \brief Conteneur d’un pixel
 *
 *  Un pixel est défini par sa couleur représenté en RGB (rouge, vert, bleu).
 *  Il contient également une valeur booléenne afin de savoir si le Pixel fut
 *  visité précédemment par l’algorithme de compression.
 */
struct Pixel {
  uint8_t red;     /*!< Couleur rouge du pixel */
  uint8_t green;   /*!< Couleur verte du pixel */
  uint8_t blue;    /*!< Couleur bleue du pixel */
  uint8_t visited; /*!< Le pixel a-t-il été visité avant */
};

/**
 *  \brief Conteneur de zone de couleur unie
 *
 *  Une zone est un ensemble de pixels de même couleur ou de couleur similaire
 *  dont on conserve uniquement les marges dans le tableau dynamique.
 */
struct Zone {
  uint8_t red;      /*!< Couleur rouge de la zone */
  uint8_t green;    /*!< Couleur verte de la zone */
  uint8_t blue;     /*!< Couleur bleue de la zone */
  darray *segments; /*!< Vecteur de \ref Segment */
};

/**
 *  \brief Conteneur de segment de couleur unie
 *
 *  Un segment est un ensemble de pixels de même ordonnée et de couleur unie ou
 *  similaire. Il se définit par son ordonnée y et de ses deux pixels de bordure
 *  à son extrême droite et à son extrême gauche.
 */
struct Segment {
  uint32_t left_limit;  /*!< extrême gauche du segment  */
  uint32_t right_limit; /*!< extrême droit du segment */
};

/*****************************************************************************/
/*                       Utility functions declaration                       */
/*****************************************************************************/

/// \brief Création d’un nouveau pixel
Pixel *newPixel(uint8_t t_r, uint8_t t_g, uint8_t t_b);
/// \brief Création d’une nouvelle image
Image *newImage();
/// \brief Destructeur d’une image
void deleteImage(Image *t_self);
/// \brief Constructeur d’un segment de couleur unie
Segment *newSegment(uint32_t t_right_limit, uint32_t t_left_limit);
/// \brief Constructeur de conteneur de zone
Zone *newZone(uint8_t t_r, uint8_t t_g, uint8_t t_b);

#endif /* SRC_UTILITIES_H_ */
