#ifndef __OGL2_VECTOR2_H__
#define __OGL2_VECTOR2_H__

#if !defined (__GNUG__) && !defined (__attribute__)
#define __attribute__(foo) /* Ignore.  */
#endif

#include <iostream>

extern "C++" {

template <class __type>
struct Vector2 {
  __type x;
  __type y;

  Vector2() :
    x(0), y(0) {}
  Vector2(__type _x, __type _y) :
    x(_x), y(_y) {}

  Vector2<__type>& operator () (__type _x, __type _y) {
    x = _x; y = _y;
    return *this;
  }
  Vector2<__type>& operator () (const Vector2<__type>& b) {
    x = b.x;
    y = b.y;
    return *this;
  }
  Vector2<__type>& operator += (const Vector2<__type>& b) {
    x += b.x;
    y += b.y;
    return *this;
  }
  Vector2<__type>& operator -= (const Vector2<__type>& b) {
    x -= b.x;
    y -= b.y;
    return *this;
  }
  Vector2<__type>& operator *= (const Vector2<__type>& b) {
    x *= b.x;
    y *= b.y;
    return *this;
  }
  Vector2<__type>& operator *= (__type s) {
    x *= s;
    y *= s;
    return *this;
  }
  __type Length () {
    return sqrt(x*x + y*y);
  }
  __type Len () {
    return Length();
  }

  void Unpack(__type* u) {
    u[0] = x;
    u[1] = y;
  }
};

template struct Vector2<GLfloat>;
template struct Vector2<GLdouble>;

typedef Vector2<GLfloat> Vector2f;
typedef Vector2<GLdouble> Vector2d;

template <class __type>
ostream& operator << (ostream& s, const Vector2<__type>& a) {
  return s << "(" << a.x << "," << a.y << ")";
}

template <class __type> inline Vector2<__type>
operator + (const Vector2<__type>& a) __attribute__ ((const));

template <class __type> inline Vector2<__type>
operator + (const Vector2<__type>& a) {
  return a;
}

template <class __type> inline Vector2<__type>
operator - (const Vector2<__type>& a) __attribute__ ((const));

template <class __type> inline Vector2<__type>
operator - (const Vector2<__type>& a) {
  return Vector2<__type> (-a.x, -a.y);
}

template <class __type> inline Vector2<__type>
operator + (const Vector2<__type>& a, const Vector2<__type>& b) __attribute__ ((const));

template <class __type> inline Vector2<__type>
operator + (const Vector2<__type>& a, const Vector2<__type>& b) {
  return Vector2<__type> (a.x+b.x, a.y+b.y);
}

template <class __type> inline Vector2<__type>
operator - (const Vector2<__type>& a, const Vector2<__type>& b) __attribute__ ((const));

template <class __type> inline Vector2<__type>
operator - (const Vector2<__type>& a, const Vector2<__type>& b) {
  return Vector2<__type> (a.x-b.x, a.y-b.y);
}

template <class __type> inline Vector2<__type>
operator * (const Vector2<__type>& a, __type s) __attribute__ ((const));

template <class __type> inline Vector2<__type>
operator * (const Vector2<__type>& a, __type s) {
  return Vector2<__type> (a.x*s, a.y*s);
}

template <class __type> inline Vector2<__type>
operator * (__type s, const Vector2<__type>& a) __attribute__ ((const));

template <class __type> inline Vector2<__type>
operator * (__type s, const Vector2<__type>& a)
{
  return Vector2<__type> (s*a.x, s*a.y);
}

template <class __type> inline Vector2<__type>
operator * (const Vector2<__type>& a, const Vector2<__type>& b) __attribute__ ((const));

template <class __type> inline Vector2<__type>
operator * (const Vector2<__type>& a, const Vector2<__type>& b) {
  return Vector2<__type> (a.x*b.x, a.y*b.y);
}

template <class __type> inline __type
Dot (const Vector2<__type>& a, const Vector2<__type>& b) __attribute__ ((const));

template <class __type> inline __type
Dot (const Vector2<__type>& a, const Vector2<__type>& b) {
  return (a.x*b.x + a.y*b.y);
}

} // extern "C++"

#endif 
