/////////////////////////////////////////////////////////////
// CINEMA 4D SDK                                           //
/////////////////////////////////////////////////////////////
// (c) MAXON Computer GmbH, all rights reserved            //
/////////////////////////////////////////////////////////////

//---------------------------------------------------
//Spline Helper Class :: Header
//Routines to generate a full set of spline matrices
//incorporating a correct normal
//and accurate spline length to realworld length controls
//---------------------------------------------------
#ifndef _C4D_SPLINEHELP_H_
#define _C4D_SPLINEHELP_H_

#include "ge_math.h"
#include "c4d_library.h"

#ifndef __API_INTERN__
#include "c4d_baseobject.h"
#endif

#define C4D_SPLINEHELP_LIBRARY_ID		1019534

class SplineHelp
{
private:
	SplineHelp();
	~SplineHelp();
public:
	// autoalloc
	static SplineHelp *Alloc(void);
	static void				Free(SplineHelp *&node);

	Bool							InitSpline(BaseObject *op, Vector upvector=0.0, BaseObject *rail = NULL, Bool target_rail = TRUE, Bool use_deformed_points = FALSE, Bool force_update = FALSE, Bool use_global_space = TRUE); //must be called before any other command, optional up-vector
	void							FreeSpline(void); //must be called afterwards to free data
	//-----------------------------------------------------
	//helper routines
	Bool							Exists(void);
	LONG							GetSegmentCount(void);
	Real							GetSplineLength(void);
	Real							GetSegmentLength(LONG segment);
	Matrix						GetVertexMatrix(LONG index);
	Real							GetPointValue(Real offset, LONG segment);
	LONG							GetPointIndex(Real offset, LONG segment);
	Vector						GetPosition(Real offset, LONG segment = 0, Bool smooth = TRUE, Bool realoffset = FALSE);
	Vector						GetTangent(Real offset, LONG segment = 0, Bool smooth = TRUE, Bool realoffset = FALSE);
	Vector						GetNormal(Real offset, LONG segment = 0, Bool smooth = TRUE, Bool realoffset = FALSE);
	Vector						GetCrossNormal(Real offset, LONG segment = 0, Bool smooth = TRUE, Bool realoffset = FALSE);
	Real							GetOffsetFromUnit(Real unitoffset, LONG segment = 0);
	Real							GetOffsetFromReal(Real offset, LONG segment = 0);
	Matrix						GetMatrix(Real offset, LONG segment = 0, Bool smooth = TRUE, Bool realoffset = FALSE);
	void							GetLinePointSegment(LONG index, Real *offset, LONG *ind, LONG *segment);
	void							GetSplinePointSegment(LONG index, Real *offset, LONG *ind, LONG *segment);
	void							GlobalToLocal(Real offset, Real *off, LONG *segment, Bool realoffset = FALSE);
	LONG							SplineToLineIndex(LONG index);

	Real							GetSize(Real offset, LONG segment = 0, Bool smooth = TRUE, Bool realoffset = FALSE);
	Real							GetVertexSize(LONG index);
	LONG							GetVertexCount(LONG segment = NOTOK);
	Matrix						GetVertexMatrix(LONG segment, LONG index);

	Bool							IsClosed(LONG segment = 0);
	SPLINETYPE				GetType(void);
	
	Bool							CopyTo(SplineHelp *dest);

	LONG							GetPointCount(void);

	void							SetOwner(BaseObject *op);
};


//---------------------------------------------------
//	---INTERNAL STUFF
class iSplineHelp;

struct SplineHelpLibrary : public C4DLibrary
{
	iSplineHelp*			(*Alloc)();
	void							(*Free)(iSplineHelp *&node);


	Bool							(*InitSplineEx)(iSplineHelp *this_ptr, SplineObject *op, Vector upvector);

	void							(*FreeSpline)(iSplineHelp *this_ptr);
	Bool							(*Exists)(iSplineHelp *this_ptr);
	LONG							(*GetSegmentCount)(iSplineHelp *this_ptr);
	Real							(*GetSplineLength)(iSplineHelp *this_ptr);
	Real							(*GetSegmentLength)(iSplineHelp *this_ptr, LONG segment);
	Real							(*GetPointValue)(iSplineHelp *this_ptr, Real offset, LONG segment);
	LONG							(*GetPointIndex)(iSplineHelp *this_ptr, Real offset, LONG segment);

	Vector						(*GetPositionEx)(iSplineHelp *this_ptr, Real offset, LONG segment, Bool smooth);
	Vector						(*GetTangentEx)(iSplineHelp *this_ptr, Real offset, LONG segment, Bool smooth);
	Vector						(*GetNormalEx)(iSplineHelp *this_ptr, Real offset, LONG segment, Bool smooth);
	Vector						(*GetCrossNormalEx)(iSplineHelp *this_ptr, Real offset, LONG segment, Bool smooth);

	Real							(*GetOffsetFromUnit)(iSplineHelp *this_ptr, Real unitoffset, LONG segment);
	Real							(*GetOffsetFromReal)(iSplineHelp *this_ptr, Real offset, LONG segment);

	Matrix						(*GetMatrix)(iSplineHelp *this_ptr, Real offset, LONG segment, Bool smooth, Bool realoffset);
	void							(*GetLinePointSegment)(iSplineHelp *this_ptr, LONG index, Real *offset, LONG *ind, LONG *segment);
	void							(*GetSplinePointSegment)(iSplineHelp *this_ptr, LONG index, Real *offset, LONG *ind, LONG *segment);
	void							(*GlobalToLocal)(iSplineHelp *this_ptr, Real offset, Real *off, LONG *segment, Bool realoffset);
	Matrix						(*GetVertexMatrix)(iSplineHelp *this_ptr, LONG index);
	LONG							(*SplineToLineIndex)(iSplineHelp *this_ptr, LONG index);

	//MoGraph 2 Updates
	Bool							(*InitSpline)(iSplineHelp *this_ptr, BaseObject *op, Vector upvector, BaseObject *rail, Bool target_rail, Bool use_deformed_points, Bool force_update, Bool use_global_space);
	Vector						(*GetPosition)(iSplineHelp *this_ptr, Real offset, LONG segment, Bool smooth, Bool realoffset);
	Vector						(*GetTangent)(iSplineHelp *this_ptr, Real offset, LONG segment, Bool smooth, Bool realoffset);
	Vector						(*GetNormal)(iSplineHelp *this_ptr, Real offset, LONG segment, Bool smooth, Bool realoffset);
	Vector						(*GetCrossNormal)(iSplineHelp *this_ptr, Real offset, LONG segment, Bool smooth, Bool realoffset);
	Real							(*GetSize)(iSplineHelp *this_ptr, Real offset, LONG segment, Bool smooth, Bool realoffset);
	Real							(*GetVertexSize)(iSplineHelp *this_ptr, LONG index);
	LONG							(*GetVertexCount)(iSplineHelp *this_ptr, LONG segment);
	Matrix						(*GetVertexMatrix2)(iSplineHelp *this_ptr, LONG segment, LONG index);
	Bool							(*IsClosed)(iSplineHelp *this_ptr, LONG segment);
	SPLINETYPE				(*GetType)(iSplineHelp *this_ptr);
	Bool							(*CopyTo)(iSplineHelp *this_ptr, iSplineHelp *dest);

	LONG							(*GetPointCount)(iSplineHelp *this_ptr);
	void							(*SetOwner)(iSplineHelp *this_ptr, BaseObject *op);
};

#ifdef __API_INTERN__
#include "lib_splinehelp.cpp"
#endif

//	---INTERNAL STUFF
//---------------------------------------------------


#endif
 
 