#include <math.h>

#include "vector.h"

// Properties
const double degreeToRadians = M_PI / 180.0f;
// End Properties

Vector vectorScale(Vector v, double factor){
    return (Vector)
           {
               .x = v.x * factor,
               .y = v.y * factor
           };
}

double vectorMagnitude(Vector v){
    return sqrt((v.x * v.x) + (v.y * v.y));
}

double vectorRotation(Vector v){
    double da = atan2(v.x, -v.y) / degreeToRadians;

    if (da < 0.0f) return (da + 360.0f);
    else return da;
}

Vector vectorScaleTo(Vector v, double magnitude){
    return vectorScale(v, magnitude / vectorMagnitude(v));
}

double dotProduct(Vector v1, Vector v2){
    return (v1.x * v2.x ) + (v1.y * v2.y);
}

double vectorDist(Vector v1, Vector v2){
    return sqrt(dotProduct(v1, v2));
}

Vector vectorAdd(Vector v1, Vector v2){
    return (Vector)
           {
               .x = v1.x + v2.x,
               .y = v1.y + v2.y
           };
}

Vector vectorSub(Vector v1, Vector v2){
    return (Vector)
           {
               .x = v1.x - v2.x,
               .y = v1.y - v2.y
           };
}

double degreeSin(double x){
    return sin(x * degreeToRadians);
}

double degreeCos(double x){
    return cos(x * degreeToRadians);
}

Vector getDirectionalUnitVector(double rotation){
    return (Vector)
           {
               .x = degreeSin(rotation),
               .y = -degreeCos(rotation)
           };
}

Vector getScaledDirectionalUnitVector(double rotation, double Magnitude){
    Vector v = (Vector)
    {
        .x = degreeSin(rotation),
        .y = -degreeCos(rotation)
    };

    return vectorScale(v, Magnitude);
}

Vector getScaledVectorFromTo(Vector from, Vector to, double Magnitude){
    return vectorScale(vectorSub(to, from), Magnitude);
}
