#![allow(non_snake_case)]

use std::ops::{Add, Sub, Mul, Div};

#[derive(Debug)]
pub struct Vector2D {
    pub X: f64,
    pub Y: f64,
}

impl Vector2D {
    pub fn New(&self, nx: f64, ny: f64) -> Vector2D {
        Vector2D { X: nx, Y: ny }
    }

    pub fn Magnitude(&self) -> f64 {
        (((self.X * self.X) + (self.Y * self.Y))).sqrt()
    }

    pub fn Normalize(&mut self) {
        let temp_mag = self.Magnitude();
        self.X = self.X / temp_mag;
        self.Y = self.Y / temp_mag;
    }
}

impl Add for Vector2D {
    type Output = Vector2D;

    fn add(self, rhs: Vector2D) -> Vector2D {
        Vector2D {
            X: self.X + rhs.X,
            Y: self.Y + rhs.Y,
        }
    }
}

impl Sub for Vector2D {
    type Output = Vector2D;

    fn sub(self, rhs: Vector2D) -> Vector2D {
        Vector2D {
            X: self.X - rhs.X,
            Y: self.Y - rhs.Y,
        }
    }
}

impl Mul for Vector2D {
    type Output = Vector2D;

    fn mul(self, rhs: Vector2D) -> Vector2D {
        Vector2D {
            X: self.X * rhs.X,
            Y: self.Y * rhs.Y,
        }
    }
}

impl Div for Vector2D {
    type Output = Vector2D;

    fn div(self, rhs: Vector2D) -> Vector2D {
        Vector2D {
            X: self.X / rhs.X,
            Y: self.Y / rhs.Y,
        }
    }
}
