DustCloudParticle::DustCloudParticle(unsigned int numParticles, float minSize, float maxSize, float xPos, float yPos)
{
	RenderComponent::RenderComponent();
	//gameObjectRef->AddComponent(COMPONENT_RENDER, this);
	SceneManager* sceneMan = SceneManager::GetSceneManager();
	RenderManager* renderMan = RenderManager::getRenderManager();
	ResourceManager* ResMan = ResourceManager::GetResourceManager();
	//RenderResource * originalImage = ;
	//std::function<bool(void)> charge = isCharging;
	objRef = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), -1, xPos, yPos);
	objRef->toggleVisible();
	for (unsigned int i = 0; i < numParticles; i++){
		SDLRenderObject * sprite = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), -1, xPos, yPos);
		RenderResource * resource = new RenderResource((RenderResource*)ResMan->findResourcebyID(4001));
		resource->load();
		sprite->setResourceObject(resource);
		sprite->setScale(sprite->calcXScale(minSize + (maxSize-minSize)*(rand()%100)/100));
		std::list<motion> movements;
		movements.push_back(makeMotion(moveLinearXY(sprite, xPos, yPos, xPos+ 40 -(rand() % 80),
													yPos + 40 - (rand() % 80)),0, 1, ease_QuadIn));
		movements.push_back(makeMotion(rotateTransform(sprite, rand() % 360, (rand() % 90) - 45), 0, 1));
		Animation * movement = new Animation((float)(700 - (rand() % 200)), movements);
		particle p;
		p.animations = movement;
		p.sprite = sprite;
		p.timer = (float)progress;
		particles.push_back(p);
	}
}
void *motionTask (void * arg)
{
	printf ("# Demarrage tache MOTION: OK\n");

	// Chargement des séquences de mouvement (hexapodRemote.cfg)
	loadHexapodMotionSeq();

	usleep(100000);

	th6_timerMotionIntervalInit(motionTime);

	while(!killAllThread){
		//	  pthread_mutex_lock (&my_mutex);
		if(runMotion)th6_timerMotionIntervalStart();

		else th6_timerMotionIntervalStop();

		if(th6_timerMotionIntervalReadyFlag){
			th6_timerMotionIntervalInit(motionTime);
			makeMotion();
			th6_timerMotionIntervalReadyFlag=0;
			}

			//	pthread_mutex_unlock (&my_mutex);
		usleep(25000);
	}

	printf( "# ARRET tache MOTION\n");

	usleep(10000);

	killAllThread+=1;
	pthread_exit (0);
}
ShrapnelExplosionParticle::ShrapnelExplosionParticle(SDLRenderObject * base, unsigned int numParticles, float x, float y)
{
	RenderComponent::RenderComponent();
	//gameObjectRef->AddComponent(COMPONENT_RENDER, this);
	SceneManager* sceneMan = SceneManager::GetSceneManager();
	RenderManager* renderMan = RenderManager::getRenderManager();
	objRef = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), -1, x, y, base->getPosZ());
	objRef->toggleVisible();
	baseImage = base->renderResource;
	SDL_Rect baseRect = base->getRenderRect();
	unsigned int scale = 2;
	float size = (float)(baseRect.w/scale);
	float centerX = x;
	float centerY = y;
	for (unsigned int i = 0; i < numParticles; i++){
		SDLRenderObject * sprite = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), -1, centerX, centerY);
		//play->setResourceObject(renderMan->renderText("Timer", 255, 0, 255, 50, "BowlbyOneSC-Regular"));
		sprite->setResourceObject(baseImage);
		int xPos = (baseRect.w - int(size) > 0) ? rand() % (baseRect.w - int(size)) : 0;
		int yPos = (baseRect.h - int(size) > 0) ? rand() % (baseRect.h - int(size)) : 0;
		SDL_Rect rect = { xPos, yPos , (int)size, (int)size };
		sprite->setScaleX(base->getScaleX());
		sprite->setScaleY(base->getScaleY());
		sprite->setRenderRect(rect);
		float u = (float)((rand() % 360) / 360.0);
		float v = (float)((rand() % 360) / 360.0);
		float angle1 = (float)(3.14 * 2 * u);
		float angle2 = acos(2 * v - 1);

		std::list<motion> movements;
		movements.push_back(makeMotion(moveLinearXY(sprite, centerX, centerY, centerX + sin(angle1)*cos(angle2) * 300, centerY + sin(angle1)* sin(angle2) * 300), 0, 1, ease_QuadOut));
		movements.push_back(makeMotion(moveLinearZ(sprite, 0, cos(angle1) * 10), 0, 1, ease_QuadOut));
		movements.push_back(makeMotion(rotateTransform(sprite, rand() % 360, (rand() % 90) - 45), 0, 1));
		Animation * movement = new Animation((float)(1000.0f - (rand() % 200)), movements);
		//int maxtime = 100000; //in seconds
		//std:list<motion> motions;
		particle p;
		p.animations = movement;
		p.sprite = sprite;
		p.timer = 0;
		particles.push_back(p);
	}
}
void ChickenClassComponent::animation(SDLRenderObject** objRef, map_obj& allObjs, map_anim& animations)
{
    SceneManager* sceneMan = SceneManager::GetSceneManager();
    RenderManager* renderMan = RenderManager::getRenderManager();
    SDLRenderObject * base = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 0, 0, 0);
    base->toggleIfRenderImage();
    SDLRenderObject * armL = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 100103, 0, 0);
    SDLRenderObject * legL = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 100105, 30, 300);
    SDLRenderObject * body = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 100101, 0, -18);
    SDLRenderObject * legR = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 100104, 50, 300);
    SDLRenderObject * armR = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 100102, 0, 0);

    //PlayerPhysicsComponent pos = gameObjectRef->GetComponent(COMPONENT_PHYSICS);


    //objRef->setAnchor(0.5, 0.5);

    armR->setAnchor(174 / double(armR->renderRect.w), 154 / double(armR->renderRect.h));
    armL->setAnchor(178 / double(armL->renderRect.w), 168 / double(armL->renderRect.h));
    legR->setAnchor(128 / double(legR->renderRect.w), 39 / double(legR->renderRect.h));
    legL->setAnchor(253 / double(legL->renderRect.w), 62 / double(legL->renderRect.h));
    //armR->setCurrentFrame(1);
    body->setParent(base);
    armL->setParent(body);
    armR->setParent(body);
    legL->setParent(body);
    legR->setParent(body);

    //body->setScale(0.1);
    //body->calcScale(50,50);
    body->setScale(body->calcXScale(50));
    //body->setScale(body->calcXScale(90));

    *objRef = base;
    allObjs["base"] = base;
    allObjs["body"] = body;
    allObjs["legL"] = legL;
    allObjs["legR"] = legR;
    allObjs["armL"] = armL;
    allObjs["armR"] = armR;

    SDLRenderObject * box = sceneMan->InstantiateBlankObject(sceneMan->findLayer("layer2"), 0, 0, 0, 0);
    box->setIfRenderRect(true);
    //box->setParent(base);
    allObjs["box"] = box;
    //SDLRenderObject * name = sceneMan->InstantiateBlankObject(sceneMan->findLayer("layer2"), 0, 0, 0, 0);
    // changing the values in InstantiateBlankObject does not stop the text from being stretched
    // need fixing (to not stretch text to fill box)
    // text, R, G, B, fontsize, fontname

    //std::string playerName = GamerServices::sInstance->GetLocalPlayerName();
    //name->setResourceObject(renderMan->renderText(playerName.c_str(), 200, 0, 200, 20, "BowlbyOneSC-Regular"));
    //name->setParent(base);
    //name->setPos(0, -60);
    //allObjs["name"] = name;

    /////// IDLE ANIMATION
    std::list<motion> motions;
    motions.push_back(makeMotion(keyframeJump(armR, 0), 0.0, 0.0));
    motions.push_back(makeMotion(moveCircArc(armR, 0, 50, 50, 0, 360), 0, 1));
    motions.push_back(makeMotion(moveCircArc(armL, 0, 50, 50, 180, 360), 0, 1));
    motions.push_back(makeMotion(rotateTransform(legR, 0, 0), 0, 0));
    motions.push_back(makeMotion(rotateTransform(legL, 0, 0), 0, 0));
    Animation* idle = new Animation(400, motions);
    animations["idle"] = idle;
    //auto mot = idle.motions.begin();
    //currentAnimation = idle;
    ////// WALKING ANIMATION
    std::list<motion> motions2;
    motions2.push_back(makeMotion(keyframeJump(armR, 0), 0.0, 0.0));
    motions2.push_back(makeMotion(moveCircArc(armR, 0, 50, 50, 0, 360), 0, 1));
    motions2.push_back(makeMotion(moveCircArc(armL, 0, 50, 50, 180, 360), 0, 1));
    motions2.push_back(makeMotion(rotateTransform(legR, -60, 120), 0, 0.5, ease_QuadInOut));
    motions2.push_back(makeMotion(rotateTransform(legR, 60, -120), 0.5, 0.5, ease_QuadInOut));
    motions2.push_back(makeMotion(rotateTransform(legL, 60, -120), 0, 0.5, ease_QuadInOut));
    motions2.push_back(makeMotion(rotateTransform(legL, -60, 120), 0.5, 0.5, ease_QuadInOut));
    //motions2.push_back(makeMotion(rotateTransform(legR, -30, 60), 0.5, 0.5, ease_QuadIn));
    animations["walk"] = new Animation(400, motions2);

    ////// THROW ANIMATION
    std::list<motion> motions3;
    motions3.push_back(makeMotion(keyframeJump(armR, 1), 0.0, 0.0));
    motions3.push_back(makeMotion(rotateTransform(armR, -30, 0), 0.0, 1.0,ease_QuadOut));
    animations["throw"] = new Animation(100, motions3);
    ////// CHARGE ANIMATION
    std::list<motion> motions4;
    motions4.push_back(makeMotion(rotateTransform(armR,-20,0), 0.0, 0.0));
    animations["charge"] = new Animation(100, motions4);
}
BackgroundProps::BackgroundProps()
{
	SceneManager* sceneMan = SceneManager::GetSceneManager();
	objRef = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), -1, 0, 0);
	//Planets
	allObjs["planet1"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2105, 0.0f, -200.0f, 400.0f);
	allObjs["planet1"]->setScale(20);
	allObjs["planet2"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2104, 80000.0f, -20000.0f, 4000.0f);
	allObjs["planet2"]->setScale(200);
	allObjs["planet3"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2103, -80000.0f, 40000.0f, 4000.0f);
	allObjs["planet3"]->setScale(200);

	//Clouds
	allObjs["cloudB1"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2106, 0.0f, 500.0f, 4000.1f);
	allObjs["cloudB1"]->setScale(170);
	allObjs["cloudT1"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2106, 0.0f, -500.0f, 4000.1f);
	allObjs["cloudT1"]->setScale(170);
	allObjs["cloudT1"]->setRotation(180);
	allObjs["cloudB2"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2107, 0.0f, 4800.0f, 300.0f);
	allObjs["cloudB2"]->setScale(20);
	allObjs["cloudT2"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2107, 0.0f, -4800.0f, 300.0f);
	allObjs["cloudT2"]->setScale(20);
	allObjs["cloudT2"]->setRotation(180);

	//Boids
	allObjs["boidB1"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2108, 3250.0f, 2200.0f, 99.9f);
	allObjs["boidB1"]->setScale(1);
	allObjs["boidB2"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2109, 1200.0f, 2000.0f, 99.9f);
	allObjs["boidB2"]->setScale(1);
	allObjs["boidB2"]->setFlippedH(true);
	allObjs["boidB3"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2108, -1500.0f, 2100.0f, 99.9f);
	allObjs["boidB3"]->setScale(1);
	allObjs["boidB3"]->setFlippedH(true);
	allObjs["boidB4"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2109, -3400.0f, 2200.0f, 99.9f);
	allObjs["boidB4"]->setScale(1);

	allObjs["boidT1"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2108, -3250.0f, -2200.0f, 99.9f);
	allObjs["boidT1"]->setScale(1);
	allObjs["boidT1"]->setFlippedV(true);
	allObjs["boidT2"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2109, -1200.0f, -2000.0f, 99.9f);
	allObjs["boidT2"]->setScale(1);
	allObjs["boidT2"]->setFlippedH(true);
	allObjs["boidT2"]->setFlippedV(true);
	allObjs["boidT3"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2108, 1500.0f, -2100.0f, 99.9f);
	allObjs["boidT3"]->setScale(1);
	allObjs["boidT3"]->setFlippedH(true);
	allObjs["boidT3"]->setFlippedV(true);
	allObjs["boidT4"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2109, 3400.0f, -2200.0f, 99.9f);
	allObjs["boidT4"]->setScale(1);
	allObjs["boidT4"]->setFlippedV(true);
	//cloudT2->setRotation(180);

	//Protein Mountain


	//Beaches

	allObjs["beachB"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2101, 0.0f, 2200.0f, 100.0f);
	allObjs["beachT"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2101, 0.0f, -2200.0f, 100.0f);
	allObjs["surfB"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2102, 0.0f, 0.0f, 0.0f);
	allObjs["surfT"] = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 2102, 0.0f, 0.0f, 0.0f);
	allObjs["beachB"]->setScale(6);
	allObjs["beachT"]->setScale(6);
	allObjs["surfB"]->setParent(allObjs["beachB"]);
	allObjs["surfT"]->setParent(allObjs["beachT"]);
	allObjs["beachT"]->setRotation(180);
	std::list<motion> surfMotions;
	surfMotions.push_back(makeMotion(transformFlipH(allObjs["surfB"], false), 0.0, 0.0));
	surfMotions.push_back(makeMotion(transformFlipH(allObjs["surfT"], false), 0.0, 0.0));
	surfMotions.push_back(makeMotion(moveLinearY(allObjs["surfB"], -21, -6), 0, 0.5));
	surfMotions.push_back(makeMotion(moveLinearY(allObjs["surfT"], -21, -6), 0, 0.5));
	surfMotions.push_back(makeMotion(transformFlipH(allObjs["surfB"], true), 0.5, 0.5));
	surfMotions.push_back(makeMotion(transformFlipH(allObjs["surfT"], true), 0.5, 0.5));
	surfMotions.push_back(makeMotion(moveLinearY(allObjs["surfB"], -21, -6), 0.5, 1.0));
	surfMotions.push_back(makeMotion(moveLinearY(allObjs["surfT"], -21, -6), 0.5, 1.0));
	animations["surf"] = new Animation(1000, surfMotions);
	setAnimation("surf");
}
EggImplosionParticle::EggImplosionParticle(SDLRenderObject * base, unsigned int divisions, float x, float y)
{
	RenderComponent::RenderComponent();
	//gameObjectRef->AddComponent(COMPONENT_RENDER, this);
	SceneManager* sceneMan = SceneManager::GetSceneManager();
	RenderManager* renderMan = RenderManager::getRenderManager();
	ResourceManager* ResMan = ResourceManager::GetResourceManager();
	objRef = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), -1, x, y, base->getPosZ());
	objRef->toggleVisible();
	//baseImage = base->renderResource;
	//RenderResource * baseImage = (RenderResource*)ResMan->findResourcebyID(74);
	//SDL_Rect baseRect = objRef->getRenderRect();
	//unsigned int scale = 2;
	//float size = baseRect.w / scale;
	float centerX = base->getPosX();
	float centerY = base->getPosY();
	//for (int x = 1; x < float(divisions+1)*2.0; x+=2){ 
	//	for (int y  = 1; y < float(divisions+1)*2.0; y+=2){
	for (unsigned x = 0; x <= divisions; x++){ 
		for (unsigned y = 0; y <= divisions; y++){
			SDLRenderObject * sprite = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 74, centerX, centerY);
			sprite->setScale(2);
			float yStart = (float)sprite->getWidth() *((x*2+1) / (float(divisions + 1)*2.0f) - sprite->getAnchorX());
			float xStart = (float)sprite->getHeight() *((y*2+1) / (float(divisions + 1)*2.0f) - sprite->getAnchorY());
			sprite->flipV = true;
			sprite->setPos(centerX, centerY);
			//play->setResourceObject(renderMan->renderText("Timer", 255, 0, 255, 50, "BowlbyOneSC-Regular"));
			sprite->setResourceObject(baseImage);
			SDL_Rect baseRect = sprite->getRenderRect(); 
			/*int xPos = (baseRect.w - int(baseRect.w / (divisions + 1.0)) > 0) ?
						rand() % (baseRect.w - int(baseRect.w / (divisions + 1.0))) : 0;
			int yPos = (baseRect.h - int(baseRect.h / (divisions + 1.0)) > 0) ?
						rand() % (baseRect.h - int(baseRect.h / (divisions + 1.0))) : 0;*/
			int xPos = x * int(baseRect.h / (divisions + 1.0));
			int yPos = y * int(baseRect.h / (divisions + 1.0));
			SDL_Rect rect = { xPos, yPos, (int)round(baseRect.w / (divisions + 1.0)), (int)round(baseRect.h / (divisions + 1.0)) };
			//sprite->setScaleX(base->getScaleX());
			sprite->setRenderRect(rect);
			float u = (float)((rand() % 360) / 360.0f);
			float v = (float)((rand() % 360) / 360.0f);
			float angle1 = 3.14f * 2.0f * u;
			float angle2 = acos(2 * v - 1);

			std::list<motion> movements;
			movements.push_back(makeMotion(moveLinearXY(sprite, centerX + sin(angle1)*cos(angle2) * 300,
																centerY + sin(angle1)* sin(angle2) * 300,
																xStart + centerX, yStart+ centerY), 0, 1, ease_QuadOut));
			movements.push_back(makeMotion(moveLinearZ(sprite, cos(angle1) * 10, 0), 0, 1, ease_QuadOut));
			float spinAngle = (float)(rand() % 360);
			//movements.push_back(makeMotion(rotateTransform(sprite, rand() % 360, (rand() % 90) - 45), 0, 1));
			movements.push_back(makeMotion(rotateTransform(sprite, spinAngle, -spinAngle+90), 0, 1,ease_QuadOut));
			Animation * movement = new Animation(1000, movements);
			//int maxtime = 100000; //in seconds
			//std:list<motion> motions;
			particle p;
			p.animations = movement;
			p.sprite = sprite;
			p.timer = 0;
			particles.push_back(p);
		}
	}
}
void FeatherZoomParticle::Update(){
	if (!parentObject || !(parentObject->isAlive)){
		alive = false;
	}
	unsigned int currenttime = clock();
	unsigned int oldTime = progress;
	progress += currenttime - lasttime;
	if (alive && ((currenttime - lasttime) > frequencyOfParticles || oldTime%frequencyOfParticles > progress%frequencyOfParticles)){
		SceneManager* sceneMan = SceneManager::GetSceneManager();
		RenderManager* renderMan = RenderManager::getRenderManager();
		//SDL_Rect baseRect = parent->getRenderRect();
		//unsigned int scale = 2;
		//float size = baseRect.w / scale;
		float centerX = parentObject->posX;
		float centerY = parentObject->posY;
		for (unsigned int i = 0; i < numberOfParticles; i++){
			SDLRenderObject * sprite = sceneMan->InstantiateObject(sceneMan->findLayer("layer2"), 4002, centerX, centerY,0.1f);
			//play->setResourceObject(renderMan->renderText("Timer", 255, 0, 255, 50, "BowlbyOneSC-Regular"));
			//sprite->setScaleX(base->getScaleX());
			//sprite->setScaleY(base->getScaleY());
			//sprite->setRenderRect(rect);
			float angle1 = (30 - (rand() % 60)) + parentObject->rotation;
			sprite->setRotation(angle1);
			std::list<motion> movements;
			movements.push_back(makeMotion(resizeSquareTransform(sprite, 0.01f,0.5f), 0.0f, 0.5f, ease_QuadOut));
			movements.push_back(makeMotion(resizeSquareTransform(sprite, 0.5f, 0.01f), 0.5f, 1.0f, ease_QuadIn));
			movements.push_back(makeMotion(keyframeAnimate(sprite,0,3), 0.0, 1.0, ease_QuadIn));
			//movements.push_back(makeMotion(moveLinearXY(sprite, centerX, centerY, centerX + rand() % 20 - 40, centerY +rand() % 20 - 40), 0, 1, ease_QuadOut));
			//movements.push_back(makeMotion(moveLinearZ(sprite, 0, cos(angle1) * 10), 0, 1, ease_QuadOut));
			//movements.push_back(makeMotion(rotateTransform(sprite, rand() % 360, (rand() % 90) - 45), 0, 1));
			Animation * movement = new Animation((float)(500 - (rand() % 100)), movements);
			//int maxtime = 100000; //in seconds
			//std:list<motion> motions;
			particle p;
			p.animations = movement;
			p.sprite = sprite;
			p.timer = (float)progress;
			particles.push_back(p);
		}
	}
	if (particles.empty() && !alive){
		//delete self and remove GameObject from list of objects
		gameObjectRef->isAlive = false;
	}
	for (auto iter = particles.begin(); iter != particles.end();){
		float curr = iter->animations->lengthConversion((int)(progress-iter->timer));
		//if (curr >= 1.0) iter->sprite->setIfRenderImage(false);
		if (curr >= 1.0){
			//iter->sprite->setIfRenderImage(false);
			delete iter->animations;
			SceneManager* sceneMan = SceneManager::GetSceneManager();
			sceneMan->RemoveObject(iter->sprite);
			auto toErase = iter;
			iter++;
			particles.erase(toErase);
		}
		else{
			iter->animations->animate(curr);
			iter++;
		}
	}
	lasttime = currenttime;
}