#ifndef _CELL_H_
#define _CELL_H_

#include "bag.h"
#include "particle.h"
#include "assert.h"

class Particle;

enum CELL_STATUS { CELL_EMPTY, CELL_SURFACE, CELL_FULL };

class Cell {

public:

  // ========================
  // CONSTRUCTOR & DESTRUCTOR
  Cell() { 
    particles = new Bag<Particle*>(10,Particle::extract_func); 
    u_plus = 0;
    v_plus = 0;
    w_plus = 0;
    new_u_plus = 0;
    new_v_plus = 0;
    new_w_plus = 0;
    pressure = 0;
  }
  ~Cell() { delete particles; }

  // =========
  // ACCESSORS
  float get_u_plus() const { return u_plus; }
  float get_v_plus() const { return v_plus; }
  float get_w_plus() const { return w_plus; }
  float get_new_u_plus() const { return new_u_plus; }
  float get_new_v_plus() const { return new_v_plus; }
  float get_new_w_plus() const { return new_w_plus; }

  int numParticles() const { return particles->Count(); }
  Bag<Particle*>* getParticles() const { return particles; }
  enum CELL_STATUS getStatus() const { return status; }
  float getPressure() const { return pressure; }

  // =========
  // MODIFIERS
  void set_u_plus(float f) { u_plus = f; }
  void set_v_plus(float f) { v_plus = f; }
  void set_w_plus(float f) { w_plus = f; }
  void set_new_u_plus(float f) { new_u_plus = f; }
  void set_new_v_plus(float f) { new_v_plus = f; }
  void set_new_w_plus(float f) { new_w_plus = f; }
  void adjust_new_u_plus(float f) { new_u_plus += f; }
  void adjust_new_v_plus(float f) { new_v_plus += f; }
  void adjust_new_w_plus(float f) { new_w_plus += f; }

  void copyVelocity() { 
    u_plus = new_u_plus; new_u_plus = 0;
    v_plus = new_v_plus; new_v_plus = 0;
    w_plus = new_w_plus; new_w_plus = 0; }

  void addParticle(Particle *p) {
    assert(p != NULL);
    particles->Add(p); }
  void removeParticle(Particle *p) {
    assert(p != NULL);
    particles->Remove(p); }

  void setStatus(enum CELL_STATUS s) { status = s; }
  void setPressure(float p) { pressure = p; }

private:

  // ==============
  // REPRESENTATION
  Bag<Particle*> *particles;

  // velocities at the center of each face (flowing in the positive direction)
  float u_plus,v_plus,w_plus;
  float new_u_plus,new_v_plus,new_w_plus;

  float pressure;
  enum CELL_STATUS status;

};

#endif

