#include <vector>
#include <cmath>
#include <iostream>



class FloodIsolation {
public:
    FloodIsolation() :
            numberOfCells(20000),
            h(numberOfCells, 0),
            floodedCells(numberOfCells, 0),
            floodedCellsTimeInterval(numberOfCells, 0),
            qInflow(numberOfCells, 0),
            qStartTime(numberOfCells, 0),
            qEndTime(numberOfCells, 0),
            lowerFloorCells(numberOfCells, 0),
            cellLocationX(numberOfCells, 0),
            cellLocationY(numberOfCells, 0),
            cellLocationZ(numberOfCells, 0),
            levelOfCell(numberOfCells, 0),
            valueOfCellIds(numberOfCells, 0),
            h0(numberOfCells, 0),
            vU(numberOfCells, 0),
            vV(numberOfCells, 0),
            vUh(numberOfCells, 0),
            vVh(numberOfCells, 0),
            vUh0(numberOfCells, 0),
            vVh0(numberOfCells, 0),
            ghh(numberOfCells, 0),
            sfx(numberOfCells, 0),
            sfy(numberOfCells, 0),
            qIn(numberOfCells, 0),
            typeInterface(numberOfCells * nEdges, 0),
            neighborIds(numberOfCells * nEdges, 0)
    {
    }
    ~FloodIsolation(){
    }

    void isUpdateNeeded() {
        for (int i = 0; i < numberOfCells; ++i) {
            h[i] =  h[i] + 1;
            floodedCells[i] =  !floodedCells[i];
            floodedCellsTimeInterval[i] =  !floodedCellsTimeInterval[i];
            qInflow[i] =  qInflow[i] + 1;
            qStartTime[i] =  qStartTime[i] + 1;
            qEndTime[i] =  qEndTime[i] + 1;
            lowerFloorCells[i] =  lowerFloorCells[i] + 1;
            cellLocationX[i] =  cellLocationX[i] + 1;
            cellLocationY[i] =  cellLocationY[i] + 1;
            cellLocationZ[i] =  cellLocationZ[i] + 1;
            levelOfCell[i] =  levelOfCell[i] + 1;
            valueOfCellIds[i] =  valueOfCellIds[i] + 1;
            h0[i] =  h0[i] + 1;
            vU[i] =  vU[i] + 1;
            vV[i] =  vV[i] + 1;
            vUh[i] =  vUh[i] + 1;
            vVh[i] =  vVh[i] + 1;
            vUh0[i] =  vUh0[i] + 1;
            vVh0[i] =  vVh0[i] + 1;
            ghh[i] =  ghh[i] + 1;
            sfx[i] =  sfx[i] + 1;
            sfy[i] =  sfy[i] + 1;
            qIn[i] =  qIn[i] + 1;
            for(int j = 0; j < nEdges; ++j) {
                typeInterface[i * nEdges + j] = typeInterface[i * nEdges + j] + 1;
                neighborIds[i * nEdges + j] = neighborIds[i * nEdges + j] + 1;
            }
        }

    }

private:

    const int numberOfCells;
    const int nEdges = 6;
    std::vector<bool> floodedCells;
    std::vector<bool> floodedCellsTimeInterval;

    std::vector<int> neighborIds;
    std::vector<double> valueOfCellIds;
    std::vector<double> h;

    std::vector<double> h0;
    std::vector<double> vU;
    std::vector<double> vV;
    std::vector<double> vUh;
    std::vector<double> vVh;
    std::vector<double> vUh0;
    std::vector<double> vVh0;
    std::vector<double> ghh;
    std::vector<double> sfx;
    std::vector<double> sfy;
    std::vector<double> qInflow;
    std::vector<double> qStartTime;
    std::vector<double> qEndTime;
    std::vector<double> qIn;
    std::vector<double> nx;
    std::vector<double> ny;
    std::vector<double> floorLevels;
    std::vector<int> lowerFloorCells;
    std::vector<bool> flagInterface;
    std::vector<int> typeInterface;
    std::vector<bool> floorCompleteleyFilled;
    std::vector<double> cellLocationX;
    std::vector<double> cellLocationY;
    std::vector<double> cellLocationZ;
    std::vector<int> levelOfCell;
};

int main() {
	{
        // grab a large chunk of contiguous memory and liberate it
        std::vector<double> alloc(20000 * 20);
    }
    FloodIsolation isolation;
    clock_t start = clock();
    for (int i = 0; i < 400; ++i) {
        if(i % 100 == 0) {
            std::cout << i << "\n";
        }
        isolation.isUpdateNeeded();
    }
    clock_t stop = clock();
    std::cout << "Time: " << difftime(stop, start) / 1000 << "\n";
}
