/*
  vector2.h: header for C equivalent of:

  class Vector2
      double x, y;
      double method magnitude();
      double method distance_to( Vector2 p );
      void method add( Vector2 v );
      void method scale( double n );
      void method normalize();
      void method print();
  }
*/

typedef struct Vector2 *Vector2;	                   // all objects are pointers

// foreach method, declare a type definition to make life easier
// note that every method, and hence method signature, takes "this" first.
typedef double (*Vector2_magnitude   )( Vector2 this );
typedef double (*Vector2_distance_to )( Vector2 this, Vector2 other );
typedef void   (*Vector2_add         )( Vector2 this, Vector2 other );
typedef void   (*Vector2_normalize   )( Vector2 this );
typedef void   (*Vector2_print       )( Vector2 this );
typedef void   (*Vector2_scale       )( Vector2 this, double d );
typedef void   (*Vector2_dispose     )( Vector2 this );

struct Vector2
{
	char *		     isa;		           // attributes
	double               x, y;
	Vector2_magnitude    magnitude;                    // methods
	Vector2_distance_to  distance_to;
	Vector2_add          add;
	Vector2_scale        scale;
	Vector2_normalize    normalize;
	Vector2_print        print;
	Vector2_dispose      dispose;                      // deconstructor
};

extern Vector2 new_Vector2( double x, double y );          // constructor
extern Vector2 alloc_Vector2( void );			   // allocator
extern void init_Vector2( Vector2 v, double x, double y ); // initializer

// OO call helpers to add "implicit this object first param"
#define OM0(o,m)      (*((o)->m))(o)
#define OM1(o,m,p)    (*((o)->m))((o),(p))
