void StateSwitch::updateState()
{
	if(newState_ != currentState_)
	{
		oldState_ = currentState_;
		currentState_ = newState_;
	}

	switch(currentState_)
	{
	case STATE_IDLE:
		handleIdle();
			break;
	case STATE_WANDER:
			handleWander();
			break;
	case STATE_FOLLOW:
			handleFollow();
			break;
	case STATE_OFFENSIVE:
			handleOffensive();
			break;
	case STATE_DEFENSIVE:
			handleDefensive();
			break;
	case STATE_FLEEING:
			handleFleeing();
			break;
	case STATE_DEATH:
			handleDeath();
			break;
	}
}
void ComponentCollider::onMessage(const Message& message)
{
	switch (message.type)
	{
	case Message::DEATH:
		handleDeath();
		break;
	case Message::REPAIRED:
		GameManager::getInstance()->getCollisionManager()->addComponentCollider(this);
		break;
	}

}
void AManaJourneyCharacter::TakeCharacterDamage(float Damage, UDamageType* damageType, class AController* EventInstigator, class AActor* DamageCauser)
{
	if (!bIsDead)
	{
		health = health - Damage;
		if (health <= 0.0f)
		{
			handleDeath();
		}
		else
		{
			handleHitByDamageType(DamageCauser, damageType);
		}

	}
	else
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("you are dead")));
	}

}
void Application::handlePhysics()
{
    //apply gravity
    phy.gravity(delta.get_ticks()/1000.f, player.posY);
    //the call to check for collision between the player and all of the inanimate objects
    //registered in the physics "database"
    phy.isCollision(delta.get_ticks()/1000.f, player.playerPos, player.posX, player.posY);

    //checks for collision between the player and the spikes
    if(phy.Collision(&player.playerPos, &environment.spikesPos))
    {
        //handles the death behavior
        handleDeath();
    }

    if(phy.Collision(&player.playerPos, &environment.spikes1Pos))
    {
        handleDeath();
    }

    //if arrow hits wraith from the right
    for(list<Arrow>::iterator itr = arrowListR.begin(); itr!=arrowListR.end(); itr++)
    {
        for(int i = 0; i<2; i++)//for each wraith
        {
            if(phy.Collision(&itr->arrowRpos, &wraithFactory[i].monsterPos))
            {
                wraithFactory[i].deadMonsterR = true;//stops updating the monster
                itr->used = true;//sets arrow as used
                wraithFactory[i].monsterAnim = {wraithFactory[i].frame_x*100, wraithFactory[i].frame_y*150, 100, 150};//update death animation
            }

            if(wraithFactory[i].deadMonsterR)//goes into death animation
            {
                if(wraithFactory[i].killedMonsterR(delta.get_ticks()/1000.f))
                {
                    wraithFactory[i].monsterDead = true;
                }

            }
        }
    }

    //if arrow hits wraith from the left
    for(list<Arrow>::iterator itr = arrowListL.begin(); itr!=arrowListL.end(); itr++)
    {
        for(int i = 0; i<2; i++)
        {
            if(phy.Collision(&itr->arrowLpos, &wraithFactory[i].monsterPos))
            {
                wraithFactory[i].deadMonsterL = true;//stops updating the monster
                itr->used = true;
                wraithFactory[i].monsterAnim = {wraithFactory[i].frame_x*100, wraithFactory[i].frame_y*150, 100, 150};//update death animation
            }

            if(wraithFactory[i].deadMonsterL)//goes into death animation
            {
                if(wraithFactory[i].killedMonsterL(delta.get_ticks()/1000.f))
                {
                    wraithFactory[i].monsterDead = true;

                }

            }
        }

    }

    //if wraith is alive and collides with player, kill player
    for(int i = 0; i < 2; i++)
    {
        //calls individual collision detection method
        if(!wraithFactory[i].monsterDead && phy.Collision(&wraithFactory[i].monsterPos, &player.playerPos))
        {
            handleDeath();//player is killed
        }
    }


    //if arrow hits mummy from the right
    for(list<Arrow>::iterator itr = arrowListR.begin(); itr!=arrowListR.end(); itr++)
    {
        for(int i = 0; i<2; i++)//for each mummy
        {
            if(phy.Collision(&itr->arrowRpos, &mummyFactory[i].monsterPos))//if arrow collides with mummy's current position
            {
                mummyFactory[i].deadMonsterR = true;//stops updating the monster
                itr->used = true;//sets arrow as used
                mummyFactory[i].monsterAnim = {mummyFactory[i].frame_x*100, mummyFactory[i].frame_y*100, 100, 100};//update death animation
            }

            if(mummyFactory[i].deadMonsterR)//goes into death animation
            {
                if(mummyFactory[i].killedMonsterR(delta.get_ticks()/1000.f))//death animation method
                {
                    mummyFactory[i].monsterDead = true;//sets monster to dead when animation finishes
                }

            }
        }
    }

    //if arrow hits mummy from the left
    for(list<Arrow>::iterator itr = arrowListL.begin(); itr!=arrowListL.end(); itr++)
    {
        for(int i = 0; i<2; i++)//for each mummy
        {
            if(phy.Collision(&itr->arrowLpos, &mummyFactory[i].monsterPos))//if arrow collides with mummy current position
            {
                mummyFactory[i].deadMonsterL = true;//stops updating the monster
                itr->used = true;//set arrow to used
                mummyFactory[i].monsterAnim = {mummyFactory[i].frame_x*100, mummyFactory[i].frame_y*100, 100, 100};//update death animation
            }

            if(mummyFactory[i].deadMonsterL)//goes into death animation
            {
                if(mummyFactory[i].killedMonsterL(delta.get_ticks()/1000.f))//calls death animation method
                {
                    mummyFactory[i].monsterDead = true;//sets monster to dead

                }

            }
        }

    }

    //if mummy is alive and collides with player, kill player
    for(int i = 0; i < 2; i++)
    {
        if(!mummyFactory[i].monsterDead && phy.Collision(&mummyFactory[i].monsterPos, &player.playerPos))
        {
            handleDeath();//player is killed
        }
    }

    //if arrow hits seeker from the right
    for(list<Arrow>::iterator itr = arrowListR.begin(); itr!=arrowListR.end(); itr++)
    {
        if(phy.Collision(&itr->arrowRpos, &seeker.monsterPos))
        {
            seeker.deadMonsterR = true;//stops updating the monster
            itr->used = true;//sets arrow as used
            seeker.monsterAnim = {seeker.frame_x*100, seeker.frame_y*100, 100, 100};//update death animation
        }

        if(seeker.deadMonsterR)//goes into death animation
        {
            if(seeker.killedMonsterR(delta.get_ticks()/1000.f))
            {
                seeker.monsterDead = true;
            }

        }
    }

    //if arrow hits seeker from the left
    for(list<Arrow>::iterator itr = arrowListL.begin(); itr!=arrowListL.end(); itr++)
    {
        if(phy.Collision(&itr->arrowLpos, &seeker.monsterPos))
        {
            seeker.deadMonsterL = true;//stops updating the monster
            itr->used = true;//sets arrow as used
            seeker.monsterAnim = {seeker.frame_x*100, seeker.frame_y*100, 100, 100};//update death animation
        }

        if(seeker.deadMonsterL)//goes into death animation
        {
            if(seeker.killedMonsterL(delta.get_ticks()/1000.f))
            {
                seeker.monsterDead = true;
            }

        }
    }

    //if seeker is alive and collides with player, kill player
    if(!seeker.monsterDead && phy.Collision(&seeker.monsterPos, &player.playerPos))
    {
        handleDeath();//player is killed
    }

    //ghost
    for(list<Arrow>::iterator itr = arrowListR.begin(); itr!=arrowListR.end(); itr++)
    {
        if(phy.Collision(&itr->arrowRpos, &ghost.monsterPos))
        {
            ghost.deadMonsterR = true;//stops updating the monster
            itr->used = true;//sets arrow as used
            ghost.monsterAnim = {ghost.frame_x*122, ghost.frame_y*130, 122, 130};//update death animation
        }

        if(ghost.deadMonsterR)//goes into death animation
        {
            if(ghost.killedMonsterR(delta.get_ticks()/1000.f))
            {
                ghost.monsterDead = true;
                ghost.isLightning = false;
            }

        }
    }

    for(list<Arrow>::iterator itr = arrowListL.begin(); itr!=arrowListL.end(); itr++)
    {
        if(phy.Collision(&itr->arrowLpos, &ghost.monsterPos))
        {
            ghost.deadMonsterL = true;//stops updating the monster
            itr->used = true;//sets arrow as used
            ghost.monsterAnim = {ghost.frame_x*122, ghost.frame_y*130, 122, 130};//update death animation
        }

        if(ghost.deadMonsterL)//goes into death animation
        {
            if(ghost.killedMonsterL(delta.get_ticks()/1000.f))
            {
                ghost.monsterDead = true;
                ghost.isLightning = false;
            }

        }
    }
    //if ghost's lightning hits player, kill player
    if(ghost.isLightning && phy.Collision(&player.playerPos, &ghost.lightningPos))
    {
        handleDeath();
    }
}