#include "Easer.h"

//Sets 'position' to 'newPosition'.
void Easer::SetPosition(float position)
{
    this->Position = position;
}

//Resets 'position' to 0.0f. This is the same as calling SetPosition(0.0f);
void Easer::Reset()
{
    this->Position = 0.0f;
}

//Returns true if 'position' is at or beyond 1.0f.
bool Easer::AtEnd() const
{
    return (this->Position >= 1.0f);
}

//Returns the value at the current position.
//(Note: Unless constrained, the actual result may actually drop below 0.0f or above 1.0f depending
//on the easing function. This is intentional, and desirable for some effects)
float Easer::Get() const
{
    return this->plot(this->Position);
}

//Returns the value at the current position, scaled to the range of 'min' to 'max' instead of around (0.0f - 1.0f)-ish
float Easer::GetInRange(const FloatRange &range) const
{
    float value = this->plot(this->Position);
    return range.GetAt(value);
}

//Returns the value at 'pos'.
float Easer::GetAt(float pos) const
{
    return this->plot(pos);
}

//Returns the value at 'pos', scaled to the range of 'min' to 'max' instead of around (0.0f - 1.0f)-ish
float Easer::GetInRangeAt(float pos, const FloatRange &range) const
{
    float value = this->plot(pos);
    return range.Constrained(value);
}
    
//Moves the position of the ease by 'amount'.
void Easer::Step(float amount)
{
    this->Position += amount;
}

//Same as Step().
void Easer::operator+=(float amount)
{
    this->Step(amount);
}

//Same as Step() with a negative amount.
void Easer::operator-=(float amount)
{
    this->Step(-amount);
}

//Same as SetPosition().
void Easer::operator=(float position)
{
    this->SetPosition(position);
}

//Same as Get()
float Easer::operator()() const
{
    return this->Get();
}

//Same as GetAt()
float Easer::operator()(float value) const
{
    return this->GetAt(value);
}

//Calls the virtual function 'plot' and processes the result depending on the EaseStyle.
float Easer::plot(float position) const
{
    //Binds 'position' from 0.0 to 1.0.
    //if(position > 1.0f) position = 1.0f;
    //if(position < 0.0f) position = 0.0f;
    
    float result;
    
    if(this->Style == EaseIn)
    {
        //Plots the position.
        result = this->EaseFunc(position);
    }
    else if(this->Style == EaseOut)
    {
        //Plots the position.
        result = DoEaseOut(this->EaseFunc, position);
    }
    else if(this->Style == EaseInOut)
    {
        //Plots the position.
        result = DoEaseInOut(this->EaseFunc, position);
    }
    else if(this->Style == EaseOutIn)
    {
        //Plots the position.
        result = DoEaseOutIn(this->EaseFunc, position);
    }
    
    //Constrains the result and returns.
    return this->Constaints.Constrained(result);
}