// GraphicsTemplate.cpp
// 
//////////////////////////////////////////////////////////////////////////////////////////
// includes 
//////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "iostream"
#include"time.h"
using namespace std;
//////////////////////////////////////////////////////////////////////////////////////////
// externals 
//////////////////////////////////////////////////////////////////////////////////////////
extern cRenderClass graphics;
extern cShell* shell = new cShell[shellnumber];
//you can easily change the numbers of the shell as well as the numbers of the particles each shell contains as you want in global.h 
void processNormalKeys(unsigned char key, int x, int y)
{
	switch (key)
	{
	case 'e':
	{
		//if you press e in the game interface, it will make this program no longer generate(recycle) particle array,
		//although the previously generated one will run its life span


		for (int i = 0; i < shellnumber; i++) {
			shell[i].s_recycle = false;
		}

		break;
	}
	}
}

//////////////////////////////////////////////////////////////////////////////////////////
// mouseFunc - mouse input callback function
//////////////////////////////////////////////////////////////////////////////////////////
void mouseFunc(int button, int state, int mouse_x, int mouse_y)
{
	if (state == GLUT_UP)
	{
	}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// passiveMotionFunc() - process passive mouse movements
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void passiveMotionFunc(int mouse_x, int mouse_y)
{
}

//////////////////////////////////////////////////////////////////////////////////////////
// renderScene() - render the scene
//////////////////////////////////////////////////////////////////////////////////////////
void renderScene()
{

		srand(time(NULL));
	// set a colour
	for (int i = 0; i < shellnumber; i++) {
		for (int j = 0; j < particlenumber; j++) {
			if (shell[i].particle[j].c_life >= 2 * (shell[i].particle[j].getCurrentTime() - shell[i].particle[j].c_starttime))
			{
				graphics.setColour(0.9f, 0.5f, 0.7f);
			}
			else {//if the particle has run out of its half life, the color will change
				graphics.setColour(0.3*i*(rand()%10)/1.0, 0.3 * j*(rand() % 10) / 2.0, 0.3 * i*j*(rand() % 10) / 3.0);
			}
		}
	}
	//graphics.setColour( 1.0f, 0.5f, 0.1f );
	
	// set pixel size..
	graphics.setPointSize(4);

	/////////////////////////////////////////////
	// render your particle here..
	/////////////////////////////////////////////
	
	for (int i = 0; i < shellnumber; i++) {
		
		for (int j = 0; j < particlenumber; j++) {
			
			graphics.drawPixel(shell[i].particle[j].c_posx, shell[i].particle[j].c_posy);
	
		}
	}

	// draw to an off screen buffer

	// render the scene
	graphics.render();
}

//////////////////////////////////////////////////////////////////////////////////////////
// update() - update function
//////////////////////////////////////////////////////////////////////////////////////////
void update()
{


	for (int i = 0; i < shellnumber; i++) {

		if (shell[i].s_fly_active == false&&shell[i].s_recycle==true) {
			
			shell[i].Init();
			//cout << "the number of bytes per shell is " << sizeof(shell[i]);
			//you can use this to see the number of bytes of every shell after the Init function
		}
	}
	/////////////////////////////////////////////
	// update your particle here..
	/////////////////////////////////////////////
	
	//every shell after declared has an attribute called s_fly_active, and its value is false,
	//every particle is allowed to move or show after the Init function in shell object(the s_fly_active becomes true), 
	//particle array declared, and within the particle's life, the attribute is always true, when the particle run out of its life or touch the screen, s_fly_active will become
	//false, then the particle is not allowed to move or show and it will be deleted, after that, because the attribute s_fly_active is false, the function Init is called again
	for (int i = 0; i < shellnumber; i++) {
		if (shell[i].s_fly_active)
		{
			shell[i].particlemove();

		}
	}

	for (int i = 0; i < shellnumber; i++) {
		if (shell[i].s_fly_active)
		{
			for (int j = 0; j < particlenumber; j++) {
				//when the particles has run out of its half life
				if (shell[i].particle[j].c_life <= 2 * (shell[i].particle[j].getCurrentTime() - shell[i].particle[j].c_starttime))
				{
					shell[i].changevel(shell[i]);
				}
			}
		}	
	}
	int deletenumber = 0;
	for (int i = 0; i < shellnumber; i++) {
		if (shell[i].s_fly_active == false && shell[i].s_recycle == false) {
			deletenumber++;
		}
	}
	if (deletenumber == shellnumber){
		cout << "the firework has ended,thank you for using!";
		for (int i = 0; i < shellnumber; i++) {
			delete[i]shell;
			//when all of the shell is deleted, exit the program
		}
		exit(0);

	}
	// always re-render the scene..
	renderScene();
}



//////////////////////////////////////////////////////////////////////////////////////////
// _tmain() - program entry point
//////////////////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{	
	


	cout <<"press s to start game" << endl;
	cout <<"press e to exit" << endl;
	while (true)
	{
		char enter;
		cin >> enter;
		if (enter == 's')
		{
			break;
		}
	}
	// init glut stuff..
	graphics.create(argc, argv);

	// good place for one-off initialisations and objects creation..

	// enter game loop..
	graphics.loop();	

	return 0;
}




