using Unity.VisualScripting;
/// <summary>
/// BPM组单元，用于储存对应时间组的物件速度变化，与乐曲相关
/// </summary>
public class BPMGroup
{
    /*关于时间组与BPM变换的机制
     *BPM变换是一种用来完成适应中间有BPM变换的歌曲的一种机制
     *其原理是通过控制当前BPM的基准BPM的比值，使得NoteSpeed得以变化
     *当BPM变换到比原定的数值更大时，那么音符的速度将会更快
     *当BPM变换到比原定的数值更小时，那么音符的速度将会更慢
     *
     *但是将这种变换设置为全局的是不合适的，因此我们从数据上为Note划分组别
     *使得每一个时间组都可以被单独控制
     *我们将在控制器重创建一个列表，统一管理列表中的所有时间组单元
     *在每一个物件被实例化时，它将被传递对应的时间组单元的引用
     *
     *每一个时间组单元通过更新自身存储的NoteSpeed以达到控制Note的效果
     *因为每一个被创建的物件实例都会不断的通过NoteSpeed更新自身位置
     *
     *由于时间组条数通常在100这个数量级以内，选择字典结构去管理是相对合适的
     */

    /// <summary>
    /// 当前BPM组的NoteSpeed
    /// </summary>
    public float CurrentNoteSpeed
    {
        get
        {
            if (CurrentBPM == 0) return 0;
            //单位向量*基础速度*音符流速*BPM/基准BPM
            return _noteStream * CurrentBPM * _baseSpeed / _baseBPM;
        }
    }
    private float _noteStream;
    private float _baseSpeed;
    private float _baseBPM;
    /// <summary>
    /// 每拍的时间长度（秒）
    /// </summary>
    public float Beat
    {
        get
        {
            return CurrentBPM > 0 ? 60f / CurrentBPM : 0f;
        }
    }
    /// <summary>
    /// 音符相对当前BPM的抵达下落目标所需时间,单位:ms
    /// </summary>
    public float InitializeOffset
    {
        get
        {
            if (CurrentNoteSpeed == 0) return 0;
            //到达目标点的时间
            return TrackLength / CurrentNoteSpeed;
        }
    }
    /// <summary>
    /// 轨道长度,该值应当添加至游戏主控变成玩家偏好设置
    /// </summary>
    private float TrackLength;
    public float CurrentBPM { set; get; }
    public int GroupNum { get; }
    public BPMGroup(float currentBPM, int groupNum, float noteStream, float baseSpeed, float baseBPM, float trackLength)
    {
        CurrentBPM = currentBPM;
        GroupNum = groupNum;
        _noteStream = noteStream;
        _baseSpeed = baseSpeed;
        _baseBPM = baseBPM;
        TrackLength = trackLength;
    }
    public void UpdatePlayerSetting(float noteStream, float baseSpeed, float baseBPM, float trackLength)
    {
        _noteStream = noteStream;
        _baseSpeed = baseSpeed;
        _baseBPM = baseBPM;
        TrackLength = trackLength;
    }
    public override string ToString()
    {
        return $"BPMGroup [Group: {GroupNum}]\n" +
               $"BPM: {CurrentBPM}\n" +
               $"Beat: {Beat:F3}s\n" +
               $"NoteSpeed: {CurrentNoteSpeed:F2}\n" +
               $"Stream: {_noteStream}\n" +
               $"BaseSpeed: {_baseSpeed}\n" +
               $"BaseBPM: {_baseBPM}\n" +
               $"InitializeOffset:{InitializeOffset}\n"+
               $"当前速度:{CurrentNoteSpeed}"
               ;
    }
}