void Application::Shoot(Projectile::PROJECTILE_TYPE type)
{
	Projectile* p = FetchProjectile();
	if (p)
	{
		float posX = ships_.at(0)->GetX();
		float posY = ships_.at(0)->GetY();
		switch (type)
		{
		case Projectile::PROJ_BULLET:
			{
				// TODO: Find pos
				p->Init(ships_.at(0), type, posX, posY, ships_.at(0)->GetW());
				p->SetDamage(1);
				p->SetSpeed(400.f);
				bulletShootTimer = 0.f;
			}
			break;
		case Projectile::PROJ_SEEKING_MISSLE:
			{
				// TODO: Find pos
				p->Init(ships_.at(0), type, posX, posY, ships_.at(0)->GetW());
				p->SetDamage(5);
				p->SetSpeed(250.f);
				p->SetTarget(FindNearest());
				missileShootTimer = 0.f;
			}
			break;
		}

		RakNet::BitStream bs;
		bs.Write((unsigned char)ID_SHOOT);
		bs.Write(p->GetID());
		bs.Write(p->GetType());
		bs.Write(p->GetX());
		bs.Write(p->GetY());
		bs.Write(p->GetW());
		bs.Write(p->GetVelocityX());
		bs.Write(p->GetVelocityY());
		bs.Write(p->GetSpeed());
		bs.Write(p->GetDamage());
		bs.Write(p->GetOwner()->GetID());
		// Send target if available
		if (p->GetTarget())
		{
			bs.Write(p->GetTarget()->GetID());
		}
		else
		{
			bs.Write(-1);
		}
		rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
	}
}
/**
* Update cycle
*
* Checks for keypresses:
*   - Esc - Quits the game
*   - Left - Rotates ship left
*   - Right - Rotates ship right
*   - Up - Accelerates the ship
*   - Down - Deccelerates the ship
*
* Also calls Update() on all the ships in the universe
*/
bool Application::Update()
{
	float timedelta = hge_->Timer_GetDelta();
	if (bulletShootTimer < S_BULLET_SHOOT_INTERVAL)
	{
		bulletShootTimer += timedelta;
	}
	if (missileShootTimer < S_MISSILE_SHOOT_INTERVAL)
	{
		missileShootTimer += timedelta;
	}

	ships_.at(0)->SetAngularVelocity(0.0f);

	// Lab 13 Task 4 : Add a key to shoot missiles
	/*if (hge_->Input_GetKeyState(HGEK_ENTER))
	{
		if (!keydown_enter)
		{
			CreateMissile(ships_.at(0)->GetX(), ships_.at(0)->GetY(), ships_.at(0)->GetW(), ships_.at(0)->GetID());
			keydown_enter = true;
		}
	}
	else
	{
		if (keydown_enter)
		{
			keydown_enter = false;
		}
	}*/

	static const float MAX_ENTER_TIMER = 0.5f;
	static float enterTimer;

	if (enterTimer < MAX_ENTER_TIMER)
	{
		enterTimer += timedelta;
	}

	// Chat
	if (chatMode)
	{
		char input = hge_->Input_GetKey();

		if (input == HGEK_ESCAPE)
		{
			chatMode = false;
			typingMsg = "";
		}
		else if (input == HGEK_ENTER && enterTimer >= MAX_ENTER_TIMER)
		{
			// Send
			if (typingMsg != "")
			{
				RakNet::BitStream chatBS;
				chatBS.Write((unsigned char)ID_CHAT_SEND);
				chatBS.Write(typingMsg.c_str());
				rakpeer_->Send(&chatBS, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
				chatList.push_back(typingMsg);
			}

			// Reset
			chatMode = false;
			typingMsg = "";
			enterTimer = 0.f;
			chatShowTimer = 5.f;
		}
		else if (input >= 32 && input <= 126)
		{
			typingMsg += input;
		}
	}
	else
	{
		if (chatShowTimer > 0.f)
		{
			chatShowTimer -= timedelta;
		}

		if (hge_->Input_GetKeyState(HGEK_ENTER) && enterTimer >= MAX_ENTER_TIMER)
		{
			chatMode = true;
			enterTimer = 0.f;
		}

		// Ship controls
		if (hge_->Input_GetKeyState(HGEK_LEFT))
		{
			ships_.at(0)->SetAngularVelocity(ships_.at(0)->GetAngularVelocity() - DEFAULT_ANGULAR_VELOCITY);
		}

		if (hge_->Input_GetKeyState(HGEK_RIGHT))
		{
			ships_.at(0)->SetAngularVelocity(ships_.at(0)->GetAngularVelocity() + DEFAULT_ANGULAR_VELOCITY);
		}

		if (hge_->Input_GetKeyState(HGEK_UP))
		{
			ships_.at(0)->Accelerate(DEFAULT_ACCELERATION, timedelta);
		}

		if (hge_->Input_GetKeyState(HGEK_DOWN))
		{
			ships_.at(0)->Accelerate(-DEFAULT_ACCELERATION, timedelta);
		}

		// Shooting
		if (hge_->Input_GetKeyState(HGEK_1))
		{
			if (missileShootTimer >= S_MISSILE_SHOOT_INTERVAL)
			{
				Shoot(Projectile::PROJ_SEEKING_MISSLE);
			}
		}
		if (hge_->Input_GetKeyState(HGEK_2))
		{
			if (bulletShootTimer >= S_BULLET_SHOOT_INTERVAL)
			{
				Shoot(Projectile::PROJ_BULLET);
			}
		}

		if (hge_->Input_GetKeyState(HGEK_ESCAPE))
		{
			return true;
		}
	}

	// Update all ships
	for (ShipList::iterator ship = ships_.begin();
	ship != ships_.end(); ship++)
	{
		(*ship)->Update(timedelta);

		//collisions
		/*if ((*ship) == ships_.at(0))
			checkCollisions((*ship));*/
	}

	// Lab 13 Task 5 : Updating the missile
	/*if (mymissile)
	{
		if (mymissile->Update(ships_, timedelta))
		{
			//havecollision
			delete mymissile;
			mymissile = 0;
		}
	}*/

	// Lab 13 Task 13 : Update network missiles
	/*for (MissileList::iterator missile = missiles_.begin(); missile != missiles_.end(); missile++)
	{
		if ((*missile)->Update(ships_, timedelta))
		{
			//havecollision
			delete*missile;
			missiles_.erase(missile);
			break;
		}
	}*/

	// Update enemies
	/*for (vector<Enemy*>::iterator it = enemyList.begin(); it != enemyList.end(); ++it)
	{
		Enemy* e = *it;
		if (e->GetActive())
		{
			bool reset = e->Update(timedelta);
			if (reset)
			{
				RakNet::BitStream bs;
				bs.Write((unsigned char)ID_DESTROY_ENEMY);
				bs.Write(e->GetID());
				rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
			}
		}
	}*/

	// Update projectile
	for (vector<Projectile*>::iterator it = projectileList.begin(); it != projectileList.end(); ++it)
	{
		Projectile* p = *it;
		if (/*p->GetOwner() == ships_.at(0) && */p->GetActive()) // Only update your own projectile
		{
			bool reset = p->Update(timedelta);
			RakNet::BitStream bs;
			if (reset)
			{
				DestroyProjectile(p);
				bs.Write((unsigned char)ID_DESTROY_PROJECTILE);
				bs.Write(p->GetID());
				rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
			}
			else
			{
				for (vector<Enemy*>::iterator it2 = enemyList.begin(); it2 != enemyList.end(); ++it2)
				{
					Enemy* e = *it2;
					if (e->GetActive())
					{
						bool collision = p->CollideWith(e);
						if (collision)
						{
							int newHP = e->Injure(p->GetDamage());
							if (newHP <= 0)
							{
								RakNet::BitStream bs;
								// Add score to player
								p->GetOwner()->AddScore(100);

								bs.Write((unsigned char)ID_UPDATE_SCORE);
								bs.Write(p->GetOwner()->GetID());
								bs.Write(p->GetOwner()->GetScore());
								rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);

								// Destroy enemy
								DestroyEnemy(e);

								// Send to server to destroy enemy
								bs.ResetWritePointer();
								bs.Write((unsigned char)ID_DESTROY_ENEMY);
								bs.Write(e->GetID());
								rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
							}
							else
							{
								// Send to server to injure enemy
								RakNet::BitStream bs;
								bs.ResetWritePointer();
								bs.Write((unsigned char)ID_INJURE_ENEMY);
								bs.Write(e->GetID());
								bs.Write(e->GetHP());
								rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
							}

							// Reset projectile
							DestroyProjectile(p);
							bs.ResetWritePointer();
							bs.Write((unsigned char)ID_DESTROY_PROJECTILE);
							bs.Write(p->GetID());
							rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
						}
					}
				}
				/*int max = projectileUpdateList.size();
				int count = 0;
				for (vector<Projectile*>::iterator it2 = projectileUpdateList.begin(); it2 != projectileUpdateList.end(); ++it2)
				{
					Projectile* p2 = *it2;
					if (p == p2)
					{
						break;
					}
					else
					{
						++count;
					}
				}
				if (count == max)
				{
					projectileUpdateList.push_back(p);
				}*/
				/*bs.Write((unsigned char)ID_UPDATE_PROJECTILE);
				bs.Write(p->GetID());
				bs.Write(p->GetActive());
				bs.Write(p->GetType());
				bs.Write(p->GetX());
				bs.Write(p->GetY());
				bs.Write(p->GetVelocityX());
				bs.Write(p->GetVelocityY());
				bs.Write(p->GetSpeed());
				bs.Write(p->GetDamage());
				bs.Write(p->GetOwner()->GetID());
				// Send target id if available
				if (p->GetTarget())
				{
					bs.Write(p->GetTarget()->GetID());
				}
				else
				{
					bs.Write(-1);
				}
				rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);*/
			}
		}
	}

	// Update explosions
	for (vector<Explosion*>::iterator it = explosionList.begin(); it != explosionList.end(); ++it)
	{
		Explosion* e = *it;
		if ( e->isActive())
		{
			e->Update(timedelta);
		}
	}

	// Update boom
	for (vector<Boom*>::iterator it = boomList.begin(); it != boomList.end(); ++it)
	{
		Boom* b = *it;
		if (b->isActive())
		{
			b->Update(timedelta);
		}
	}

	// Packet receive
	if (Packet* packet = rakpeer_->Receive())
	{
		RakNet::BitStream bs(packet->data, packet->length, false);
		
		unsigned char msgid = 0;
		RakNetTime timestamp = 0;

		bs.Read(msgid);

		if (msgid == ID_TIMESTAMP)
		{
			bs.Read(timestamp);
			bs.Read(msgid);
		}

		switch(msgid)
		{
		case ID_CONNECTION_REQUEST_ACCEPTED:
			{
				std::cout << "Connected to Server" << std::endl;
				SendScreenSize();
				InitEnemyList();
				InitExplosionList();
				InitBoomList();
				InitProjectileList();
				InitBackground();
				InitBase();
				InitScore();
				chatMsg = new hgeFont("font1.fnt");
				chatMsg->SetScale(1);
				
			}
			break;

		case ID_NO_FREE_INCOMING_CONNECTIONS:
		case ID_CONNECTION_LOST:
		case ID_DISCONNECTION_NOTIFICATION:
			std::cout << "Lost Connection to Server" << std::endl;
			rakpeer_->DeallocatePacket(packet);
			return true;

		case ID_WELCOME:
			{
				unsigned int shipcount, id;
				float x_, y_;
				int type_;
				std::string temp;
				char chartemp[5];

				bs.Read(id);
				ships_.at(0)->setID( id );
				bs.Read(shipcount);

				for (unsigned int i = 0; i < shipcount; ++ i)
				{
					bs.Read(id);
					bs.Read(x_);
					bs.Read(y_);
					bs.Read(type_);
					std::cout << "New Ship pos" << x_ << " " << y_ << std::endl;
					Ship* ship = new Ship(type_, x_, y_ ); 
					temp = "Ship ";
					temp += _itoa(id, chartemp, 10);
					ship->SetName(temp.c_str());
					ship->setID( id );
					ships_.push_back(ship);
				}

				for (vector<Enemy*>::iterator it = enemyList.begin(); it != enemyList.end(); ++it)
				{
					int id, hp;
					bool active;
					Enemy::ENEMY_TYPE type;
					float x, y, vel_x, vel_y, speed;
					bs.Read(id);
					bs.Read(active);
					bs.Read(type);
					bs.Read(x);
					bs.Read(y);
					bs.Read(vel_x);
					bs.Read(vel_y);
					bs.Read(speed);
					bs.Read(hp);
					Enemy* e = FindEnemyByID(id);
					if (e)
					{
						float w = CalcW(Vector2(vel_x, vel_y));
						/*if (speed != 0)
						{
							w = acosf(vel_x / speed);
						}
						else
						{
							w = 0.f;
						}*/
						e->Init(type, x, y, w, active);
						e->SetVelocityX(vel_x);
						e->SetVelocityY(vel_y);
						e->SetSpeed(speed);
						e->SetHP(hp);
					}
				}
				
				// Base hp
				bs.Read(base_hp);

				SendInitialPosition();
			}
			break;
		case ID_REJECT_PLAYER:
			{
				std::cout << "Rejected player" << std::endl;
				return true;
			}
			break;

		case ID_NEWSHIP:
			{
				unsigned int id;
				bs.Read(id);

				if( id == ships_.at(0)->GetID() )
				{
					// if it is me
					break;
				}
				else
				{
					float x_, y_;
					int type_;
					std::string temp;
					char chartemp[5];

					bs.Read( x_ );
					bs.Read( y_ );
					bs.Read( type_ );
					std::cout << "New Ship pos" << x_ << " " << y_ << std::endl;
					Ship* ship = new Ship(type_, x_, y_);
					temp = "Ship "; 
					temp += _itoa(id, chartemp, 10);
					ship->SetName(temp.c_str());
					ship->setID( id );
					ships_.push_back(ship);
				}

			}
			break;

		case ID_LOSTSHIP:
			{
				unsigned int shipid;
				bs.Read(shipid);
				for (ShipList::iterator itr = ships_.begin(); itr != ships_.end(); ++itr)
				{
					if ((*itr)->GetID() == shipid)
					{
						delete *itr;
						ships_.erase(itr);
						break;
					}
				}
			}
			break;

		case ID_INITIALPOS:
			break;

		case ID_MOVEMENT:
			{
				unsigned int shipid;
				float temp;
				float x,y,w;
				bs.Read(shipid);
				for (ShipList::iterator itr = ships_.begin(); itr != ships_.end(); ++itr)
				{
					if ((*itr)->GetID() == shipid)
					{
						// this portion needs to be changed for it to work
#ifdef INTERPOLATEMOVEMENT
						bs.Read(x);
						bs.Read(y);
						bs.Read(w);

						(*itr)->SetServerLocation( x, y, w ); 

						bs.Read(temp);
						(*itr)->SetServerVelocityX( temp );
						bs.Read(temp);
						(*itr)->SetServerVelocityY( temp );
						bs.Read(temp);
						(*itr)->SetAngularVelocity( temp );

						(*itr)->DoInterpolateUpdate();
#else
						bs.Read(x);
						bs.Read(y);
						bs.Read(w);
						(*itr)->setLocation( x, y, w ); 

						// Lab 7 Task 1 : Read Extrapolation Data velocity x, velocity y & angular velocity
						bs.Read(temp);
						(*itr)->SetVelocityX( temp );
						bs.Read(temp);
						(*itr)->SetVelocityY( temp );
						bs.Read(temp);
						(*itr)->SetAngularVelocity( temp );
#endif

						break;
					}
				}
			}
			break;

		case ID_COLLIDE:
			{
				unsigned int shipid;
				float x, y;
				bs.Read(shipid);
				
				if( shipid == ships_.at(0)->GetID() )
				{
					std::cout << "collided with someone!" << std::endl;
					bs.Read(x);
					bs.Read(y);
					ships_.at(0)->SetX( x );
					ships_.at(0)->SetY( y );
					bs.Read(x);
					bs.Read(y);
					ships_.at(0)->SetVelocityX( x );
					ships_.at(0)->SetVelocityY( y );
#ifdef INTERPOLATEMOVEMENT
					bs.Read(x);
					bs.Read(y);
					ships_.at(0)->SetServerVelocityX( x );
					ships_.at(0)->SetServerVelocityY( y );
#endif	
				}
			}
			break;


		// Lab 13 Task 10 : new cases to handle missile on application side
		case ID_NEWMISSILE:
			{
				float x, y, w;
				int id;
				bs.Read(id);
				bs.Read(x);
				bs.Read(y);
				bs.Read(w);
				missiles_.push_back(new Missile("missile.png", x, y, w, id));
			}
			break;
		case ID_UPDATEMISSILE:
			{
				float x, y, w;
				int id;
				char deleted;
				bs.Read(id);
				bs.Read(deleted);
				for (MissileList::iterator itr = missiles_.begin(); itr !=
					missiles_.end(); ++itr)
				{
					if ((*itr)->GetOwnerID() == id)
					{
						if (deleted == 1)
						{
							delete*itr;
							missiles_.erase(itr);
						}
						else
						{
							bs.Read(x);
							bs.Read(y);
							bs.Read(w);
							(*itr)->UpdateLoc(x, y, w);
							bs.Read(x);
							(*itr)->SetVelocityX(x);
							bs.Read(y);
							(*itr)->SetVelocityY(y);
						}
						break;
					}
				}
			}
			break;
		case ID_NEW_ENEMY:
			{
				int id, hp;
				Enemy::ENEMY_TYPE type;
				float x, y, vel_x, vel_y, speed;
				bs.Read(id);
				bs.Read(type);
				bs.Read(x);
				bs.Read(y);
				bs.Read(vel_x);
				bs.Read(vel_y);
				bs.Read(speed);
				bs.Read(hp);
				Enemy* e = FindEnemyByID(id);
				if (e)
				{
					float w = CalcW(Vector2(vel_x, vel_y));
					e->Init(type, x, y, w);
					e->SetVelocityX(vel_x);
					e->SetVelocityY(vel_y);
					e->SetSpeed(speed);
					e->SetHP(hp);
				}
			}
			break;
		case ID_UPDATE_ENEMY:
			{
				int id;
				bs.Read(id);
				Enemy* e = FindEnemyByID(id);
				if (e)
				{
					float x, y;
					bs.Read(x);
					bs.Read(y);
					e->SetX(x);
					e->SetY(y);
				}
			}
			break;
		case ID_INJURE_ENEMY:
			{
				int id, hp;
				bs.Read(id);
				Enemy* e = FindEnemyByID(id);
				if (e && e->GetActive())
				{
					bs.Read(hp);
					e->SetHP(hp);
				}
			}
			break;
		case ID_DESTROY_ENEMY:
			{
				int id;
				bs.Read(id);
				Enemy* e = FindEnemyByID(id);

				DestroyEnemy(e);
			}
			break;
		case ID_SHOOT:
			{
				int id, damage, owner, target;
				Projectile::PROJECTILE_TYPE type;
				float x, y, w, vel_x, vel_y, speed;
				bs.Read(id);

				Projectile* p = FindProjectileByID(id);
				if (p)
				{
					bs.Read(type);
					bs.Read(x);
					bs.Read(y);
					bs.Read(w);
					bs.Read(vel_x);
					bs.Read(vel_y);
					bs.Read(speed);
					bs.Read(damage);
					bs.Read(owner);
					bs.Read(target);
					
					Ship* sOwner = FindShipByID(owner);
					if (sOwner)
					{
						p->Init(sOwner, type, x, y, w);
						p->SetVelocityX(vel_x);
						p->SetVelocityY(vel_y);
						p->SetSpeed(speed);
						p->SetDamage(damage);
						if (target != -1)
						{
							Enemy* sTarget = FindEnemyByID(target);
							if (sTarget)
							{
								p->SetTarget(sTarget);
							}
						}
					}
				}
			}
			break;
		case ID_UPDATE_PROJECTILE:
			{
				int id, damage, owner, target;
				Projectile::PROJECTILE_TYPE type;
				float x, y, vel_x, vel_y, speed;
				bool active;
				bs.Read(id);

				Projectile* p = FindProjectileByID(id);
				if (p)
				{
					bs.Read(active);
					bs.Read(type);
					bs.Read(x);
					bs.Read(y);
					bs.Read(vel_x);
					bs.Read(vel_y);
					bs.Read(speed);
					bs.Read(damage);
					bs.Read(owner);
					bs.Read(target);

					Ship* sOwner = FindShipByID(owner);
					if (sOwner)
					{
						p->SetOwner(sOwner);
						p->SetType(type);
						p->SetX(x);
						p->SetY(y);
						p->SetActive(active);
						p->SetVelocityX(vel_x);
						p->SetVelocityY(vel_y);
						p->SetSpeed(speed);
						p->SetDamage(damage);
						if (target != -1)
						{
							Enemy* sTarget = FindEnemyByID(target);
							if (sTarget)
							{
								p->SetTarget(sTarget);
							}
						}
					}
				}
			}
			break;
		case ID_DESTROY_PROJECTILE:
			{
				int id;
				bs.Read(id);
				Projectile* p = FindProjectileByID(id);
				if (p && p->GetActive())
				{
					// Reset projectile
					//DestroyProjectile(p);
					p->Reset();
				}
			}
			break;
		case ID_UPDATE_BASE:
			{
				bs.Read(base_hp);
			}
			break;
		case ID_UPDATE_SCORE:
			{
				int id, score;
				bs.Read(id);
				Ship* s = FindShipByID(id);
				if (s)
				{
					bs.Read(score);
					s->SetScore(score);
				}
			}
			break;
		case ID_CHAT_SEND:
			{
				char cMsg[256];
				bs.Read(cMsg);
				chatList.push_back(cMsg);
				chatShowTimer = 5.f;
			}
			break;

		default:
			std::cout << "Unhandled Message Identifier: " << (int)msgid << std::endl;

		}
		rakpeer_->DeallocatePacket(packet);
	}

	if (base_hp <= 0)
	{
		return true;
	}

	// Send projectile updates
	/*static const int SYNCS_PER_SEC = 24;
	static const float TIME_PER_SYNC = 1 / SYNCS_PER_SEC;
	static float projSendTimer = TIME_PER_SYNC;
	if (projSendTimer < TIME_PER_SYNC)
	{
		projSendTimer += timedelta;
	}
	else
	{
		for (vector<Projectile*>::iterator it = projectileList.begin(); it != projectileList.end(); ++it)
		{
			Projectile* p = *it;
			if (p->GetActive() && p->GetOwner() == ships_.at(0))
			{
				RakNet::BitStream sendProj;
				sendProj.Write((unsigned char)ID_UPDATE_PROJECTILE);
				sendProj.Write(p->GetID());
				sendProj.Write(p->GetActive());
				sendProj.Write(p->GetType());
				sendProj.Write(p->GetX());
				sendProj.Write(p->GetY());
				sendProj.Write(p->GetVelocityX());
				sendProj.Write(p->GetVelocityY());
				sendProj.Write(p->GetSpeed());
				sendProj.Write(p->GetDamage());
				sendProj.Write(p->GetOwner()->GetID());
				// Send target id if available
				if (p->GetTarget())
				{
					sendProj.Write(p->GetTarget()->GetID());
				}
				else
				{
					sendProj.Write(-1);
				}
				rakpeer_->Send(&sendProj, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
				std::cout << p->GetX() << " | " << p->GetY() << std::endl;
			}
		}
		projSendTimer = 0.f;
	}*/

	// Send data
	float timeToSync = 1000 / 24; // Sync 24 times in a second (Millisecond)
	if (RakNet::GetTime() - timer_ > timeToSync)
	{
		timer_ = RakNet::GetTime(); // Store previous time
		RakNet::BitStream bs2;
		unsigned char msgid = ID_MOVEMENT;
		bs2.Write(msgid);

#ifdef INTERPOLATEMOVEMENT
		bs2.Write(ships_.at(0)->GetID());
		bs2.Write(ships_.at(0)->GetServerX());
		bs2.Write(ships_.at(0)->GetServerY());
		bs2.Write(ships_.at(0)->GetServerW());
		bs2.Write(ships_.at(0)->GetServerVelocityX());
		bs2.Write(ships_.at(0)->GetServerVelocityY());
		bs2.Write(ships_.at(0)->GetAngularVelocity());

#else
		bs2.Write(ships_.at(0)->GetID());
		bs2.Write(ships_.at(0)->GetX());
		bs2.Write(ships_.at(0)->GetY());
		bs2.Write(ships_.at(0)->GetW());
		// Lab 7 Task 1 : Add Extrapolation Data velocity x, velocity y & angular velocity
		bs2.Write(ships_.at(0)->GetVelocityX());
		bs2.Write(ships_.at(0)->GetVelocityY());
		bs2.Write(ships_.at(0)->GetAngularVelocity());
#endif

		rakpeer_->Send(&bs2, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true);


		// Lab 13 Task 11 : send missile update 
		/*if (mymissile)
		{
			RakNet::BitStream bs3;
			unsigned char msgid2 = ID_UPDATEMISSILE;
			unsigned char deleted = 0;
			bs3.Write(msgid2);
			bs3.Write(mymissile->GetOwnerID());
			bs3.Write(deleted);
			bs3.Write(mymissile->GetX());
			bs3.Write(mymissile->GetY());
			bs3.Write(mymissile->GetW());
			bs3.Write(mymissile->GetVelocityX());
			bs3.Write(mymissile->GetVelocityY());
			rakpeer_->Send(&bs3, HIGH_PRIORITY, UNRELIABLE_SEQUENCED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
		}*/

		// Send update projectile
		/*for (int i = 0; i < projectileUpdateList.size(); ++i)
		{
			Projectile* p = projectileList[i];
			if (p && p->GetActive())
			{
				RakNet::BitStream sendProj;
				sendProj.Write((unsigned char)ID_UPDATE_PROJECTILE);
				sendProj.Write(p->GetID());
				sendProj.Write(p->GetActive());
				sendProj.Write(p->GetType());
				sendProj.Write(p->GetX());
				sendProj.Write(p->GetY());
				sendProj.Write(p->GetVelocityX());
				sendProj.Write(p->GetVelocityY());
				sendProj.Write(p->GetSpeed());
				sendProj.Write(p->GetDamage());
				sendProj.Write(p->GetOwner()->GetID());
				// Send target id if available
				if (p->GetTarget())
				{
					sendProj.Write(p->GetTarget()->GetID());
				}
				else
				{
					sendProj.Write(-1);
				}
				rakpeer_->Send(&sendProj, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
			}
		}
		projectileUpdateList.clear();*/
	}

	return false;
}