#ifndef _TPFVEC_H
#define _TPFVEC_H

#include "f1616.h"
#include "ang.h"

/* Contains code to manipulate a 3D vector of f1616's
   Each whole unit corresponds to one map block */

/* Vector structure
   Manipulating .x, .y and .z manually is OK */
typedef struct {
	f1616 x,y,z;
} tpfVec;

#ifdef __cplusplus
extern "C" {
#endif

/* Create a new vector */
extern tpfVec *TpfVec_New();

/* Delete a vector */
extern void TpfVec_Delete(tpfVec *v);

/* Add one vector to another: a=a+b */
extern void TpfVec_Add(tpfVec *a,tpfVec *b);

/* Subtract one vector from another: a=a-b */
extern void TpfVec_Sub(tpfVec *a,tpfVec *b);

/* Negate a vectore: a.x=-a.x, a.y=-a.y, a.z=-a.z */
extern void TpfVec_Neg(tpfVec *a);

/* Multiply one vector by another: a.x=a.x*b.x a.y=a.y*b.y, a.z=a.z*b.z */
extern void TpfVec_Mul(tpfVec *a,tpfVec *b);

/* Divide one vector by another: a.x=a.x/b.x a.y=a.y/b.y a.z=a.z/b.z */
extern void TpfVec_Div(tpfVec *a,tpfVec *b);

/* Multiply one vector by an f1616: a.x=a.x*b, a.y=a.y*b, a.z=a.z*b */
extern void TpfVec_Mul2(tpfVec *a,f1616 b);

/* Divide one vector by an f1616: a.x=a.x/b, a.y=a.y/b, a.z=a.z/b */
extern void TpfVec_Div2(tpfVec *a,f1616 b);

/* Divide an f1616 by a vector: b.x=a/b.x, b.y=a/b.y, b.z=a/b.z */
extern void TpfVec_Div3(f1616 a,tpfVec *b);

/* Return the length of a vector */
extern f1616 TpfVec_Len(tpfVec *v);

/* Scale the vector so it's length is 1 */
extern void TpfVec_Normalize(tpfVec *v);

/* Return the dot product of both vectors */
extern f1616 TpfVec_DotProd(tpfVec *a,tpfVec *b);

/* Set c to the cross product of a and b */
extern void TpfVec_CrossProd(tpfVec *a,tpfVec *b,tpfVec *c);

/* 'move' vector p to x location tx by adding on some multiple of d
   recdx should be 1/d.x
   Returns the distance moved (i.e. multiple of d used) */ 
extern f1616 TpfVec_MoveToX(tpfVec *p,tpfVec *d,f1616 tx,f1616 recdx);

/* 'move' vector p to y location ty by adding on some multiple of d
   recdy should be 1/d.y
   Returns the distance moved (i.e. multiple of d used) */ 
extern f1616 TpfVec_MoveToY(tpfVec *p,tpfVec *d,f1616 ty,f1616 recdy);

/* 'move' vector p to z location tz by adding on some multiple of d
   recdz should be 1/d.z
   Returns the distance moved (i.e. multiple of d used) */ 
extern f1616 TpfVec_MoveToZ(tpfVec *p,tpfVec *d,f1616 tz,f1616 recdz);

/* Rotate v about the z axis by the angle a */
extern void TpfVec_Rotate(tpfVec *v,tpfAng a);

#ifdef __cplusplus
}
#endif

#endif
