#include "GameMapCamera.h"
#include "EngineCore/Game.h"
#include "Actor/Map/GameMap.h"
#include "Actor/Object/BaseObject.h"
#include <algorithm>

GameMapCamera::GameMapCamera()
{
}

GameMapCamera::~GameMapCamera()
{
}

void GameMapCamera::SetFromActor(BaseObject *actor)
{
    this->_FromActor = actor;
    _FromActor->_AffCamera = this;
}

void GameMapCamera::Update(float deltaTime)
{
    SyncPosByFromParent(deltaTime);
}

void GameMapCamera::SyncPos(float deltaTime)
{
}

void GameMapCamera::SetPos(int x, int y, int z)
{
    // this->X = x;
    // this->Y = y;
    // this->Z = z;
}

void GameMapCamera::AddPos(int x, int y, int z)
{
    // this->X += x;
    // this->Y += y;
    // this->Z += z;
}

void GameMapCamera::SyncPosByFromParent(float deltaTime)
{
    if (this->_FromActor == nullptr)
    {
        return;
    }
    int targetX = _FromActor->Position.x;
    int targetY = _FromActor->Position.y;

    if (_isSmoothMoving)
    {
        // 平滑移动计算
        VecPos targetPosition(targetX, targetY);
        _currentPosition = SmoothDamp(_currentPosition, targetPosition, _velocity, _smoothTime, _maxSpeed, deltaTime);
    }
    else
    {
        _currentPosition.x = targetX;
        _currentPosition.y = targetY;
    }
}

VecPos GameMapCamera::SmoothDamp(const VecPos &current, const VecPos &target, VecPos &currentVelocity, float smoothTime, int maxSpeed, float deltaTime)
{
    // 平滑时间为0时直接返回目标位置并重置速度
    if (smoothTime <= 0.f)
    {
        currentVelocity = VecPos(0, 0);
        return target;
    }

    // 临界阻尼系数计算（避免过冲的核心参数）
    const float omega = 2.0f / smoothTime;
    const float x = omega * deltaTime;
    const float expTerm = 1.0f / (1.0f + x + 0.48f * x * x + 0.235f * x * x * x);

    // 计算当前位置与目标的差值
    VecPos delta = target - current;

    // 计算目标速度（基于阻尼公式和当前差值）
    // 注意：这里先通过浮点计算保持精度，最后转换为整数
    const float tx = delta.x * (omega * omega * deltaTime) - currentVelocity.x * (1.0f + 0.48f * x) * x;
    const float ty = delta.y * (omega * omega * deltaTime) - currentVelocity.y * (1.0f + 0.48f * x) * x;
    VecPos targetVelocity(static_cast<int>(tx), static_cast<int>(ty));

    // 应用速度衰减（指数平滑）
    currentVelocity += targetVelocity;
    currentVelocity = VecPos(
        static_cast<int>(currentVelocity.x * expTerm),
        static_cast<int>(currentVelocity.y * expTerm));

    // 限制最大速度（如果设置了maxSpeed）
    if (maxSpeed > 0)
    {
        // 计算当前速度的模长（浮点精度）
        const float speedSq = static_cast<float>(currentVelocity.x * currentVelocity.x + currentVelocity.y * currentVelocity.y);
        const float maxSpeedSq = static_cast<float>(maxSpeed * maxSpeed);

        if (speedSq > maxSpeedSq)
        {
            // 速度超限，按比例缩放至最大速度
            const float scale = maxSpeed / sqrtf(speedSq);
            currentVelocity = VecPos(
                static_cast<int>(currentVelocity.x * scale),
                static_cast<int>(currentVelocity.y * scale));
        }
    }

    // 计算新位置（当前位置 + 速度 * 时间）
    VecPos newPos = current + VecPos(
                                  static_cast<int>(currentVelocity.x * deltaTime),
                                  static_cast<int>(currentVelocity.y * deltaTime));

    // 检测过冲：如果新位置已越过目标，直接锁定目标并重置速度
    // 点积 > 0 表示方向相反（已超过目标）
    const int dot = delta.x * (newPos.x - target.x) + delta.y * (newPos.y - target.y);
    if (dot > 0)
    {
        newPos = target;
        currentVelocity = VecPos(0, 0);
    }

    return newPos;
}