#include "character/CharacterShadowActor.h"
#include <algorithm>

namespace frostbite2D {
namespace {

constexpr Color kShadowColor(0.0f, 0.0f, 0.0f, 0.42f);
const Vec2 kShadowScale(0.9f, 0.30f);
constexpr float kShadowSkewX = 50.0f;

} // namespace

CharacterShadowActor::CharacterShadowActor() {
  SetName("characterShadow");
  SetColor(kShadowColor);
  SetScale(kShadowScale);
  // Anchor stays on the ground point while the upper silhouette falls left.
  SetSkew(kShadowSkewX, 0.0f);
  SetBlendMode(BlendMode::Normal);
  SetVisible(false);
}

void CharacterShadowActor::ApplyFrameSnapshot(
    const CharacterShadowFrameSnapshot& snapshot) {
  bool hasTexture = snapshot.visible && snapshot.texture && snapshot.textureSize.x > 0.0f &&
                    snapshot.textureSize.y > 0.0f;
  if (!hasTexture) {
    SetVisible(false);
    return;
  }

  ApplyTextureState(snapshot);
  SetPosition(snapshot.groundScreenPosition);
  SetZOrder(snapshot.zOrder);
  SetVisible(true);
}

void CharacterShadowActor::ApplyTextureState(
    const CharacterShadowFrameSnapshot& snapshot) {
  if (appliedTexture_ == snapshot.texture &&
      appliedTextureSize_ == snapshot.textureSize &&
      appliedGroundAnchorInTexture_ == snapshot.groundAnchorInTexture &&
      appliedTextureVersion_ == snapshot.textureVersion) {
    return;
  }

  SetTexture(snapshot.texture);
  SetSize(snapshot.textureSize);

  float safeWidth = std::max(snapshot.textureSize.x, 1.0f);
  float safeHeight = std::max(snapshot.textureSize.y, 1.0f);
  SetAnchor(std::clamp(snapshot.groundAnchorInTexture.x / safeWidth, 0.0f, 1.0f),
            std::clamp(snapshot.groundAnchorInTexture.y / safeHeight, 0.0f, 1.0f));

  appliedTexture_ = snapshot.texture;
  appliedTextureSize_ = snapshot.textureSize;
  appliedGroundAnchorInTexture_ = snapshot.groundAnchorInTexture;
  appliedTextureVersion_ = snapshot.textureVersion;
}

} // namespace frostbite2D
