//
// Created by Tristan on 1/4/2026.
//

#include <math.h>
#include "vector.h"


float vec3_length(vec3_t v) {
    return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}

// Addition
vec3_t vec3_add(vec3_t a, vec3_t b) {
    vec3_t result = {
        .x = a.x + b.x,
        .y = a.y + b.y,
        .z = a.z + b.z
    };

    return result;
}

// Subtraction
vec3_t vec3_sub(vec3_t a, vec3_t b) {
    vec3_t result = {
        .x = a.x - b.x,
        .y = a.y - b.y,
        .z = a.z - b.z
    };

    return result;
}

// Multiplication
vec3_t vec3_mul(vec3_t v, float factor) {
    vec3_t result = {
        .x = v.x * factor,
        .y = v.y * factor,
        .z = v.z * factor
    };

    return result;
}

// Division
vec3_t vec3_div(vec3_t v, float factor) {
    vec3_t result = {
        .x = v.x / factor,
        .y = v.y / factor,
        .z = v.z / factor
    };

    return result;
}

// Cross Product - helps to find the perpendicular vector between two vectors
vec3_t vec3_cross(vec3_t a, vec3_t b) {
    vec3_t result = {
        .x = a.y * b.z - a.z * b.y,
        .y = a.z * b.x - a.x * b.z,
        .z = a.x * b.y - a.y * b.x
    };

    return result;
}

// Dot Product - helps to find how aligned two vectors are to each other
float vec3_dot(vec3_t a, vec3_t b) {
    return (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
}

// Normalize a vec3_t vector
void vec3_normalize(vec3_t* v) {
    float length = sqrt((v->x * v->x) + (v->y * v->y) + (v->z * v->z));

    // avoid dividing by 0
    if (length < 0.00001f) {
        v->x = 0;
        v->y = 0;
        v->z = 0;

        return;
    }

    v->x /= length;
    v->y /= length;
    v->z /= length;
}

vec3_t vec3_rotate_x(vec3_t v, float angle) {
   vec3_t rotated_vector = {
      .x = v.x,
      .y = v.y * cos(angle) - v.z * sin(angle),
      .z = v.y * sin(angle) + v.z * cos(angle)
   };
   return rotated_vector;
}

vec3_t vec3_rotate_y(vec3_t v, float angle) {
   vec3_t rotated_vector = {
      .x = v.x * cos(angle) - v.z * sin(angle),
      .y = v.y,
      .z = v.x * sin(angle) + v.z * cos(angle)
   };
   return rotated_vector;
}

vec3_t vec3_rotate_z(vec3_t v, float angle) {
   vec3_t rotated_vector = {
      .x = v.x * cos(angle) - v.y * sin(angle),
      .y = v.x * sin(angle) + v.y * cos(angle),
      .z = v.z
   };
   return rotated_vector;
}
