#ifndef __AMSMATHUTIL25_VEC2_HPP__
#define __AMSMATHUTIL25_VEC2_HPP__

namespace ams
{

class vec2
{
public:
    double x;
    double y;

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

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

//vector operations
double vec2_dot(vec2 v1, vec2 v2);
double vec2_norm(vec2 v);
vec2 vec2_normalize(vec2 v);
double vec2_dist(vec2 v1, vec2 v2);
double vec2_cross(vec2 v1, vec2 v2);
vec2 vec2_proj(vec2 v1, vec2 v2);
vec2 vec2_hodgedual(vec2 v); 
double vec2_arg(vec2 v);

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

class mat2
{
public:
    double data[4];

    mat2();
    mat2(double _xx, double _yx, double _xy, double _yy);
    mat2(const double *_data);
    mat2(const mat2 &rhs);
    mat2(const vec2 _col1, const vec2 _col2);

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

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

    mat2 operator*(double rhs) const;
    mat2 operator/(double rhs) const;
    vec2 operator*(vec2 rhs) const;

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

    double det();
    mat2 inverse();
    void invert();
    mat2 transpose();
    void dotranspose();
};

//matrix operations
mat2 mat2_eye();
mat2 mat2_zeros();
mat2 mat2_ones();

mat2 mat2_mult(mat2 a, mat2 b);
vec2 mat2_mult(vec2 a, mat2 b);
vec2 mat2_mult(mat2 a, vec2 b);

double mat2_det(mat2 a);
mat2 mat2_inverse(mat2 a);
mat2 mat2_transpose(mat2 a);



}; //end namespace ams

#endif

