

#if !COMBAT_SERVER
using UnityEngine;
#endif

public class ParabolaPath
{
    public Vector2 startPos;
    public Vector2 targetPos;
    private Vector2 posOff;

    private float gravity = (float)(-19);

    public float addH;

    public ParabolaPath()
    {
    }

    public ParabolaPath(Vector2 startPos, Vector2 targetPos)
    {
        SetPos(startPos, targetPos);
    }

    // public void SetPos(Vector2 startPos, Vector2 targetPos)
    // {
    //     SetPos(new Vector2(startPos), new Vector2(targetPos));
    // }

    public void SetPos(Vector3 startPos, Vector3 targetPos)
    {
        SetPos(startPos, targetPos);
    }

    public void SetPos(Vector2 startPos, Vector2 targetPos)
    {
        this.startPos = startPos;
        this.targetPos = targetPos;
        posOff = this.targetPos - this.startPos;
    }

    public Vector2 GetPos(float t)
    {
        t = Mathf.Clamp(t,0,1);
        float h = posOff.y + posOff.magnitude / 2 + addH;
        float v0;
        float angle;
        float time;
        CalculatePathWithHeight(posOff, h, out v0, out angle, out time);
        return CalculatePath(v0, angle, time, t);
    }

    private Vector2 CalculatePath(float v0, float angle, float step, float t)
    {
        float v = step * t;
        float x = v0 * v * Mathf.Cos(angle);
        float y = v0 * v * Mathf.Sin(angle) - 0.5f * -gravity * Mathf.Pow(v, (float)2);
        return new Vector2(x, y) + startPos;
    }

    private float QuadraticEquation(float a, float b, float c, float sign)
    {
        float v = b * b - 4 * a * c;
        v = Mathf.Max((float)0.01f, v);

        return (-b + sign * Mathf.Sqrt(v)) / (2 * a);
    }

    private void CalculatePathWithHeight(Vector2 targetPos, float h, out float v0, out float angle, out float time)
    {
        h = Mathf.Max((float)0.01f, h) * 0.5f;
        float xt = targetPos.x;
        float yt = targetPos.y;
        float g = -gravity;


        float a = (-0.5f * g);
        float c = -yt;
        float b = Mathf.Sqrt(2 * g * h);


        float tplus = QuadraticEquation(a, b, c, (float)1);
        float tmin = QuadraticEquation(a, b, c, (float)(-1));
        time = tplus > tmin ? tplus : tmin;
        angle = Mathf.Atan(b * time / xt);
        v0 = b / Mathf.Sin(angle);
    }
}