/*
 * Author:          Patrick-Christopher Mattulat
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2022-08-05
 * Changed:         2022-08-07
 *
 * */

#include <ls-math/vector/Vector2.hpp>
#include <cmath>

ls::math::vector::Vector2::Vector2(const ls::math::core::type::vector2_component &_x, const ls::math::core::type::vector2_component &_y)
{
  this->components[0] = _x;
  this->components[1] = _y;
}

ls::math::vector::Vector2 ls::math::vector::Vector2::operator+(const ls::math::vector::Vector2& _vector) const
{
  return ls::math::vector::Vector2::_add(*this, _vector);
}

ls::math::vector::Vector2 ls::math::vector::Vector2::operator-(const ls::math::vector::Vector2& _vector) const
{
  return ls::math::vector::Vector2::_subtract(*this, _vector);
}

ls::math::core::type::vector_scalar ls::math::vector::Vector2::operator*(const ls::math::vector::Vector2& _vector) const
{
  return ls::math::vector::Vector2::_dot(*this, _vector);
}

ls::math::vector::Vector2 ls::math::vector::Vector2::operator*(double _value)
{
  return ls::math::vector::Vector2{components[0] * _value, components[1] * _value};
}

ls::math::vector::Vector2 ls::math::vector::Vector2::operator/(double _divisor)
{
  return ls::math::vector::Vector2::_operatorDivision(this->components[0], this->components[1], _divisor);
}

bool ls::math::vector::Vector2::operator==(const ls::math::vector::Vector2 &_vector)
{
  return this->components[0] == _vector.components[0] && this->components[1] == _vector.components[1];
}

bool ls::math::vector::Vector2::operator!=(const ls::math::vector::Vector2 &_vector)
{
  return this->components[0] != _vector.components[0] || this->components[1] != _vector.components[1];
}

ls::math::vector::Vector2 ls::math::vector::Vector2::add(const ls::math::vector::Vector2 &_leftAddend, const ls::math::vector::Vector2 &_rightAddend)
{
  return ls::math::vector::Vector2::_add(_leftAddend, _rightAddend);
}

ls::math::core::type::vector_scalar ls::math::vector::Vector2::dot(const ls::math::vector::Vector2 &_leftAddend, const ls::math::vector::Vector2 &_rightAddend)
{
  return ls::math::vector::Vector2::_dot(_leftAddend, _rightAddend);
}

ls::math::core::type::vector2_components ls::math::vector::Vector2::getComponents()
{
  return this->components;
}

double ls::math::vector::Vector2::getLength()
{
  return ls::math::vector::Vector2::_getLength(this->components[0], this->components[1]);
}

ls::math::core::type::vector2_component ls::math::vector::Vector2::getX()
{
  return this->components[0];
}

ls::math::core::type::vector2_component ls::math::vector::Vector2::getY()
{
  return this->components[1];
}

ls::math::vector::Vector2 ls::math::vector::Vector2::normalize()
{
  double length = ls::math::vector::Vector2::_getLength(this->components[0], this->components[1]) + std::numeric_limits<double>::min();
  return ls::math::vector::Vector2::_operatorDivision(this->components[0], this->components[1], length);
}

void ls::math::vector::Vector2::setX(const ls::math::core::type::vector2_component &_value)
{
  this->components[0] = _value;
}

void ls::math::vector::Vector2::setY(const ls::math::core::type::vector2_component &_value)
{
  this->components[1] = _value;
}

ls::math::vector::Vector2 ls::math::vector::Vector2::subtract(const ls::math::vector::Vector2 &_leftAddend, const ls::math::vector::Vector2 &_rightAddend)
{
  return ls::math::vector::Vector2::_subtract(_leftAddend, _rightAddend);
}

ls::math::vector::Vector2 ls::math::vector::Vector2::_add(const ls::math::vector::Vector2 &_leftAddend, const ls::math::vector::Vector2 &_rightAddend)
{
  return ls::math::vector::Vector2{_leftAddend.components[0] + _rightAddend.components[0], _leftAddend.components[1] + _rightAddend.components[1]};
}

ls::math::core::type::vector_scalar ls::math::vector::Vector2::_dot(const ls::math::vector::Vector2 &_leftAddend, const ls::math::vector::Vector2 &_rightAddend)
{
  return _leftAddend.components[0] * _rightAddend.components[0] + _leftAddend.components[1] * _rightAddend.components[1];
}

ls::math::vector::Vector2 ls::math::vector::Vector2::_subtract(const ls::math::vector::Vector2 &_leftAddend, const ls::math::vector::Vector2 &_rightAddend)
{
  return ls::math::vector::Vector2{_leftAddend.components[0] - _rightAddend.components[0], _leftAddend.components[1] - _rightAddend.components[1]};
}

double ls::math::vector::Vector2::_getLength(const ls::math::core::type::vector2_component& _x, const ls::math::core::type::vector2_component& _y)
{
  return sqrt(_x * _x + _y * _y);
}

ls::math::vector::Vector2 ls::math::vector::Vector2::_operatorDivision(const ls::math::core::type::vector2_component &_x, const ls::math::core::type::vector2_component &_y, double _divisor)
{
  return ls::math::vector::Vector2{_x / _divisor, _y / _divisor};
}
