package Algorithm::Easing::Quadratic;

use Moo;

use Math::Trig qw(:pi);

use constant EPSILON => 0.000001;

extends 'Algorithm::Easing::Ease';

use namespace::clean;

sub ease_in  {
    my $self = shift;
    my ($t,$b,$c,$d) = (shift,shift,shift,shift);

    return $b if ($t < EPSILON);
    return $c if ($d < EPSILON);

    return $c * ($t /= $d) * $t + $b;
}

sub ease_out  {
    my $self = shift;
    my ($t,$b,$c,$d) = (shift,shift,shift,shift);

    return $b if ($t < EPSILON);
    return $c if ($d < EPSILON);
    
    return -$c *($t /= $d) * ($t - 2) + $b;
}

sub ease_both  {
    my $self = shift;
    my ($t,$b,$c,$d) = (shift,shift,shift,shift);

    return $b if ($t < EPSILON);
    return $c if ($d < EPSILON);

    if (($t /= $d / 2) < 1) {
        return (($c / 2) * ($t * $t)) + $b;
    }
    return -$c / 2 * ((($t - 2)*(--$t)) - 1) + $b;
}

1;

__END__

# MAN3 POD

=head1 NAME

Algorithm::Easing::Quadratic - Calculate eased translations between two positive whole integer values over time

=head1 SYNOPSIS

        ## with mediator

        use Algorithm::Easing;
        use Algorithm::Easing::Quadratic;

        # this example produces traditional 'quadratic' output;

        my $translation = Algorithm::Easing::Quadratic->new;

        # total time for eased translation as a real positive integer value
        my $d = 2.5;

        # begin
        my $b = 0;

        # change
        my $c = 240;

        # time passed in seconds as a real positive integer between each frame
        my $frame_time = 0.0625;

        my @p = [319,0];

        for(my $t = 0; $t < 2.5; $t += 0.0625) {
            $p[1] = $translation->ease_out($t,$b,$c,$d)

            # plot
            ...;
        }

=head1 INTRODUCTION

Commonly used in animation, Penner's easing functions are beautiful translations between two positive whole integer values.

The included easing functions in Algorithm::Easing are :

=over
=item Exponential
=item Elastic
=item Bounce
=item Linear
=item Cubic
=item Quadratic
=item Quartinion
=item Quintonion
=item Sinusoidal
=item Backdraft
=item Circular
=back

For ease of use, there is an included Mediator class.  The Mediator class permits the programmer to select from the spread of easing functions through a single class name.

=over
=item ease_none
    Usage :
    
        Arguments : 
            t = time,
            b = begin,
            c = change,
            d = duration,
        Return :
            p = position,
            
        my $p = $obj->ease_both($t,$b,$c,$d);

This method is used for a linear translation between two positive real whole integers using a positive real integer as the parameter for time.

=item ease_in
    Usage :
    
        Arguments : 
            t = time,
            b = begin,
            c = change,
            d = duration,
        Return :
            p = position,
            
        my $p = $obj->ease_both($t,$b,$c,$d);

This method is used for a eased translation between two positive real whole integers as an inward tween using a positive real integer as the parameter for time.

=item ease_out
    Usage :
    
        Arguments : 
            t = time,
            b = begin,
            c = change,
            d = duration,
        Return :
            p = position,
            
        my $p = $obj->ease_both($t,$b,$c,$d);

This method is used for a eased translation between two positive real whole integers as an outward tween using a positive real integer as the parameter for time.

=item ease_both
    Usage :
    
        Arguments : 
            t = time,
            b = begin,
            c = change,
            d = duration,
        Return :
            p = position,
            
        my $p = $obj->ease_both($t,$b,$c,$d);

This method is used for a eased translation between two positive real whole integers as an inward then outward tween using a positive real integer as the parameter for time.

=back
=head1 AUTHOR

Jason McVeigh, <jmcveigh@outlook.com>

=head1 COPYRIGHT AND LICENSE

Copyright 2016 by Jason McVeigh

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=back
=cut