#ifndef _CELL_H
#define _CELL_H

#include "utils.h"
#include "setting.h"
#include "bubble.h"

typedef enum { 
  EAST=0, 
  NORTH_EAST, 
  NORTH_WEST, 
  WEST,
  SOUTH_WEST, 
  SOUTH_EAST 
} Quadrant;

#define NB_CELLS       (COLS * ROWS)
#define EMPTY_CELL     NULL
#define OUT_OF_BOUNDS  -1
#define ROW_HEIGHT     0.8660254037844386 /* sqrt(3)/2 */


struct _CellArray {
  Bubble cell[NB_CELLS];
  int tagged[NB_CELLS];
  int neighbor[NB_CELLS][SOUTH_EAST+1];
  int first_row;
  int parity;
  int moving_ceiling;
  Vector list1;
  Vector list2;
};

typedef struct _CellArray * CellArray;

#define row_start(A,R)    ((( 1 - A->parity )/2 + R )%2 )
#define first_cell(A)     ( A->first_row*COLS )
#define ceiling_y(A)      ( 0.5 + A->first_row*ROW_HEIGHT )
#define cell_y(C)         (( (C)/COLS )*ROW_HEIGHT + 0.5 )
#define cell_not_empty(A,C) (( C != OUT_OF_BOUNDS )&&( A->cell[C] != EMPTY_CELL))

CellArray cell_array_new( int moving_ceiling );
void cell_array_free( CellArray ca );
void cell_array_empty( CellArray ca );
int  cell_array_is_empty( CellArray ca );
void cell_array_lower( CellArray ca );
int  cell_array_is_overflow( CellArray ca );

//int neighbor_cell( CellArray ca, int cell, Quadrant quadrant );
#define neighbor_cell(ca,cell,quadrant) (ca->neighbor[cell][quadrant])

int cellCL( CellArray ca, int row, int col );
int floating_cell( CellArray ca, int c );
void cell_center( CellArray ca, int cell, double *x, double *y);
int find_target_cell( CellArray ca, 
		      int angle, 
		      double * target_y,
		      Vector path );

int find_random_empty_cell( CellArray ca, int from_top  );

int count_floating_bubbles( CellArray ca, Vector floating );
int count_explosive_bubbles( CellArray ca,
			     int cell,
			     Set explosive, 
			     Vector explosion_dates );
int count_reacting_bubbles( CellArray ca,
			    Set explosive,
			    Set reacting, Vector destinations );
#endif /* _CELL_H */
