#ifndef __AMSMATHUTIL25_VEC2F_HPP__
#define __AMSMATHUTIL25_VEC2F_HPP__

namespace ams
{

class vec2f
{
public:
    float x;
    float y;

    vec2f();
    vec2f(float _x, float _y);
    vec2f(const vec2f &rhs);
    vec2f& operator=(const vec2f &rhs);
    bool operator==(vec2f rhs);
    
    vec2f operator+(vec2f rhs) const;
    vec2f operator-(vec2f rhs) const;
    vec2f operator*(float rhs) const;
    vec2f operator/(float rhs) const;
    friend vec2f operator-(vec2f rhs);

    float& operator[](int ind);
    const float& operator[](int ind) const;
};

//vector operations
float vec2f_dot(vec2f v1, vec2f v2);
float vec2f_norm(vec2f v);
vec2f vec2f_normalize(vec2f v);
float vec2f_dist(vec2f v1, vec2f v2);
float vec2f_cross(vec2f v1, vec2f v2);
vec2f vec2f_proj(vec2f v1, vec2f v2);
vec2f vec2f_hodgedual(vec2f v); 
float vec2f_arg(vec2f v);

//vector operations (old nomenclature)
float vdot(vec2f v1, vec2f v2);
float vnorm(vec2f v);
vec2f vnormalize(vec2f v);
float vdist(vec2f v1, vec2f v2);
float vcross(vec2f v1, vec2f v2);
vec2f vproj(vec2f v1, vec2f v2);

class mat2f
{
public:
    float data[4];

    mat2f();
    mat2f(float _xx, float _yx, float _xy, float _yy);
    mat2f(const float *_data);
    mat2f(const mat2f &rhs);
    mat2f(const vec2f _col1, const vec2f _col2);

    mat2f& operator=(const mat2f rhs);
    bool operator==(const mat2f rhs);

    mat2f operator+(mat2f rhs) const;
    mat2f operator-(mat2f rhs) const;
    mat2f operator*(mat2f rhs) const;
    mat2f operator/(mat2f rhs) const;

    mat2f operator*(float rhs) const;
    mat2f operator/(float rhs) const;
    vec2f operator*(vec2f rhs) const;

    float& operator()(int I, int J);
    float& operator[](int I);
    const float& operator()(int I, int J) const;
    const float& operator[](int I) const;
    float& at(int I, int J);
    const float& at(int I, int J) const;

    float det();
    mat2f inverse();
    void invert();
    mat2f transpose();
    void dotranspose();
};

//matrix operations
mat2f mat2f_eye();
mat2f mat2f_zeros();
mat2f mat2f_ones();

mat2f mat2f_mult(mat2f a, mat2f b);
vec2f mat2f_mult(vec2f a, mat2f b);
vec2f mat2f_mult(mat2f a, vec2f b);

float mat2f_det(mat2f a);
mat2f mat2f_inverse(mat2f a);
mat2f mat2f_transpose(mat2f a);



}; //end namespace ams

#endif

