#include "ParticleUtils.h"

#include "CasualCore/Game.h"
#include "CasualCore/Graphics/Scene.h"
#include "CasualCore/Graphics/Object.h"
#include "CasualCore/Graphics/ParticleManager.h"
#include "CasualCore/Graphics/ParticleEmitter.h"

#if defined(BNE_OBJECT_CROSSOVER)
#include "Utils/ObjectUtils.h"
#endif // defined(BNE_OBJECT_CROSSOVER)
#if defined(BNE_OBJECT_PARTICLE_LEVEL)
#include "CasualCore/Events/RKEvent.h"
#endif // defined(BNE_OBJECT_PARTICLE_LEVEL)


CasualCore::Object* ParticleUtils::SpawnPFX(const char * a_pfxName, bool a_selfDelete, const char * a_objectClassName)
{
  CasualCore::ParticleManager *pParticleManager = CasualCore::Game::GetInstance()->GetParticleManager();

#if defined(BNE_OBJECT_PARTICLE_LEVEL)
  CasualCore::Level *pLevel = RKEventVFX::GetParticleLevel();
#else // (!)defined(BNE_OBJECT_PARTICLE_LEVEL)
  CasualCore::Level *pLevel = NULL;
#endif // defined(BNE_OBJECT_PARTICLE_LEVEL)

#if defined(BNE_OBJECT_CROSSOVER)
  if (!pParticleManager || !pParticleManager->CanAddEmitter() || !pLevel)
#else // (!)defined(BNE_OBJECT_CROSSOVER)
  if (!pParticleManager || !pParticleManager->CanAddEmitter())
#endif // defined(BNE_OBJECT_CROSSOVER)
  {
    return nullptr;
  }

  // Create the object in the scene
#if defined(BNE_OBJECT_CROSSOVER)
  RKTransformObject *pTransformObject = bne::object::CreateFromType(a_objectClassName ? a_objectClassName : "Object", pLevel);
#else // (!)defined(BNE_OBJECT_CROSSOVER)
  RKTransformObject *pTransformObject = CasualCore::Game::GetInstance()->GetScene()->AddObjectWithRenderable(a_objectClassName ? a_objectClassName : "Object", a_pfxName, pLevel ? pLevel->GetLevelName().GetString() : NULL);
#endif // defined(BNE_OBJECT_CROSSOVER)
  CasualCore::Object* obj = NULL;
  if(pTransformObject && pTransformObject->IsCCObject())
  {
    obj = (CasualCore::Object*)pTransformObject;
#if defined(BNE_OBJECT_CROSSOVER)
    obj->Reload(a_pfxName);
#endif // defined(BNE_OBJECT_CROSSOVER)
  }
  if (!obj ||
    !obj->GetRenderable() ||
    !obj->GetRenderable()->GetEmitter())  // If there is no emitter, no point in this PFX?
  {
    // Delete object that cannot be added
    if (obj)
    {
#if defined(BNE_OBJECT_CROSSOVER)
      bne::object::Destroy(obj);
#else // (!)defined(BNE_OBJECT_CROSSOVER)
      CasualCore::Game::GetInstance()->GetScene()->RemoveObject(obj);
#endif // defined(BNE_OBJECT_CROSSOVER)
    }
    return nullptr;
  }

  // Check if particle system is highend only and if we are running low detail settings
  CasualCore::GameSettings *pSettings = CasualCore::Game::GetInstance()->GetSettings();
  if(pSettings)
  {
    if(obj->GetRenderable()->GetEmitter()->GetParticleEmitterType()->m_bHighendOnly && !pSettings->m_highEndObjects)
    {
      bne::object::Destroy(obj);
      return nullptr;
    }
  }

  obj->MarkNoSave();
  obj->SetUpdatable(true);

  // Mark for self deletion
  if (a_selfDelete)
  {
    obj->GetRenderable()->GetEmitter()->SetDynamic();
  }

  return obj;
}

CasualCore::Object* ParticleUtils::SpawnPFX(const char * a_pfxName, const RKVector & a_worldPosition, bool a_selfDelete, const char * a_objectClassName)
{
  CasualCore::Object* obj = SpawnPFX(a_pfxName, a_selfDelete, a_objectClassName);
  if (obj)
  {
    obj->SetWorldPosition(a_worldPosition);
  }

  return obj;
}

void ParticleUtils::KillParticles()
{
  CasualCore::ParticleManager *pParticleManager = CasualCore::Game::GetInstance()->GetParticleManager();
  if (pParticleManager)
  {
    pParticleManager->KillThemAllNow();
  }
}
