void Item :: createFile()
{
	ofstream outFile;
	char ch;
	outFile.open("ITEM.DAT",ios::binary);
	do
	{
	  clrBox(34,8,70,23);
	  whiteColor();
	  drawBoxTwo(34,11,70,23);
	  gotoxy(46,9);
	  headingColor();
	  cprintf("STOCK CREATION");
	  lightcyanColor();
	  a.getRecord();
	  outFile.write( (char*)&a,sizeof(a) );
	  whiteColor();
	  drawBox(35,20,69,22);
	  gotoxy(37,21);
	  textcolor(YELLOW+BLINK);
	  cprintf("Record is successfully inserted");
	  gotoxy(37,24);
	  yellowColor();
	  cprintf("Do you want to continue (Y/N) ? ");
	  cin >>ch;
	  ch=toupper(ch);
	  gotoxy(37,24);
	  clreol();
	} while ( ch=='Y');
	outFile.close();
}
void Item::addItem(int iNo)
{
	fstream inFile;
	inFile.open("ITEM.DAT",ios::in | ios::binary);
	if(!inFile)
	{
		gotoxy(44,16);
		warningColor();
		cprintf("File does not exist!!");
		cout<<'\a';
		return;
	}
	inFile.read( (char*)&a,sizeof(a) );
	fstream outFile;
	outFile.open("TEMP.DAT",ios::out | ios::binary);
	boolean found = FALSE;
	while( (!inFile.eof()) && (!found) )
	{
		if(iNo == a.itemNo)
		{
			gotoxy(40,18);
			warningColor();
			cprintf("Duplicate Item No.Rejected..!\n");
			cout<<'\a';
			return;
		}
		else
		if(iNo > a.itemNo)
		{
			outFile.write( (char*)&a, sizeof(a) );
			inFile.read( (char*)&a,sizeof(a) );
		}
		else
			found = TRUE;
	}
	Item newRec;
	newRec.itemNo = iNo;
	lightcyanColor();
	newRec.getNewRecord();
	outFile.write( (char*)&newRec, sizeof(newRec) );
	while(inFile)
	{
		outFile.write( (char*)&a, sizeof(a) );
		inFile.read( (char*)&a,sizeof(a) );
	}
	whiteColor();
	drawBox(37,20,73,22);
	gotoxy(39,21);
	textcolor(YELLOW+BLINK);
	cprintf("Item #. %d is successfully added",iNo);
	inFile.close();
	outFile.close();
	remove("ITEM.DAT");
	rename("TEMP.DAT","ITEM.DAT");
}
void Item :: Modify(int iNo)
{
	ifstream inFile("ITEM.DAT",ios::binary);

	if(!inFile)
	{
	  gotoxy(44,16);
	  warningColor();
	  cprintf("File does not exist!!");
	  cout<<'\a';
	  return;
	}

	inFile.close();
	fstream modifyFile;
	modifyFile.open("ITEM.DAT",ios::in | ios::out | ios::binary);

	modifyFile.read( (char*)&a,sizeof(a) );
	boolean found = FALSE;
	int rec = 0;
	while( (!modifyFile.eof()) && (!found) )
	{
		rec++;
		if(iNo == a.itemNo)
		{
			lightcyanColor();
			a.getModifiedRecord();
			modifyFile.seekg( (rec-1)*sizeof(a),ios::beg);
			modifyFile.write( (char*)&a, sizeof(a) );
			found = TRUE;
		}
		else
			modifyFile.read( (char*)&a, sizeof(a) );
	}
	if(found)
	{
		whiteColor();
		drawBox(42,20,69,22);
		gotoxy(44,21);
		textcolor(YELLOW+BLINK);
		cprintf("Item #. %d is modified",iNo);
	}
	else
	{
		 gotoxy(43,16);
		 warningColor();
		 cprintf("Item #. %d Not Found!",iNo);
		 cout<<'\a';
		 remove("TEMP.DAT");
		 return;
	}
	modifyFile.close();
}
void TupColorPalette::setBaseColorsPanel()
{
#ifndef Q_OS_ANDROID
    QSize cellSize(50, 30);
#else
    QSize cellSize(70, 50);
#endif

    k->currentBaseColor = 0;
    QColor redColor(255, 0, 0);
    QBrush redBrush(redColor, k->brush.style());
    TupColorWidget *red = new TupColorWidget(0, redBrush, cellSize, false);
    red->selected();
    connect(red, SIGNAL(clicked(int)), this, SLOT(updateMatrix(int)));
    k->baseColors << red;

    QColor greenColor(0, 255, 0);
    QBrush greenBrush(greenColor, k->brush.style());
    TupColorWidget *green = new TupColorWidget(1, greenBrush, cellSize, false);
    connect(green, SIGNAL(clicked(int)), this, SLOT(updateMatrix(int)));
    k->baseColors << green;

    QColor blueColor(0, 0, 255);
    QBrush blueBrush(blueColor, k->brush.style());
    TupColorWidget *blue = new TupColorWidget(2, blueBrush, cellSize, false);
    connect(blue, SIGNAL(clicked(int)), this, SLOT(updateMatrix(int)));
    k->baseColors << blue;

    QColor whiteColor(255, 255, 255);
    QBrush whiteBrush(whiteColor, k->brush.style());
    TupColorWidget *white = new TupColorWidget(3, whiteBrush, cellSize, false);
    connect(white, SIGNAL(clicked(int)), this, SLOT(updateMatrix(int)));
    k->baseColors << white;

    QBoxLayout *bottomLayout = new QHBoxLayout;
    bottomLayout->setAlignment(Qt::AlignHCenter);
    bottomLayout->setContentsMargins(3, 3, 3, 3);

#ifndef Q_OS_ANDROID
    bottomLayout->setSpacing(10);
#else
    bottomLayout->setSpacing(25);
#endif

    bottomLayout->addWidget(red);
    bottomLayout->addWidget(green);
    bottomLayout->addWidget(blue);
    bottomLayout->addWidget(white);

    k->paletteGlobalLayout->addWidget(new TupSeparator(Qt::Horizontal));
    k->paletteGlobalLayout->addLayout(bottomLayout);
}
void Item::Billing()
{
	normalColor();
	clrscr();
	ifstream inFile;
	inFile.open("ITEM.DAT",ios::in | ios::binary);
	if(!inFile)
	{
		gotoxy(30,12);
		warningColor();
		cprintf("File does not exist!!");
		cout<<'\a';
		delay(500);
		normalColor();
		return;
	}
	fstream recordBill("BILLS.TXT",ios::app);
	inFile.close();
	char* time;
	int billNo;
	int sNo=0;
	int sQty;
	int iNo;
	int itemK=0;
	int lcount;
	float price;
	float amount=0;
	billNo=nextBillNo();
	time=getTime();
	clrscr();
	gotoxy(30,1);
	headingColor();
	cprintf("ABC STORES MANAGEMENT");
	gotoxy(30,2);
	cprintf("---------------------");
	gotoxy(37,3);
	cprintf("BILLING");
	gotoxy(37,4);
	cprintf("-------");
	gotoxy(4,4);
	yellowColor();
	time=getTime();
	cprintf("%s",time);
	lcount=8;
	do
	{
		sNo++;
		whiteColor();
		drawBox(3,5,55,23);
		gotoxy(3,25);
		yellowColor();
		cprintf("Type '0' to item# to end input");
		gotoxy(4,7);
		whiteColor();
		horLine(4,54);
		lightgreenColor();
		gotoxy(5,6);
		cprintf("Item#  Name           Qty       Rate   Price");
		clrBox(57,5,80,23);
		whiteColor();
		drawBox(57,5,80,23);
		gotoxy(58,7);
		whiteColor();
		horLine(58,79);
		lightgreenColor();
		gotoxy(59,6);
		cprintf("Item#  Name");
		normalColor();
		inFile.open("ITEM.DAT",ios::binary);
		int line=8;
		inFile.read((char*)&a,sizeof(a));
		while(inFile)
		{
			gotoxy(59,line); cprintf("%d",itemNo);
			gotoxy(66,line); cprintf("%s",name);
			line++;
			inFile.read((char*)&a,sizeof(a));
		}
		inFile.close();
		gotoxy(5,lcount);
		cin>>iNo;
		if(iNo==0)
		{
			gotoxy(3,25);
			clreol();
			gotoxy(5,lcount);
			clrBox(5,lcount,10,lcount);
			clrBox(57,5,80,23);
			gotoxy(39,lcount+1);
			cprintf("------------");
			gotoxy(30,lcount+2);
			cprintf("Amount = Rs. ");
			gotoxy(43,lcount+2);
			cout<<setw(6)<<amount;
			gotoxy(39,lcount+3);
			cprintf("------------");
			gotoxy(4,lcount+4);
			whiteColor();
			drawBox(4,lcount+4,54,lcount+6);
			gotoxy(20,lcount+5);
			normalColor();
			cprintf("PLEASE PAY Rs. %.2f",amount);
			getch();
			if(itemK)
			{
				recordBill<<"Bill No. "<<billNo<<'\t'<<time;
				recordBill<<"Amount = Rs. "<<amount<<'\n'<<'\n'<<'\n'<<'\n';
			}
			 else
			 {
				ofstream outFile;
				outFile.open("BILL_NO.TXT");
				outFile<<billNo;
			 }
			return;
		}
		inFile.open("ITEM.DAT",ios::binary);
		inFile.read((char*)&a,sizeof(a));
		boolean found=FALSE;
		while(!inFile.eof() && (!found))
		{
			if(iNo==a.itemNo)
				found=TRUE;
			else
				inFile.read((char*)&a, sizeof(a));
		}
		if(found)
		{
			itemK++;
			gotoxy(12,lcount);
			cprintf("%s",a.name);
			clrBox(57,5,80,23);
			whiteColor();
			drawBox(57,5,80,23);
			gotoxy(58,7);
			whiteColor();
			horLine(58,79);
			gotoxy(59,6);
			line=8;
			yellowColor();
			cprintf("Item#    Qty");
			normalColor();
			gotoxy(60,line); cprintf("%d",itemNo);
			gotoxy(68,line); cprintf("%d",qty);
			do
			{
				gotoxy(27,lcount);
				cin>>sQty;
				if(sQty>qty)
				{
					clrBox(27,lcount,35,lcount);
					cout<<'\a';
				}
			}while(sQty>qty);
			fstream modifyFile;
			modifyFile.open("ITEM.DAT",ios::in | ios::out | ios::binary);
			modifyFile.read( (char*)&a,sizeof(a) );
			found = FALSE;
			int rec = 0;
			while( (!modifyFile.eof()) && (!found) )
			{
				rec++;
				if(iNo == a.itemNo)
				{
					a.qty-=sQty;
					modifyFile.seekg( (rec-1)*sizeof(a),ios::beg);
					modifyFile.write( (char*)&a, sizeof(a) );
					found = TRUE;
				}
				else
					modifyFile.read( (char*)&a, sizeof(a) );
			}
			modifyFile.close();
			gotoxy(35,lcount);
			cout<<setw(6)<<rate;
			price=sQty*rate;
			gotoxy(43,lcount);
			cout<<setw(6)<<price;
			amount+=price;
			recordBill<<setw(7)<<setiosflags(ios::left)
				 <<setiosflags(ios::fixed)<<sNo;
			recordBill<<setw(18)<<setiosflags(ios::left)
				 <<setiosflags(ios::fixed)<<a.name;
			recordBill<<setw(10)<<setiosflags(ios::left)
				 <<setiosflags(ios::fixed)<<sQty;
			recordBill<<setw(10)<<setiosflags(ios::left)
				 <<setiosflags(ios::fixed)<<a.rate;
			recordBill<<setw(10)<<setiosflags(ios::left)
				 <<setiosflags(ios::fixed)<<price;
			recordBill.put('\n');
			lcount++;
		}
		else
		{
			gotoxy(5,lcount);
			clrBox(5,lcount,10,lcount);
			cout<<'\a';
		}
		inFile.close();
		if(lcount+5==22)
		{
			clrBox(3,5,55,23);
			lcount=8;
		}
	}while(iNo!=0);
void Item :: removeItem(int iNo)
{
   fstream inFile;
   inFile.open("ITEM.DAT",ios::in | ios::binary);
   if(!inFile)
   {
	  gotoxy(43,16);
	  warningColor();
	  cprintf("File does not exists");
	  cout<<'\a';
	  return;
   }
   inFile.read((char*)&a,sizeof(a));
   fstream outFile;
   outFile.open("TEMP.DAT",ios::out | ios::binary);
   boolean found = FALSE;
   while((!inFile.eof()))
   {
	  if(iNo != a.itemNo)
		 outFile.write((char*)&a, sizeof(a));
	  else
	  {
		 found=TRUE;
		 gotoxy(38,15);
		 lightcyanColor();
		 cprintf("Item Name        : %s",a.name);
		 gotoxy(38,17);
		 cprintf("Quantity         : %d",a.qty);
		 gotoxy(38,19);
		 cprintf("Rate             : %.2f",a.rate);
		 char confirm;
		 whiteColor();
		 drawBox(38,20,72,22);
		 gotoxy(40,21);
		 textcolor(YELLOW);
		 cprintf("Are you sure to delete(Y/N) ?\a ");
		 cin>>confirm;
		 whiteColor();
		 drawBoxTwo(36,11,74,23);
		 if(confirm != 'Y' && confirm != 'y')
		 {
			outFile.write( (char*)&a, sizeof(a) );
		 }
		 else
		 {
			whiteColor();
			drawBoxTwo(36,11,74,23);
			gotoxy(40,21);
			clreol();
			whiteColor();
			drawBoxTwo(36,11,74,23);
			drawBox(38,20,72,22);
			gotoxy(45,21);
			textcolor(YELLOW+BLINK);
			cprintf("Item #. %d is deleted",iNo);
		 }
	  }
	  inFile.read( (char*)&a,sizeof(a) );
   }
   if(!found)
   {
	  gotoxy(44,16);
	  warningColor();
	  cprintf("Item #. %d Not Found!",iNo);
	  cout<<'\a';
	  remove("TEMP.DAT");
	  return;
   }
   inFile.close();
   outFile.close();
   remove("ITEM.DAT");
   rename("TEMP.DAT","ITEM.DAT");
}
Beispiel #7
0
int main( void )
{

	// init random seed equal to current time
	std::srand(std::time(0));

	const unsigned MAX_NR_RECTANGLES = 100;

	// windows size
	int windowWidth = 600;
	int windowHeight = 600;

	// Initialise GLFW
	if(!glfwInit()) {
		std::cerr << "Failed to initialize GLFW" << std::endl;
		return -1;
	}

	glfwWindowHint(GLFW_SAMPLES, 4);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	// Open a window and create its OpenGL context
	// window = glfwCreateWindow( 1024, 768, "Tutorial 03 - Matrices", NULL, NULL);
	window = glfwCreateWindow(windowWidth, windowHeight, "Mondrian", NULL, NULL);
	if(window == NULL) {
		std::cerr << "Failed to open GLFW window.";
		std::cerr << " If you have an Intel GPU, they are not 3.3 compatible.";
		std::cerr << " Try the 2.1 version of the tutorials." << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);

	// Initialize GLEW
	glewExperimental = true; // Needed for core profile
	if (glewInit() != GLEW_OK) {
		std::cerr << "Failed to initialize GLEW" << std::endl;
		return -1;
	}

	// enable z-buffer
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);

	// Ensure we can capture the escape key being pressed below
	glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
	glfwSetMouseButtonCallback(window, mouseButtonCallback);

	// white background
	glm::vec4 whiteColor (1.0f, 1.0f, 1.0f, 0.0f);
	glClearColor(whiteColor.r, whiteColor.g, whiteColor.b, whiteColor.a);

	// nr rectangles * 2 triangles each * 3 vertices * 4 floats
	float cpuBufferDataPoints[MAX_NR_RECTANGLES * 2 * 3 * 4];
	float cpuBufferColors[MAX_NR_RECTANGLES * 2 * 3 * 4];
	// nr rectangles * 2 triangles each * 3 vertices * 4x4 floats
	float cpuBufferMVProw1[MAX_NR_RECTANGLES * 2 * 3 * 4];
	float cpuBufferMVProw2[MAX_NR_RECTANGLES * 2 * 3 * 4];
	float cpuBufferMVProw3[MAX_NR_RECTANGLES * 2 * 3 * 4];
	float cpuBufferMVProw4[MAX_NR_RECTANGLES * 2 * 3 * 4];
	float *cpuBufferLines;

	// Create and compile our GLSL program from the shaders
	GLuint rectangleProgram = LoadShaders( "rectangleVertexShader.glsl", "rectangleFragmentShader.glsl" );
	GLuint lineProgram = LoadShaders( "lineVertexShader.glsl", "lineFragmentShader.glsl" );

	// Use our shader (it's not required to be using a program to bind VAOs)
	glUseProgram(rectangleProgram);

	// VAOs
	GLuint rectangleVAO;
	GLuint lineVAO;
	glGenVertexArrays(1, &rectangleVAO);
	glGenVertexArrays(1, &lineVAO);
	glBindVertexArray(rectangleVAO);

	// left, right, bottom, top, angle1, angle2
	// glm::mat4 Projection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f,0.0001f,10.0f); // In world coordinates
	glm::mat4 Projection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f); // In world coordinates
	for (unsigned row = 0; row < 4; row++) {
		for (unsigned col = 0; col < 4; col++) {
			std::cout << std::setw(10) << Projection[col][row] << " ";
		}
		std::cout << std::endl;
	}

	glm::vec4 testvertex;
	for (int i = -10; i <= 10; i++) {
		testvertex = glm::vec4(1.0);
		testvertex.z = i;
		testvertex = Projection * testvertex;
		std::cout << "z = " << std::setw(3) << i << " " << testvertex.z << std::endl;
	}
	std::cout << std::endl;

	// glm::mat4 Projection = glm::ortho(-20.0f, 20.0f, -20.0f, 20.0f,1.0f,100.0f); // In world coordinates
	/*
	glm::mat4 Projection = glm::perspective(
		45.0f,         // The horizontal Field of View, in degrees : the amount of "zoom". Think "camera lens". Usually between 90° (extra wide) and 30° (quite zoomed in)
		4.0f / 4.0f, // Aspect Ratio. Depends on the size of your window. Notice that 4/3 == 800/600 == 1280/960, sounds familiar ?
		0.1f,        // Near clipping plane. Keep as big as possible, or you'll get precision issues.
		100.0f       // Far clipping plane. Keep as little as possible.
	);		
	*/
	// Camera matrix
	/*
	 * view es una matriz cuadrada almacenada por columnas (no por filas)
	 * al poner la camara mirando al origen en una posicion z=2 (positivo),
	 * lo que hace, es generar una matriz de transformación que moverá el objeto
	 * en el eje z dos unidades de "w" */
	glm::mat4 View = glm::lookAt(
		glm::vec3(0,0,2), // Camera is at (4,3,3), in World Space
		glm::vec3(0,0,0), // and looks at the origin
		glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
	);
	// glm::mat4 View = glm::mat4(1.0f);
	/*
	for (unsigned row = 0; row < 4; row++) {
		for (unsigned col = 0; col < 4; col++) {
			std::cout << std::setw(3) << View[col][row] << " ";
		}
		std::cout << std::endl;
	}
	*/

	GLuint rectangleVertexBuffer;
	glGenBuffers(1, &rectangleVertexBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, rectangleVertexBuffer);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(
		0,					// attribute. No particular reason for 0, but must match the layout in the shader.
		4,					// size
		GL_FLOAT,			// type
		GL_FALSE,			// normalized?
		0,					// stride
		(void*)0			// array buffer offset
	);

	GLuint rectangleColorBuffer;
	glGenBuffers(1, &rectangleColorBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, rectangleColorBuffer);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(
		1,					// attribute. No particular reason for 0, but must match the layout in the shader.
		4,					// size
		GL_FLOAT,			// type
		GL_FALSE,			// normalized?
		0,					// stride
		(void*)0			// array buffer offset
	);

	// GLuint rectangleMVPBuffer;
	GLuint rectangleMVProw1Buffer;
	GLuint rectangleMVProw2Buffer;
	GLuint rectangleMVProw3Buffer;
	GLuint rectangleMVProw4Buffer;
	glGenBuffers(1, &rectangleMVProw1Buffer);
	glGenBuffers(1, &rectangleMVProw2Buffer);
	glGenBuffers(1, &rectangleMVProw3Buffer);
	glGenBuffers(1, &rectangleMVProw4Buffer);
	glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw1Buffer);
	glEnableVertexAttribArray(2);
	glVertexAttribPointer(
		2,										// attribute. No particular reason for 0, but must match the layout in the shader.
		4,												// size
		GL_FLOAT,								// type
		GL_FALSE,								// normalized?
		0,		// stride
		(void*)(0)								// array buffer offset
	);
	glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw2Buffer);
	glEnableVertexAttribArray(3);
	glVertexAttribPointer(
		3,										// attribute. No particular reason for 0, but must match the layout in the shader.
		4,												// size
		GL_FLOAT,								// type
		GL_FALSE,								// normalized?
		0,		// stride
		(void*)(0)								// array buffer offset
	);
	glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw3Buffer);
	glEnableVertexAttribArray(4);
	glVertexAttribPointer(
		4,										// attribute. No particular reason for 0, but must match the layout in the shader.
		4,												// size
		GL_FLOAT,								// type
		GL_FALSE,								// normalized?
		0,		// stride
		(void*)(0)								// array buffer offset
	);
	glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw4Buffer);
	glEnableVertexAttribArray(5);
	glVertexAttribPointer(
		5,										// attribute. No particular reason for 0, but must match the layout in the shader.
		4,												// size
		GL_FLOAT,								// type
		GL_FALSE,								// normalized?
		0,		// stride
		(void*)(0)								// array buffer offset
	);

	glBindVertexArray(lineVAO);
	GLuint lineVertexBuffer;
	glGenBuffers(1, &lineVertexBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, lineVertexBuffer);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(
		0,					// attribute. No particular reason for 0, but must match the layout in the shader.
		2,					// size
		GL_FLOAT,			// type
		GL_FALSE,			// normalized?
		0,					// stride
		(void*)0			// array buffer offset
	);

	// get a handle for MVP uniform matrix in line program (it's not required
	// to be using the line program right now
	// GLuint lineMVPID = glGetUniformLocation(lineProgram, "MVP");

	glBindVertexArray(rectangleVAO);


	std::set<float> verticalLines;
	std::set<float> horizontalLines;
	unsigned nrLines = 0;

	unsigned simulationTime = 0;
	bool justEnded = true;

	double lineThickness = 0.1;
		
	do {

		// update window's title to show fps
		updateFPSCounter(window);

		// Clear the screen
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// update viewport 
		glfwGetWindowSize(window, &windowWidth, &windowHeight);
		glViewport(0, 0, windowWidth, windowHeight);	// (x,y) offset from lower left; (width, height)

		// std::cout << "nr rectangles: " << rectangles.size() << std::endl;

		// every 75 steps, create a new rectangle
		if (simulationTime % 500 == 0 && !endSimulation && rectangles.size() < MAX_NR_RECTANGLES) {
				// create rectangle
				Rectangle rectangle;
				// insert rectangle into array
				rectangles.push_back(rectangle);
		}

		// update cpu buffers

		// fill up new cpu position buffers
		float rectangleCoords[2 * 3 * 4];
		unsigned coordCounter = 0;
		for (unsigned i = 0; i < rectangles.size(); i++) {
				rectangles[i].getCoords(rectangleCoords);
				for (unsigned j = 0; j < 2*3*4; j++) {
						cpuBufferDataPoints[coordCounter] = rectangleCoords[j];
						coordCounter++;
				}
				// std::cout << "rectangle ID: " << rectangles[i].getID() << std::endl;
				// std::cout << "horizontal: [" << rectangles[i].getLeft() << " : " << rectangles[i].getRight() << "]" << std::endl;
				// std::cout << "vertical: [" << rectangles[i].getBottom() << " : " << rectangles[i].getTop() << "]" << std::endl;
		}

		// fill up new cpu colors buffers
		float rectangleColorComponents[2 * 3 * 4];
		coordCounter = 0;
		for (unsigned i = 0; i < rectangles.size(); i++) {
				rectangles[i].getColorComponents(rectangleColorComponents);
				for (unsigned j = 0; j < 2*3*4; j++) {
						cpuBufferColors[coordCounter] = rectangleColorComponents[j];
						coordCounter++;
				}
		}

		// fill up new cpu mvp buffers
		unsigned counter = 0;
		for (unsigned i = 0; i < rectangles.size(); i++) {
			glm::mat4 Model = rectangles[i].getModel();
			// glm::mat4 MVP = Projection * View * Model;
			glm::mat4 MVP = Projection * Model * View;
			// TODO: try to transfer glm::mat MVP to buffer directly with glBufferData
			// glm::vec4 vertexa = Model * rectangles[i].getVertexA();
			// glm::vec4 vertexb = Model * rectangles[i].getVertexB();
			// glm::vec4 vertexc = Model * rectangles[i].getVertexC();
			// glm::vec4 vertexd = Model * rectangles[i].getVertexD();

			// std::cout << "final positions: " << std::endl;
			// std::cout << vertexa.x << " " << vertexa.y << " " << vertexa.z << std::endl;
			// std::cout << vertexb.x << " " << vertexb.y << " " << vertexb.z << std::endl;
			// std::cout << vertexc.x << " " << vertexc.y << " " << vertexc.z << std::endl;
			// std::cout << vertexd.x << " " << vertexd.y << " " << vertexd.z << std::endl;

			for (unsigned vertex = 0; vertex < 6; vertex++) {
				for (unsigned element = 0; element < 4; element++) {
					// cpuBufferMVProw1[counter] = static_cast<int>(MVP[0][element]);
					// cpuBufferMVProw2[counter] = static_cast<int>(MVP[1][element]);
					// cpuBufferMVProw3[counter] = static_cast<int>(MVP[2][element]);
					// cpuBufferMVProw4[counter] = static_cast<int>(MVP[3][element]);

					// TODO swap these lines
					cpuBufferMVProw1[counter] = MVP[0][element];
					cpuBufferMVProw2[counter] = MVP[1][element];
					cpuBufferMVProw3[counter] = MVP[2][element];
					cpuBufferMVProw4[counter] = MVP[3][element];

					// for these ones
					// cpuBufferMVProw1[counter] = MVP[element][0];
					// cpuBufferMVProw2[counter] = MVP[element][1];
					// cpuBufferMVProw3[counter] = MVP[element][2];
					// cpuBufferMVProw4[counter] = MVP[element][3];

					// std::cout << "double: " << std::endl;
					// std::cout << MVP[0][element] << " ";
					// std::cout << MVP[1][element] << " ";
					// std::cout << MVP[2][element] << " ";
					// std::cout << MVP[3][element] << std::endl;
					// std::cout << "int: " << std::endl;
					// std::cout << cpuBufferMVProw1[counter] << " ";
					// std::cout << cpuBufferMVProw2[counter] << " ";
					// std::cout << cpuBufferMVProw3[counter] << " ";
					// std::cout << cpuBufferMVProw4[counter] << std::endl;
					counter++;
				}
			}
		}

		glUseProgram(rectangleProgram);
		glBindVertexArray(rectangleVAO);

		// transfer data to position and color buffers
		glBindBuffer(GL_ARRAY_BUFFER, rectangleVertexBuffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * rectangles.size() * 2 * 3 * 4, cpuBufferDataPoints, GL_STREAM_DRAW);

		glBindBuffer(GL_ARRAY_BUFFER, rectangleColorBuffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * rectangles.size() * 2 * 3 * 4, cpuBufferColors, GL_STREAM_DRAW);

		glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw1Buffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * rectangles.size() * 2 * 3 * 4, cpuBufferMVProw1, GL_STREAM_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw2Buffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * rectangles.size() * 2 * 3 * 4, cpuBufferMVProw2, GL_STREAM_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw3Buffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * rectangles.size() * 2 * 3 * 4, cpuBufferMVProw3, GL_STREAM_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw4Buffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * rectangles.size() * 2 * 3 * 4, cpuBufferMVProw4, GL_STREAM_DRAW);

		// draw rectangles
		glDrawArrays(GL_TRIANGLES, 0, rectangles.size()*2*3); // 3 indices starting at 0 -> 1 triangle

		for (unsigned i = 0; i < rectangles.size(); i++) {
			// std::cout << "updating rectangle id: " << i << std::endl;
			rectangles[i].updateModel();
			rectangles[i].shouldBeAlive();
		}

		for (std::vector<Rectangle>::iterator it = rectangles.begin(); it != rectangles.end();) {
			if (it->isAlive()) {
				it++;
			} else {
				it = rectangles.erase(it);
			}
		}

		if (endSimulation && !justEnded) {
			glUseProgram(lineProgram);
			glBindVertexArray(lineVAO);
			// std::cout << "drawing lines..." << std::endl;
			glDrawArrays(GL_TRIANGLES, 0, nrLines * 2 * 3); // 3 indices starting at 0 -> 1 triangle
		}

		if (endSimulation && justEnded) {

			std::cout << "creating lines..." << std::endl;
			justEnded = false;

			// load data in cpuBufferLines just the very first time

			// get vertical and horizontal coords of every line that should be drawn
			for (unsigned i = 0; i < rectangles.size(); i++) {
				if (rectangles[i].getIsPinned()) {
					// values in {-10:10}
					int left = static_cast<int>(round(rectangles[i].getLeft()));
					int right = static_cast<int>(round(rectangles[i].getRight()));
					int bottom = static_cast<int>(round(rectangles[i].getBottom()));
					int top = static_cast<int>(round(rectangles[i].getTop()));
					std::cout << "left: " << left << " right: " << right << " top: " << top << " bottom: " << bottom << std::endl;
					verticalLines.insert(left);
					verticalLines.insert(right);
					horizontalLines.insert(bottom);
					horizontalLines.insert(top);
				}
			}

			unsigned nrVerticalLines = verticalLines.size();
			unsigned nrHorizontalLines = horizontalLines.size();
			nrLines = nrVerticalLines + nrHorizontalLines;
			std::cout << "nr lines to draw: " << nrLines << std::endl;
			// 1 line = 2 triangles; 1 triangle = 3 points each; 1 point = 2 coord each;
			cpuBufferLines = new float[nrLines * 2 * 3 * 2];
			unsigned counter = 0;
			glm::mat4 PV = Projection * View;
			for (std::set<float>::iterator it = verticalLines.begin(); it != verticalLines.end(); it++) {
				glm::vec4 vertexA (*it - lineThickness, 10, 0, 1);
				glm::vec4 vertexB (*it + lineThickness, 10, 0, 1);
				glm::vec4 vertexC (*it - lineThickness, -10, 0, 1);
				glm::vec4 vertexD (*it + lineThickness, -10, 0, 1);
				vertexA = PV * vertexA;
				vertexB = PV * vertexB;
				vertexC = PV * vertexC;
				vertexD = PV * vertexD;
				// glm::vec4 firstPointMVP = Projection * View * firstPoint;
				// glm::vec4 secondPointMVP = Projection * View * secondPoint;
				// sent the points in {-10:10} domain
				// first triangle ABC
				cpuBufferLines[counter] = vertexA.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexA.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexB.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexB.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexC.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexC.y;		// y
				counter++;
				// second triangle BCD
				cpuBufferLines[counter] = vertexB.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexB.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexC.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexC.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexD.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexD.y;		// y
				counter++;
				// std::cout << "vertical line: " << std::endl;
				// std::cout << "(" << firstPointMVP.x << "," << firstPointMVP.y << ")" << std::endl;
				// std::cout << "(" << secondPointMVP.x << "," << secondPointMVP.y << ")" << std::endl;
			}

			for (std::set<float>::iterator it = horizontalLines.begin(); it != horizontalLines.end(); it++) {
				glm::vec4 vertexA (-10, *it + lineThickness, 0, 1);
				glm::vec4 vertexB (10, *it + lineThickness, 0, 1);
				glm::vec4 vertexC (-10, *it - lineThickness, 0, 1);
				glm::vec4 vertexD (10, *it - lineThickness, 0, 1);
				vertexA = PV * vertexA;
				vertexB = PV * vertexB;
				vertexC = PV * vertexC;
				vertexD = PV * vertexD;
				// glm::vec4 firstPointMVP = Projection * View * firstPoint;
				// glm::vec4 secondPointMVP = Projection * View * secondPoint;
				// first triangle ABC
				cpuBufferLines[counter] = vertexA.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexA.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexB.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexB.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexC.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexC.y;		// y
				counter++;
				// second triangle BCD
				cpuBufferLines[counter] = vertexB.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexB.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexC.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexC.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexD.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexD.y;		// y
				counter++;
				// std::cout << "horizontal line: " << std::endl;
				// std::cout << "(" << firstPointMVP.x << "," << firstPointMVP.y << ")" << std::endl;
				// std::cout << "(" << secondPointMVP.x << "," << secondPointMVP.y << ")" << std::endl;
			}

			glBindBuffer(GL_ARRAY_BUFFER, lineVertexBuffer);
			glBufferData(GL_ARRAY_BUFFER, sizeof(float) * nrLines * 2 * 3 * 2, cpuBufferLines, GL_STATIC_DRAW);


			// send MVP matrix to line program
			// TODO: check if i need to be using line program and to have bound line VAO
			// glUniformMatrix4fv(lineMVPID, 1, GL_FALSE, &PV[0][0]);
		}

		// Swap buffers
		glfwSwapBuffers(window);
		glfwPollEvents();
		// usleep(500000);
		// usleep(100000);

		simulationTime++;

		// int dummy;
		// std::cin >> dummy;

	} while ( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 );


	glBindVertexArray(rectangleVAO);
	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);

	glBindVertexArray(lineVAO);
	glDisableVertexAttribArray(0);

	// Cleanup VBO and shader
	glDeleteBuffers(1, &rectangleVertexBuffer);
	glDeleteBuffers(1, &rectangleColorBuffer);
	glDeleteBuffers(1, &rectangleMVProw1Buffer);
	glDeleteBuffers(1, &rectangleMVProw2Buffer);
	glDeleteBuffers(1, &rectangleMVProw3Buffer);
	glDeleteBuffers(1, &rectangleMVProw4Buffer);
	glDeleteBuffers(1, &lineVertexBuffer);
	glDeleteProgram(rectangleProgram);
	glDeleteProgram(lineProgram);
	glDeleteVertexArrays(1, &rectangleVAO);
	glDeleteVertexArrays(1, &lineVAO);

	// Close OpenGL window and terminate GLFW
	glfwTerminate();

	delete [] cpuBufferLines;				// make sure new was executed, i.e: right click event

	return 0;
}