// Copyright (C) 2021 - Sebastien Alaiwan
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.

#include "base/scene.h"
#include "base/util.h"

#include "gameplay/collision_groups.h"
#include "gameplay/entity.h"
#include "gameplay/entity_factory.h"
#include "gameplay/models.h" // MDL_BLOCK
#include "gameplay/player.h"
#include "gameplay/toggle.h"
#include "gameplay/vec.h"

#include <cmath>

namespace
{
struct ExitPoint : Entity
{
  ExitPoint(IEntityConfig*)
  {
    solid = 0;
    size = UnitSize;
    collisionGroup = 0;
    collidesWith = CG_PLAYER | CG_SOLIDPLAYER;
    Body::onCollision = [this] (Body* other) { onCollide(other); };
  }

  void addActors(std::vector<SpriteActor>& actors) const override
  {
    auto r = SpriteActor { pos + size / 2, MDL_RECT };
    r.scale = size;
    r.action = 3;
    r.ratio = fmod(m_time, 1);

    actors.push_back(r);
  }

  void onCollide(Body* other)
  {
    if(!active)
      return;

    if(!dynamic_cast<Playerable*>(other))
      return;

    const int remaining = game->getVariable(-2)->get();

    if(remaining)
    {
      char buf[256];
      snprintf(buf, 255, "Still missing %d trinkets", remaining);
      game->textBox(buf);
      return;
    }

    game->stopMusic();
    active = false;
    timer = 150;
  }

  void tick() override
  {
    m_time += 0.03;

    if(m_time >= 1.0f)
      m_time -= 1.0f;

    if(active)
      return;

    game->setAmbientLight(1.0 - timer / 150.0);

    if(decrement(timer))
    {
      game->postEvent(std::make_unique<FinishGameEvent>());
      active = true;
    }
  }

  bool active = true;
  int timer = 0;
  float m_time = 0;
};

DECLARE_ENTITY("exitpoint", ExitPoint);
}

