#ifndef _UTILS_H
#define _UTILS_H

#include <stdlib.h>

struct _Set {
  void ** element;
  int size;
  int max_size;
  int ref; /* refcounting on the whole set */
};
typedef struct _Set * Set;

struct _Vector {
  int * element;
  int size;
  int max_size;
};
typedef struct _Vector * Vector;

void *xmalloc( size_t size );
void *xrealloc ( void *p, size_t size);

int rnd( int range );

void fail( const char * fmt, ... );
void warn( const char * fmt, ... );

Set set_new( int max_size );
void set_free( Set s );
void set_ref( Set s );
void set_unref( Set s );
void set_empty( Set s );
void set_copy( Set source, Set dest );
void set_add( Set s, void * p );
void set_remove( Set s, void * p );
void set_remove_at( Set s, int i );

Vector vector_new( int max_size );
void vector_free( Vector v );
void vector_increase_maxsize( Vector v, int new_max ); /* make sure the vector is big enough */
void vector_empty( Vector v );
int vector_membership( Vector v, int p );
/* shift and unshift have worse performances than push et pop */
int vector_shift( Vector v );           /* Get first */
void vector_unshift( Vector v, int p ); /* Place first */
int vector_pop( Vector v );             /* Get last */
void vector_push( Vector v, int p );    /* Place last */

const char *name_state_get(int s); /* mainly for debuging */
const char *name_color_get(int c); /* mainly for debuging */

enum BubbleState { 
  NEW = 0,
  READY,
  LAUNCHED, 
  STUCK, 
  EXPLODING, 
  FALLING, 
  RISING,
  CHAINREACTING,
  RUNAWAY,
  DEAD
};

#define NB_BUBBLE_STATES (DEAD+1)
#define DEFAULT_STATE 666
#define DEFAULT_STATE_NAME "DEFAULT"


#define clip( X, m, M ) (( X < m )? m : (( X > M )? M : X ))

#endif /* _UTILS_H */
