// This is a part of the Object Oriented Mathematical Library
// Copyright (C) 1999-2008 Renishaw plc
//
// This source file is the confidential property of Renishaw plc.
// Reproduction or transmission in whole or in part, in any form or
// by any means, electronic, mechanical or otherwise, is prohibited
// without the prior written consent of the copyright owner.
//
// objarray.h -- variable-Size arrays


#ifndef __OBJARRAY_H__
#define __OBJARRAY_H__


#include "OOMathsExport.h"
//=========================================================================================================================
#define MA_ARRAY_EXPAND_SIZE	10			// Bug ID : 9131

//=========================================================================================================================
// CMaIntArray - math library array of integer numbers (concrete class)
//=========================================================================================================================

class OOMATHS_API CMaIntArray
{
public:
	// constructors
	CMaIntArray(int nInitSize, int nArrayExpandSize);				// Size >= 0 nArrayExpandSize >= 1
	CMaIntArray(int nInitSize = 0);								// Size >= 0 
	CMaIntArray(const CMaIntArray& src);						// copy

	// destructor
	~CMaIntArray();

	// attributes
	int  GetSize() const;                  // get array Size
	int GetCapacity() const;				   // Get Maximum size of the array

	// Set Capacity can be used to deallocate all memory or to increase the size of the array.
	// Truncation is not allowed using SetCapacity
	void SetCapacity(int nNewSize);
	void SetSize(int nNewSize);					// Wrapper method for SetCapacity 
	  

	int  GetExpandSize() const;                  // get Expand array Size
	void SetExpandSize(int nNewXSize);             // set or change array Expand Size

	// operations
	// assignment and accessing elements
	CMaIntArray& operator=(const CMaIntArray& src);
	int  operator[](int nIndex) const;
	int& operator[](int nIndex);
	int First() const;
	int Last() const;

	// direct access to data: return C array, may be NULL
	const int* GetData() const;
	int* GetData();

	// access to subset
	CMaIntArray SubArray(int i, int j) const;
	// note:
	//    return an array with elements [i]..[j], i <= j

	// expanding the array
	void Add(int nElement);
	void Append(const CMaIntArray& src);

	// shrinking the array
	void Remove(int nIndex);
	void FreeExtra();			// Used to shrink the array to its size.
	void Truncate(int Size);	// This reduces the array size and deletes all the contents
								// of the array greater than the size.

	// Clearing the contents of the array
	void Clear();

	// searching
	int Find(int nElement) const;   // return -1 if not found and index otherwise

	// comparison
	EMaBoolean IsEqual(const CMaIntArray& other) const;

	// ordering
	void Sort();                   // in ascending order
	void Sort(CMaIntArray* indexTable) const;

	// arithmetic
	int Sum() const;

private:
	// implementation
	void Copy(const CMaIntArray& src);

	int* m_pData;			// the actual array of data
	int  m_nSize;			// number of elements (index: 0..Size-1)
	int  m_nMaxSize;			// max number of elements allocated
	int	m_nArrayExpandSize; // Array Expand Size
};

//=========================================================================================================================
// CMaDoubleArray - math library array of double numbers (concrete class)
//=========================================================================================================================

class OOMATHS_API CMaDoubleArray
{
public:
	// constructors
	CMaDoubleArray(int nInitSize, int nArrayExpandSize);	// Size >= 0 and nArrayExpandSize >=1
	CMaDoubleArray(int nInitSize = 0);					// Size >= 0
	CMaDoubleArray(const CMaDoubleArray& src);		// copy

	// destructor
	~CMaDoubleArray();

	// attributes
	int  GetSize() const;							// get array Size
	// Set Capacity can be used to deallocate all memory or to increase the size of the array.
	// Truncation is not allowed using SetCapacity
	void SetCapacity(int nNewSize);
	void SetSize(int nNewSize);						// Wrapper method for SetCapacity 
	int GetCapacity() const;						// Get Maximum size of the array	

	int  GetExpandSize() const;						// get Expand array Size
	void SetExpandSize(int nNewXSize);				// set or change array Expand Size

	// operations
	// assignment and accessing elements
	CMaDoubleArray& operator=(const CMaDoubleArray& src);
	double  operator[](int nIndex) const;
	double& operator[](int nIndex);
	double First() const;
	double Last() const;

	// direct access to data: return C array, may be NULL
	const double* GetData() const;
	double* GetData();

	// access to subset
	CMaDoubleArray SubArray(int i, int j) const;
	// note:
	//    return an array with elements [i]..[j], i <= j

	CMaDoubleArray SubArray(const CMaIntArray& ip) const;
	// note:
	//    this and ip have the same Size
	//    elements of ip is 0 or 1

	// expanding the array
	void Add(double Element);
	void Append(const CMaDoubleArray& src);

	// shrinking the array
	void Remove(int nIndex);
	void FreeExtra();			// Used to shrink the array to its size.
	void Truncate(int nSize);	// This reduces the array size and deletes all the contents
								// of the array greater than the size.

	// Clearing the contents of the array
	void Clear();

	// conversion
	CMaVector ToVector() const;

	// searching
	int Find(double Element, double tolerance = MaGetTol()) const;   // return -1 if not found and index otherwise
	double Max() const;
	double Min() const;

	// comparison
	EMaBoolean IsEqual(const CMaDoubleArray& other, double tolerance = MaGetTol()) const;
	EMaBoolean IsMonotonicIncreasing() const;   // Ai <= Ai+1 for all i
	EMaBoolean IsStrictlyIncreasing() const;    // Ai < Ai+1 for all i

	// ordering
	void Sort();								// in ascending order
	void Sort(CMaIntArray* indexTable) const;

	// arithmetic
	double Sum() const;

private:
	// implementation
	void Copy(const CMaDoubleArray& src);

	double* m_pData;							// the actual array of data
	int     m_nSize;							// number of elements (index: 0..Size-1)
	int     m_nMaxSize;							// max number of elements allocated
	int		m_nArrayExpandSize;					// Array Expand Size
};

//=========================================================================================================================
// CMaComplexArray - math library array of complex numbers (concrete class)
//=========================================================================================================================

class OOMATHS_API CMaComplexArray
{
public:
	// constructors
	CMaComplexArray(int nInitSize, int nArrayExpandSize);	// Size >= 0 and nArrayExpandSize >=1
	CMaComplexArray(int nInitSize = 0);						// Size >= 0
	CMaComplexArray(const CMaComplexArray& src);		// copy

	// destructor
	~CMaComplexArray();

	// attributes
	int  GetSize() const;								// get array Size
	// Set Capacity can be used to deallocate all memory or to increase the size of the array.
	// Truncation is not allowed using SetCapacity
	void SetCapacity(int nNewSize);
	void SetSize(int nNewSize);							// Wrapper method for SetCapacity 
	int GetCapacity() const;							// Get Maximum size of the array

	int  GetExpandSize() const;							// get Expand array Size
	void SetExpandSize(int nNewXSize);					// set or change array Expand Size

	// operations
	// assignment and accessing elements
	CMaComplexArray& operator=(const CMaComplexArray& src);
	CMaComplex  operator[](int nIndex) const;
	CMaComplex& operator[](int nIndex);
	CMaComplex First() const;
	CMaComplex Last() const;

	// direct access to data: return C array, may be NULL
	const CMaComplex* GetData() const;
	CMaComplex* GetData();

	// access to subset
	CMaComplexArray SubArray(int i, int j) const;
	// note:
	//    return an array with elements [i]..[j], i <= j

	// expanding the array
	void Add(const CMaComplex& Element);
	void Append(const CMaComplexArray& src);

	// shrinking the array
	void Remove(int nIndex);
	void FreeExtra();			// Used to shrink the array to its size.
	void Truncate(int nSize);	// This reduces the array size and deletes all the contents
								// of the array greater than the size.
	// Clearing the contents of the array
	void Clear();

private:
	// implementation
	void Copy(const CMaComplexArray& src);

	CMaComplex* m_pData;			// the actual array of data
	int         m_nSize;			// number of elements (index: 0..Size-1)
	int         m_nMaxSize;			// max number of elements allocated
	int			m_nArrayExpandSize;	// Array Expand Size
};

//=========================================================================================================================
// CMaComplexPolarArray - math library array of polar complex numbers (concrete class)
//=========================================================================================================================

class OOMATHS_API CMaComplexPolarArray
{
public:
	// constructors
	CMaComplexPolarArray(int nInitSize, int nArrayExpandSize);	// Size >= 0 and nArrayExpandSize >=1
	CMaComplexPolarArray(int nInitSize = 0);                     // Size >= 0
	CMaComplexPolarArray(const CMaComplexPolarArray& src);  // copy

	// destructor
	~CMaComplexPolarArray();

	// attributes
	int  GetSize() const;									// get array Size
	
	// Set Capacity can be used to deallocate all memory or to increase the size of the array.
	// Truncation is not allowed using SetCapacity
	void SetCapacity(int nNewSize);
	void SetSize(int nNewSize);								// Wrapper method for SetCapacity 

	int GetCapacity() const;								// Get Maximum size of the array

	int  GetExpandSize() const;								// get Expand array Size
	void SetExpandSize(int nNewXSize);						// set or change array Expand Size

	// operations
	// assignment and accessing elements
	CMaComplexPolarArray& operator=(const CMaComplexPolarArray& src);
	CMaComplexPolar  operator[](int nIndex) const;
	CMaComplexPolar& operator[](int nIndex);
	CMaComplexPolar First() const;
	CMaComplexPolar Last() const;

	// direct access to data: return C array, may be NULL
	const CMaComplexPolar* GetData() const;
	CMaComplexPolar* GetData();

	// access to subset
	CMaComplexPolarArray SubArray(int i, int j) const;
	// note:
	//    return an array with elements [i]..[j], i <= j

	// expanding the array
	void Add(const CMaComplexPolar& Element);
	void Append(const CMaComplexPolarArray& src);

	// shrinking the array
	void Remove(int nIndex);
	void FreeExtra();			// Used to shrink the array to its size.
	void Truncate(int nSize);	// This reduces the array size and deletes all the contents
								// of the array greater than the size.

	// Clearing the contents of the array
	void Clear();

private:
	// implementation
	void Copy(const CMaComplexPolarArray& src);

	CMaComplexPolar* m_pData;			// the actual array of data
	int				m_nSize;			// number of elements (index: 0..Size-1)
	int				m_nMaxSize;			// max number of elements allocated
	int				m_nArrayExpandSize;	// Array Expand Size
};

//=========================================================================================================================
// CMaObjArray - math library array of object-pointers (concrete class)
//=========================================================================================================================

class OOMATHS_API CMaObjArray
{
public:
	// constructors
	CMaObjArray(int nInitSize, int nArrayExpandSize);			// nInitSize >= 0 and nArrayExpandSize >=1
	CMaObjArray(int nInitSize = 0);								// nInitSize >= 0
	CMaObjArray(const CMaObjArray& src);					// copy

	// destructor
	~CMaObjArray();

	// attributes
	int  GetSize() const;									// get array Size
	// Set Capacity can be used to deallocate all memory or to increase the size of the array.
	// Truncation is not allowed using SetCapacity
	void SetCapacity(int nNewSize);
	void SetSize(int nNewSize);								// Wrapper method for SetCapacity 

	int GetCapacity() const;								// Get Maximum size of the array

	int  GetExpandSize() const;								// get Expand array Size
	void SetExpandSize(int nNewXSize);						// set or change array Expand Size

	// operations
	// assignment and accessing elements
	CMaObjArray& operator=(const CMaObjArray& src);
	CMaObject*  operator[](int nIndex) const;
	CMaObject*& operator[](int nIndex);
	CMaObject* First() const;
	CMaObject* Last() const;

	// direct access to data: return C array, may be NULL
	const CMaObject** GetData() const;
	CMaObject** GetData();

	// expanding the array
	void Add(CMaObject* Element);
	void Append(const CMaObjArray& src);

	// shrinking the array
	void FreeExtra();			// Used to shrink the array to its size.
	void Truncate(int nSize);	// This reduces the array size and deletes all the contents
								// of the array greater than the size.

	// Clearing the contents of the array
	void Clear();

private:
	// implementation
	void Copy(const CMaObjArray& src);

	CMaObject** m_pData;			// the actual array of data
	int			m_nSize;			// number of elements (index: 0..Size-1)
	int			m_nMaxSize;			// max number of elements allocated
	int			m_nArrayExpandSize;	// Array Expand Size
};

//=========================================================================================================================
// CMaPointArray - math library array of points (concrete class)
//=========================================================================================================================

class OOMATHS_API CMaPointArray
{
public:
	// constructors
	CMaPointArray(int nInitSize, int nArrayExpandSize);		// Size >= 0 and nArrayExpandSize >=1
	CMaPointArray(int nInitSize = 0);						// Size >= 0
	CMaPointArray(const CMaPointArray& src);			// copy

	// destructor
	~CMaPointArray();

	// attributes
	int  GetSize() const;								// get array Size

	// Set Capacity can be used to deallocate all memory or to increase the size of the array.
	// Truncation is not allowed using SetCapacity
	void SetCapacity(int nNewSize);
	void SetSize(int nNewSize);							// Wrapper method for SetCapacity 

	int GetCapacity() const;							// Get Maximum size of the array

	int  GetExpandSize() const;							// get Expand array Size
	void SetExpandSize(int nNewXSize);					// set or change array Expand Size

	// operations
	// assignment and accessing elements
	CMaPointArray& operator=(const CMaPointArray& src);
	CMaPoint  operator[](int nIndex) const;
	CMaPoint& operator[](int nIndex);
	CMaPoint First() const;
	CMaPoint Last() const;

	// direct access to data: return C array, may be NULL
	const CMaPoint* GetData() const;
	CMaPoint* GetData();

	// access to coordinate data
	CMaDoubleArray GetDataX() const;
	CMaDoubleArray GetDataY() const;
	CMaDoubleArray GetDataZ() const;

	// access to subset
	CMaPointArray SubArray(int i, int j) const;
	// note:
	//    return an array with elements [i]..[j], i <= j

	CMaPointArray SubArray(const CMaIntArray& ip) const;
	// note:
	//    this and ip have the same Size
	//    elements of ip is 0 or 1

	// expanding the array
	void Add(const CMaPoint& Element);
	void Append(const CMaPointArray& src);

	// shrinking the array
	void FreeExtra();			// Used to shrink the array to its size.
	void Truncate(int nSize);	// This reduces the array size and deletes all the contents
								// of the array greater than the size.
	void Remove(int nIndex);
	void RemoveDuplicate(double tolerance = MaGetLengthTol());
	void RemoveAdjacentDuplicate(double tolerance = MaGetLengthTol());

	// Clearing the contents of the array
	void Clear();

	// searching
	EMaBoolean IsIn(const CMaPoint& Element, double tolerance = MaGetLengthTol()) const;
	EMaBoolean IsNoncollinear(CMaIntArray* ip, double tolerance = MaGetLengthTol()) const;
	EMaBoolean IsNoncoplanar(CMaIntArray* ip, double tolerance = MaGetLengthTol()) const;
	// note:
	//    The array of points is non-collinear if there are three points are found
	//    to be non-collinear; non-coplanar if four points are non-coplanar.
	//    ip: hold the indices of these points

	// comparison
	EMaBoolean Is2D() const;
	EMaBoolean IsEqual(const CMaPointArray& other, double tolerance = MaGetTol()) const;
	// note: on comparison of two array of points
	//    the ordering of points is not relevant

	// centroid of data
	CMaPoint MeanPoint() const;

	// transformation to a new coordinate system
	void MoveTo(const CMaPoint& origin);
	void MoveTo(const CMaVector& zaxis);
	void MoveTo(const CMaPoint& origin, const CMaVector& zaxis);
	void MoveTo(const CMaPoint& origin, const CMaVector& xaxis, const CMaVector& zaxis);

	// length calculation
	double MaxEdge(int* i, int* j) const;
	double MinEdge(int* i, int* j) const;

	// bounding data
	void BoundingBox(CMaPoint* pMin, CMaPoint* pMax) const;
	void BoundingSphere(double* radius, CMaPoint* centre) const;

	void ConvexHull(CMaIntArray* ip) const;
	// note:
	//    1. if this is a 2D point array
	//       ip: hold the indices of convex polygon points in a counter-clockwise order
	//    2. if this is a 3D point array
	//       ip: hold the indices of convex polyhedron points (not implemented)

private:
	// implementation
	void Copy(const CMaPointArray& src);

	CMaPoint*	m_pData;			// the actual array of data
	int			m_nSize;			// number of elements (index: 0..Size-1)
	int			m_nMaxSize;			// max number of elements allocated
	int			m_nArrayExpandSize;	// Array Expand Size
};

//=========================================================================================================================
#endif // __OBJARRAY_H__
