/* date = May 7th 2023 0:37 pm */

#ifndef VN_ANIMATION_CURVE_H
#define VN_ANIMATION_CURVE_H

struct animation_curve_key
{
    u64 Value;
};

inline b32 AreEqual(animation_curve_key A, animation_curve_key B)
{
    b32 Result = (A.Value == B.Value);
    return(Result);
}

struct animation_curve_entry
{
    animation_curve_key Key;
    u32 LastFrameTouched;
    
    r32 Value;
    
    animation_curve_entry *Next;
    animation_curve_entry *Prev;
};

struct animation_curve_bucket
{
    animation_curve_entry *First;
    animation_curve_entry *Last;
};

struct animation_curve_state
{
    memory_arena *Arena;
    
    u32 CurrentFrame;
    r32 dtForFrame;
    
    // sixten: Hash map
    animation_curve_bucket Buckets[256];
    
    // sixten: Free list
    animation_curve_entry *FirstFreeEntry;
    animation_curve_entry *LastFreeEntry;
};

inline void AnimationCurve_SetState(animation_curve_state *State);
inline animation_curve_key AnimationCurve_GenerateKeyFromString(string String);
static void AnimationCurve_Init(animation_curve_state *State);
static animation_curve_entry *AnimationCurve_GetEntryByKey(animation_curve_key Key, r32 Initial = 0);
inline r32 AnimationCurve_GetValue(string Name, r32 Initial);
inline void AnimationCurve_SetValue(string Name, r32 Value);
inline r32 AnimationCurve_AnimateValueDirect(r32 Target, r32 Duration, r32 *Value);
inline r32 AnimationCurve_AnimateValue(r32 Target, r32 Initial, r32 Duration, string Name);
inline r32 AnimationCurve_AnimateValueF(r32 Target, r32 Initial, r32 Duration, char *Format, ...);
static void AnimationCurve_NewFrame(animation_curve_state *State, r32 dtForFrame);

#endif //VN_ANIMATION_CURVE_H
