/*
   Project: Adun

   Copyright (C) 2005 Michael Johnston & Jordi Villa-Freixa

   Author: Michael Johnston

   This application is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This application is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/

#ifndef VECTORS
#define VECTORS

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <stdio.h>


/**
Basic vector structure for Framework
\ingroup Types
*/

typedef struct 
{
	double length;		//!< The length of the vector
	double vector[3]; 	//!< An array of three double elements
}
Vector3D;

typedef struct 
{
	double length[2];		//!< The length of the two vector
	double vector[6]; 		//!< An array of six double elements (x1, y1, x2, y2 etc);
}
DoubleVector3D;

/**
A structure for integer arrays
\ingroup Types
*/

typedef struct 
{
	int length;		//!< The length of the vector
	int* array; 	//!< An array 
}
IntArrayStruct;

/**
\defgroup Vector Vector
\ingroup Functions
@{
*/

/**
	\param vector_one Pointer to a Vector3D struct
	\param vector_two Pointer to a Vector3D structs
	\return The dot product of the two vectors
**/
inline double Ad3DDotProduct(Vector3D*, Vector3D*);
/**
	Calculates the cross product of two vectors.
	\param v_one Pointer to a Vector3D struct.
	\param v_two Pointer to a Vector3D struct.
	\param result Pointer to a Vector3D struct where the result vector will be stored.
**/
inline void Ad3DCrossProduct(Vector3D*, Vector3D*, Vector3D*);
/**
	Calculates the length of the vector represented by Vector3D.
	struct vector and then assigns the result to vector->length.
	\param vector A pointer to a Vector3D struct.
**/
inline void Ad3DVectorLength(Vector3D*);
/**
	Finds the unit vector related to a given vector.
	\param vector A pointer to a Vector3D struct.
	\param unit_vector Pointer to the Vector3D struct where the unit vector is to be stored. 
**/
inline void AdGet3DUnitVector(Vector3D*, Vector3D*);
/**
In essence generates uniformly distributed points on the unit sphere using \e generator
via the trig-method.
\param vector Pointer to a Vector3D struct in which the result will be placed
\param generator Pointer to a previously allocated gsl_rng instance which will be used
to generate the necessary random numbers.
*/
inline void AdGetRandom3DUnitVector(Vector3D* vector, gsl_rng* generator);
inline void Ad3DVectorLengthSquared(Vector3D*);
/**
	Return the index of the minimium element in a standard double array.
	If there is more than one entry with the same value the smallest
	index is returned
**/
inline int AdDoubleArrayMin(double*, int);
/**
	Return the index of the maximum element in a standard double array.
	If there is more than one entry with the same value the smallest
	index is returned
**/
inline int AdDoubleArrayMax(double*, int);


inline void AdIntArrayIntersectionAndDifference(IntArrayStruct *prime, IntArrayStruct *query, IntArrayStruct *intersection, IntArrayStruct *complement);
inline void AdIntArrayIntersection(IntArrayStruct *prime, IntArrayStruct *query, IntArrayStruct *intersection);
inline void AdIntArrayDifference(IntArrayStruct *prime, IntArrayStruct *query, IntArrayStruct *difference);

/** \@}**/

#endif

