#ifndef GRID_H
#define GRID_H

#include <vector>
#include <math.h>
#include "geometry.h"

enum cellType{
	FLUID=0,
	SOLID=1 
};

enum directions{
	XDIR=0,
	YDIR=1,
	ZDIR=2
};



class Cell {

public:
	Cell() {};
	void update(float deltaTime);
	void draw();
	void setCenter(int xVal, int yVal, int zVal) {c[0]=xVal,c[1]=yVal,c[2]=zVal;}
	int getX() {return c[0];}
	int getY() {return c[1];}
	int getZ() {return c[2];}
	void setVelocity(Tuple velocity) {v=velocity;}
	Tuple getVelocity() {return v;}
	void setTempVelocity(Tuple velocity) {tempV=velocity;}
	Tuple getTempVelocity() {return tempV;}

	void setForce(Tuple force) {f=force;}
	Tuple getForce() {return f;}

	void setType(int type) {t=type;}
	int getType() {return t;}
	void update(double dt);

private:		
	int c[3];		// cell centers are going to be at	
	Tuple v;
	Tuple tempV;	// need to store new and old velocities during update step
	Tuple f;
	int t;

};

typedef Cell*	cellPtr;

class Grid {
	public:
	Grid();
	void reInit();
	Cell* getCell(int x, int y, int z);
	void createCell(int x, int y, int z, int cType );
	void deleteCell(int x, int y, int z);
	void update();
	void advect(double dt);
	Tuple getVelocity(Tuple p);
	double interpolateVelocity(Tuple p, int index);
	double getCellVelocity(int x, int y, int z, int index);
	void draw();
	double hash(int x, int y, int z) {return ((541*x + 70*y + 31*z)%size);}

private:
	static const int w=3;
	static const int h=3;
	static const int d=3;
	static const int size=(w+2)*(h+2)*(d+2);

	vector<vector<cellPtr>> grid;	
	static const int kCFL=4;
	static const int sMIN=30;  // the minimum number of steps per second; don't need to go any faster

	static const int sMAX=500;	// max number of steps per second, needs to be tested
									// probably should allow user to adjust
	
	double uMax;				// maximum velocity
	double cSize;				// cell width=height=depth (cells are a cube)

};




#endif // GRID_H


