//-------------------------------------------------------------
void ofApp::generateAsteroids(int numAsteroids)
{
	float randSize = 0.0f;

	for ( int i = 0; i < numAsteroids; i++ ) 
	{
		// Logic to generate the Asteroids in different sizes
		// these are right now 120, 80, 40 and 20 (minimum)
		int randValue = ofRandom(0, 3);
		if(randValue == 2){
			randSize = 120;
		}
		else 
		{
			if(randValue == 1)
			{
				randSize = 80;
			}
			else 
			{
				randSize = 40;
			}
		}

		int asteroidShape = ofRandom(asteroidsDefinitions.size());

		Asteroid* temp = new Asteroid();
		temp->setup(asteroidsDefinitions.at(asteroidShape), randSize, ofRandom(100, 250), ofRandom(-PI, PI), 
			ofPoint(ofRandom(0, ofGetWidth()), ofRandom(0, ofGetHeight())), 
			ofPoint(ofRandom(-1, 1), ofRandom(-1, 1)).normalize());
		asteroids.push_back(temp);
	}
}
void ofApp::splitAsteroid(int which)
{
	int asteroidShape = 0;

	if(asteroids[which]->getSize() > 20) 
	{
		for(int i = 0; i < (asteroids[which]->getSize()/40)+1; i++) 
		{
			asteroidShape = ofRandom(asteroidsDefinitions.size());

			Asteroid* newAsteroid = new Asteroid();
			newAsteroid->setup(asteroidsDefinitions.at(asteroidShape), asteroids[which]->getSize()/2, asteroids[which]->getSpeed(), asteroids[which]->getRotation(), asteroids[which]->getPosition(), ofPoint(-(ofRandom(-1, 1)), ofRandom(-1, 1)));
			asteroids.push_back(newAsteroid);
		}
	} 

	asteroids.erase(asteroids.begin() + which);

	if(asteroids.size() == 0) 
	{
		generateAsteroids(ofRandom(4,6));
	}

	//Play sound explosion
	explosion.play();

	//GUI Data Update
	if(getSpaceShip(1)){
		Player1Lifes = ofToString (getSpaceShip(1)->getLifes());
		Player1Score = ofToString (getSpaceShip(1)->getPoints());
		switch(getSpaceShip(1)->getLifes())	{
		case 0: serialConnection.writeByte('s'); break;
		case 1: serialConnection.writeByte('o'); break;
		case 2: serialConnection.writeByte('w'); break;
		case 3: serialConnection.writeByte('h'); break;
		}
	}
	if(getSpaceShip(2)){
		Player2Lifes = ofToString (getSpaceShip(2)->getLifes());
		Player2Score = ofToString (getSpaceShip(2)->getPoints());
		switch(getSpaceShip(2)->getLifes())	{
		case 0: serialConnection.writeByte('f'); break;
		case 1: serialConnection.writeByte('u'); break;
		case 2: serialConnection.writeByte('d'); break;
		case 3: serialConnection.writeByte('t'); break;
		}
	}
}
void ofApp::getRenderFromServer()
{	
	while(clientReceiver.hasWaitingMessages())
	{
		// the data is updated and (therefore) replaced every frane !
		asteroids.clear();
		players[0]->bullets.clear();
		players[1]->bullets.clear();

		// message m from the server will contain:
		// numer of asteroids
		// position of each asteroid
		// rotation of each asteroid
		// size of each asteroid
		// position of each player
		// rotation of each player
		// number of bullets of each player
		// position of each bullet of each player
		// points of each player
		// powerup type
		// game finished (bool)

		ofxOscMessage m;
		clientReceiver.getNextMessage(&m);

		///////////////////////////////////////////////////////////////////
		// ASTEROIDS // ASTEROIDS // ASTEROIDS // ASTEROIDS // ASTEROIDS //
		///////////////////////////////////////////////////////////////////

		int numasteroids = m.getArgAsInt32(0); // num of asteroids

		Asteroid* temp;

		// for each asteroid we will receive: 1 position x, 2 position y, 3 size, and 4 rotation
		for (int i = 0; i < numasteroids; i++)
		{						
			temp = new Asteroid();
			// SETUP ( shape = 0, size, speed = 0, rotation, position, direction )
			temp->setup( asteroidsDefinitions.at(IDONTCARE), m.getArgAsFloat(4*i+3), IDONTCARE, m.getArgAsFloat(4*i+4), ofPoint(m.getArgAsInt32(4*i+1), m.getArgAsInt32(4*i+2)), ofPoint(1.0, 1.0));
			// we decided to use shape 0 to avoid sending the shape over udp but 
			// it would be as easy as to add a new integer as a message argument
			asteroids.push_back(temp);
		}
		
		int lastposition = numasteroids*4; // to avoid long formulas we will be using a last position index

		//////////////////////////////////////////////////////////////////////////
		// PLAYER 1 // PLAYER 1 // PLAYER 1 // PLAYER 1 // PLAYER 1 // PLAYER 1 //
		//////////////////////////////////////////////////////////////////////////

		// for PLAYER 1 we will receive its position x and y, its rot and the information about its bullets
		players[0]->setPosition(ofPoint(m.getArgAsInt32(lastposition+1), m.getArgAsInt32(lastposition+2)));
		players[0]->setRotation(m.getArgAsFloat(lastposition+3));

		Bullet* newbullet;
		int numbullets = m.getArgAsInt32(lastposition+4);
		// for each bullet we will receive: 1 position x, 2 position y
		for (int j = 0; j < numbullets; j++)
		{
			newbullet = new Bullet();
			newbullet->setSize(1.2); // fixed bullet size
			newbullet->setPosition(ofPoint(m.getArgAsInt32(lastposition+2*j+5), m.getArgAsInt32(lastposition+2*j+6)));
			players[0]->bullets.push_back(newbullet);
		}

		players[0]->points = m.getArgAsInt32(lastposition+2*numbullets+5);

		lastposition += 2*numbullets+5; // last position + all the information about player 1

		//////////////////////////////////////////////////////////////////////////
		// PLAYER 2 // PLAYER 2 // PLAYER 2 // PLAYER 2 // PLAYER 2 // PLAYER 2 //
		//////////////////////////////////////////////////////////////////////////

		// for PLAYER 2 we will receive its position x and y, its rot and the information about its bullets
		players[1]->setPosition(ofPoint(m.getArgAsInt32(lastposition+1), m.getArgAsInt32(lastposition+2)));
		players[1]->setRotation(m.getArgAsFloat(lastposition+3));

		int numbullets2 = m.getArgAsInt32(lastposition+4);
		// for each bullet we will receive: 1 position x, 2 position y
		for (int j = 0; j < numbullets2; j++)
		{
			newbullet = new Bullet();
			newbullet->setSize(1.2); // fixed bullet size
			newbullet->setPosition(ofPoint(m.getArgAsInt32(lastposition+2*j+5), m.getArgAsInt32(lastposition+2*j+6)));
			players[1]->bullets.push_back(newbullet);
		}

		players[1]->points = m.getArgAsInt32(lastposition+numbullets2*2+5);
		cout << players[1]->points << endl;

		lastposition += numbullets2*2+5;
		
		//////////////////////////////////////////////////////////////////////////////////////////
		// POWERUP // POWERUP // POWERUP // POWERUP // POWERUP // POWERUP // POWERUP // POWERUP //
		//////////////////////////////////////////////////////////////////////////////////////////

		powerup.setType(m.getArgAsInt32(lastposition+1));
		ofPoint powerupposition = ofPoint(m.getArgAsInt32(lastposition+2),m.getArgAsInt32(lastposition+3));

		switch (powerup.getType())
		{
		case 1:
			powerup.setup("firePowerUp.png", powerupposition, powerup.getType(), 10);
			break;
		case 2:
			powerup.setup("speedPowerUp.png", powerupposition, powerup.getType(), 10);
			break;
		case 3:
			powerup.setup("scorePowerUp.png", powerupposition, powerup.getType(), 10);
			break;
		default:
			break;
		}

		//////////////////////////////////////////////////////////////////////////////////
		// GAME ENDED ? // GAME ENDED ? // GAME ENDED ? // GAME ENDED ? // GAME ENDED ? //
		//////////////////////////////////////////////////////////////////////////////////

		if (m.getArgAsInt32(lastposition+4) == 1) gameFinish();

	}
}