/////////////////////////////////////////////////////////////
// IGES 4D    : GENERIC CURVE AND SURFACES LIBRARY         //
/////////////////////////////////////////////////////////////
// VERSION    : CINEMA 4D                                  //
/////////////////////////////////////////////////////////////
// (c) 2003-2004 MAXON Computer GmbH, Stefan Bauer         //
/////////////////////////////////////////////////////////////

#ifndef __DWGO_H
#define __DWGO_H

#include "c4d.h"
#include "lib_dwgobjectsdef.h"

#ifndef _INTERNAL_USE_ONLY_

class xBaseCurveData;

class xBaseCurveClass
{
		xBaseCurveClass();
		~xBaseCurveClass();
	public:
		xBaseCurveData *AllocCurve(LONG type);

		Bool Update(GeListNode *node);

		LONG GetSubDivision();
		void SetSubDivision(LONG subdiv);

		void SetOutput(LONG output);
};

class xBaseGeometryData
{
		xBaseGeometryData() { }
		~xBaseGeometryData() {}
	public:
		void Initialize(GeListNode *node);
};

class xBaseCurveData : public xBaseGeometryData
{
		xBaseCurveData();
		~xBaseCurveData();
	public:
		void SetPlanar(Bool planar);
};

class xLineCurveData : public xBaseCurveClass
{
		xLineCurveData();
		~xLineCurveData();
	public:
		void SetStartPoint(const Vector &v);
		void SetEndPoint(const Vector &v);
		void SetLimit(Real v);
		void SetLineType(LineCurveTypeEnum type);
};

class xCircularCurveData : public xBaseCurveData
{
		xCircularCurveData();
		~xCircularCurveData();
	public:
		void SetCenter(Real x, Real y);
		void SetZValue(Real z);
		void SetStartPoint(Real x, Real y);
		void SetEndPoint(Real x, Real y);
		void SetIsClockWise(Bool value);

		Real GetParameterMax(GeListNode *node=NULL);
		Real GetParameterMin(GeListNode *node=NULL);
};

class xConicCurveData : public xBaseCurveData
{
		xConicCurveData();
		~xConicCurveData();
	public:
		void SetZValue(Real z);
		void SetStartPoint(Real x, Real y);
		void SetEndPoint(Real x, Real y);
		void SetCoefficients(const ConicCurveCoeffcients &coeff);
		void SetCoefficients(Real a, Real b, Real c, Real d, Real e, Real f);
};

class xNurbsKnots
{
		xNurbsKnots();
		~xNurbsKnots();
	public:
		
		void SetPeriodic(Bool state);
		void Set(LONG i, Real value);
		Real GetMinValue(void);
		Real GetMaxValue(void);
		Real Get(LONG i);
};

class xBaseCurvePoint
{
		xBaseCurvePoint();
		~xBaseCurvePoint();
	public:
		void SetPosition(const Vector &vector);	
		const Vector &GetPosition();
};

class xNurbsCurvePoint : public xBaseCurvePoint
{
		xNurbsCurvePoint();
		~xNurbsCurvePoint();
	public:
		void SetWeight(Real w);
		Real GetWeight();
};

class xNurbsCurveData : public xBaseCurveData
{
		xNurbsCurveData();
		~xNurbsCurveData();
	public:
		Bool ResizeObject(LONG count, LONG degree);
		void SetClosed(Bool value);
		void SetPoint(LONG index, const Vector& position, const Real& weight);
		xNurbsKnots *GetKnots();
		void SetParameterRange(Real min, Real max);
		void SetPolynomial(Bool value);
		xNurbsCurvePoint* GetPoint(LONG index);
};

class xCompositeCurveData : public xBaseCurveData
{
		xCompositeCurveData();
		~xCompositeCurveData();
	public:
};

class xBaseSurfaceData;

class xBaseSurfaceClass : public ObjectData
{
		xBaseSurfaceClass();
		~xBaseSurfaceClass();
	public:
		xBaseSurfaceData *AllocSurface(LONG type);

		Bool Update(GeListNode *node);
		
		void SetSubU(LONG subu);
		void SetSubV(LONG subv);
		void SetOutput(LONG output);
		void SetNormalsActive(Bool normals_active);
		void SetNormalsSwap(Bool normals_swap);
};

class xBaseSurfaceData : public xBaseGeometryData
{
		xBaseSurfaceData();
		~xBaseSurfaceData();
	public:
};

class xExtrudeSurfaceData : public xBaseSurfaceData
{
		xExtrudeSurfaceData();
		~xExtrudeSurfaceData();
		
	public:
		void SetDirection(const Vector &v);
};

class xPlaneSurfaceData : public xBaseSurfaceData
{
		xPlaneSurfaceData();
		~xPlaneSurfaceData();
	public:
		void SetCoefficients(Real a, Real b, Real c, Real d);
		void SetDisplayPosition(const Vector &v);
		void SetDisplaySize(Real s);
		void SetLimit(Real v);
		void SetPlaneType(PlaneSurfaceTypeEnum type);
};

class xPolynomCurvePoint : public xBaseCurvePoint
{
		xPolynomCurvePoint();
		~xPolynomCurvePoint();
	public:
		void SetCoeff(LONG number, const Vector &vector);
};

class xPolynomCurveData : public xBaseCurveData
{
		xPolynomCurveData();
		~xPolynomCurveData();
	public:
		Bool ResizeObject(LONG count, LONG degree);
		Real* GetBreakPoint(LONG index);
		xPolynomCurvePoint* GetPoint(LONG index);
		LONG GetPointCount(GeListNode *node=NULL);
		void InitClosed();
};

class xPolynomSurfacePoint : public xPolynomCurvePoint
{
		xPolynomSurfacePoint();
		~xPolynomSurfacePoint();
	public:
		void SetUVCoeff(LONG uindex, LONG vindex, const Vector &vector);
};

class xPolynomSurfaceData : public xBaseSurfaceData
{
		xPolynomSurfaceData();
		~xPolynomSurfaceData();
	public:
		Bool ResizeObject(LONG ucount, LONG vcount, LONG udegree, LONG vdegree);
		Real* GetUBreakPoint(LONG index);
		Real* GetVBreakPoint(LONG index);
		xPolynomSurfacePoint* GetPoint(LONG uindex, LONG vindex);
		LONG GetPointCount(GeListNode *node=NULL);
		void InitClosed();
};

class xRotateSurfaceData : public xBaseSurfaceData
{
		xRotateSurfaceData();
		~xRotateSurfaceData();
	public:
		void SetStartAngle(Real angle);
		void SetEndAngle(Real angle);
		void SetInvert(Bool state);
};

class xUVPairFF
{
		xUVPairFF();
		~xUVPairFF();
	public:
		void SetPeriodicU(Bool u);
		void SetPeriodicV(Bool v);
		void SetU(LONG idx, Real u);
		void SetV(LONG idx, Real v);
		Real GetU(LONG idx);
		Real GetV(LONG idx);
};

class xNurbsSurfaceData : public xBaseSurfaceData
{
		xNurbsSurfaceData();
		~xNurbsSurfaceData();
	public:
		xUVPairFF* GetKnots();
		void SetPolynomial(Bool p);
		void SetUClosed(Bool c);
		void SetVClosed(Bool c);
		Bool ResizeObject(LONG ucount, LONG vcount, LONG udegree, LONG vdegree);
		void SetUParameterRange(Real min, Real max);
		void SetVParameterRange(Real min, Real max);
		LONG GetUPointCount(GeListNode *node=NULL);
		LONG GetVPointCount(GeListNode *node=NULL);
		xNurbsCurvePoint* GetPoint(LONG uindex, LONG vindex);
};

class xMappedCurveData;

class xMappedCurveClass : public ObjectData
{
		xMappedCurveClass();
		~xMappedCurveClass();
	public:
		xMappedCurveData *AllocMapped(LONG type);
		Bool Update(GeListNode *node);
};

class xMappedCurveData : public xBaseGeometryData
{
		xMappedCurveData();
		~xMappedCurveData();
	public:

};

class xStandardMappedCurveData : public xMappedCurveData
{
		xStandardMappedCurveData();
		~xStandardMappedCurveData();
	public:
		void SetSegmented(Bool value);
};

class xSegmentMappedCurveData : public xMappedCurveData
{
		xSegmentMappedCurveData();
		~xSegmentMappedCurveData();
	public:
		void SetReversed(Bool value);
};

class xTrimmedSurfaceData;

class xTrimmedSurfaceClass : public ObjectData
{
		xTrimmedSurfaceClass();
		~xTrimmedSurfaceClass();
	public:
		xTrimmedSurfaceData *AllocTrimmed(LONG type);
		void SetPrecision(Real precision);
		Bool Update(GeListNode *node);
};

class xTrimmedSurfaceData : public xBaseGeometryData
{
		xTrimmedSurfaceData();
		~xTrimmedSurfaceData();
	public:
};

class xStandardTrimmedSurfaceData : public xTrimmedSurfaceData
{
		xStandardTrimmedSurfaceData();
		~xStandardTrimmedSurfaceData();
	public:
		void SetFirstOuter(Bool value);
};

#else
	#define xBaseCurveClass								BaseCurveClass
	#define xBaseGeometryData							BaseGeometryData
	#define xBaseCurveData								BaseCurveData 
	#define xLineCurveData								LineCurveData 
	#define xCircularCurveData						CircularCurveData
	#define xConicCurveData								ConicCurveData 
	#define xNurbsKnots										NurbsKnots
	#define xNurbsCurveData								NurbsCurveData 
	#define xCompositeCurveData						CompositeCurveData
	#define xBaseSurfaceClass							BaseSurfaceClass
	#define xBaseSurfaceData							BaseSurfaceData
	#define xExtrudeSurfaceData						ExtrudeSurfaceData
	#define xBaseCurvePoint								BaseCurvePoint
	#define xNurbsCurvePoint							NurbsCurvePoint
	#define xPlaneSurfaceData							PlaneSurfaceData
	#define xPolynomCurvePoint						PolynomCurvePoint
	#define xPolynomCurveData							PolynomCurveData
	#define xPolynomSurfacePoint					PolynomSurfacePoint
	#define xPolynomSurfaceData						PolynomSurfaceData
	#define xRotateSurfaceData						RotateSurfaceData
	#define xUVPairFF											UVPairFF
	#define xNurbsSurfaceData							NurbsSurfaceData
	#define xMappedCurveClass							MappedCurveClass
	#define xMappedCurveData							MappedCurveData
	#define xStandardMappedCurveData			StandardMappedCurveData
	#define xSegmentMappedCurveData				SegmentMappedCurveData
	#define xTrimmedSurfaceClass					TrimmedSurfaceClass
	#define xTrimmedSurfaceData						TrimmedSurfaceData
	#define xStandardTrimmedSurfaceData		StandardTrimmedSurfaceData
#endif

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

#define DWGOBJECTS_LIB 200000212

struct DWGObjectsLib : public C4DLibrary
{
	Bool									(*Update)(xBaseCurveClass *this_ptr, GeListNode *node);
	xBaseCurveData* 			(*AllocCurve)(xBaseCurveClass *this_ptr, LONG type);
	LONG									(*GetSubDivision)(xBaseCurveClass *this_ptr);
	void									(*SetSubDivision)(xBaseCurveClass *this_ptr, LONG subdiv);
	void									(*SetOutput)(xBaseCurveClass *this_ptr, LONG output);

	void									(*SetPlanar)(xBaseCurveData *this_ptr, Bool planar);

	void									(*Initialize)(xBaseGeometryData *this_ptr, GeListNode *node);

	void									(*SetStartPoint)(xLineCurveData *this_ptr, const Vector &v);
	void									(*SetEndPoint)(xLineCurveData *this_ptr, const Vector &v);
	void									(*SetLimit)(xLineCurveData *this_ptr, Real v);
	void									(*SetLineType)(xLineCurveData *this_ptr, LineCurveTypeEnum type);

	void									(*SetCenter)(xCircularCurveData *this_ptr, Real x, Real y);
	void									(*SetZValue)(xCircularCurveData *this_ptr, Real z);
	void									(*SetStartPoint2)(xCircularCurveData *this_ptr, Real x, Real y);
	void									(*SetEndPoint2)(xCircularCurveData *this_ptr, Real x, Real y);
	void									(*SetIsClockWise)(xCircularCurveData *this_ptr, Bool value);
	Real									(*GetParameterMax)(xCircularCurveData *this_ptr, GeListNode *node);
	Real									(*GetParameterMin)(xCircularCurveData *this_ptr, GeListNode *node);

	void									(*SetZValue2)(xConicCurveData *this_ptr, Real z);
	void									(*SetStartPoint3)(xConicCurveData *this_ptr, Real x, Real y);
	void									(*SetEndPoint3)(xConicCurveData *this_ptr, Real x, Real y);
	void									(*SetCoefficients1)(xConicCurveData *this_ptr, const ConicCurveCoeffcients &coeff);
	void									(*SetCoefficients2)(xConicCurveData *this_ptr, Real a, Real b, Real c, Real d, Real e, Real f);
	
	void									(*SetPeriodic)(xNurbsKnots *this_ptr, Bool state);
	void									(*Set)(xNurbsKnots *this_ptr, LONG i, Real value);
	Real									(*GetMinValue)(xNurbsKnots *this_ptr);
	Real									(*GetMaxValue)(xNurbsKnots *this_ptr);
	Real									(*Get)(xNurbsKnots *this_ptr, LONG i);

	void									(*SetPosition)(xBaseCurvePoint *this_ptr, const Vector &vector);	
	const Vector &				(*GetPosition)(xBaseCurvePoint *this_ptr);

	void									(*SetWeight)(xNurbsCurvePoint *this_ptr, Real w);
	Real									(*GetWeight)(xNurbsCurvePoint *this_ptr);

	Bool									(*ResizeObject4)(xNurbsCurveData *this_ptr, LONG count, LONG degree);
	void									(*SetClosed)(xNurbsCurveData *this_ptr, Bool value);
	void									(*SetPoint)(xNurbsCurveData *this_ptr, LONG index, const Vector& position, const Real& weight);
	xNurbsKnots*					(*GetKnots2)(xNurbsCurveData *this_ptr);
	void									(*SetParameterRange)(xNurbsCurveData *this_ptr, Real min, Real max);
	void									(*SetPolynomial3)(xNurbsCurveData *this_ptr, Bool value);
	xNurbsCurvePoint* 		(*GetPoint)(xNurbsCurveData *this_ptr, LONG index);

	xBaseSurfaceData*			(*AllocSurface)(xBaseSurfaceClass *this_ptr, LONG type);
	Bool									(*Update2)(xBaseSurfaceClass *this_ptr, GeListNode *node);
	void									(*SetSubU)(xBaseSurfaceClass *this_ptr, LONG subu);
	void									(*SetSubV)(xBaseSurfaceClass *this_ptr, LONG subv);
	void 									(*SetOutput2)(xBaseSurfaceClass *this_ptr, LONG output);
	void									(*SetNormalsActive)(xBaseSurfaceClass *this_ptr, Bool normals_active);
	void									(*SetNormalsSwap)(xBaseSurfaceClass *this_ptr, Bool normals_swap);

	void									(*SetDirection)(xExtrudeSurfaceData *this_ptr, const Vector &v);

	void									(*SetCoefficients)(xPlaneSurfaceData *this_ptr, Real a, Real b, Real c, Real d);
	void									(*SetDisplayPosition)(xPlaneSurfaceData *this_ptr, const Vector &v);
	void									(*SetDisplaySize)(xPlaneSurfaceData *this_ptr, Real s);
	void									(*SetLimit2)(xPlaneSurfaceData *this_ptr, Real v);
	void 									(*SetPlaneType)(xPlaneSurfaceData *this_ptr, PlaneSurfaceTypeEnum type);

	void									(*SetCoeff)(xPolynomCurvePoint *this_ptr, LONG number, const Vector &vector);

	Bool									(*ResizeObject2)(xPolynomCurveData *this_ptr, LONG count, LONG degree);
	Real*									(*GetBreakPoint)(xPolynomCurveData *this_ptr, LONG index);
	xPolynomCurvePoint*		(*GetPoint2)(xPolynomCurveData *this_ptr, LONG index);
	LONG									(*GetPointCount2)(xPolynomCurveData *this_ptr, GeListNode *node);
	void									(*InitClosed)(xPolynomCurveData *this_ptr);

	void 									(*SetUVCoeff)(xPolynomSurfacePoint *this_ptr, LONG uindex, LONG vindex, const Vector &vector);

	Bool									(*ResizeObject3)(xPolynomSurfaceData *this_ptr, LONG ucount, LONG vcount, LONG udegree, LONG vdegree);
	Real*									(*GetUBreakPoint)(xPolynomSurfaceData *this_ptr, LONG index);
	Real*									(*GetVBreakPoint)(xPolynomSurfaceData *this_ptr, LONG index);
	xPolynomSurfacePoint*	(*GetPoint3)(xPolynomSurfaceData *this_ptr, LONG uindex, LONG vindex);
	LONG									(*GetPointCount3)(xPolynomSurfaceData *this_ptr, GeListNode *node);
	void									(*InitClosed3)(xPolynomSurfaceData *this_ptr);

	void									(*SetStartAngle)(xRotateSurfaceData *this_ptr, Real angle);
	void									(*SetEndAngle)(xRotateSurfaceData *this_ptr, Real angle);
	void 									(*SetInvert)(xRotateSurfaceData *this_ptr, Bool state);

	void									(*SetPeriodicU)(xUVPairFF *this_ptr, Bool u);
	void									(*SetPeriodicV)(xUVPairFF *this_ptr, Bool v);
	void 									(*SetU)(xUVPairFF *this_ptr, LONG idx, Real u);
	void 									(*SetV)(xUVPairFF *this_ptr, LONG idx, Real v);
	Real 									(*GetU)(xUVPairFF *this_ptr, LONG idx);
	Real 									(*GetV)(xUVPairFF *this_ptr, LONG idx);

	xUVPairFF*						(*GetKnots)(xNurbsSurfaceData *this_ptr);
	void									(*SetPolynomial2)(xNurbsSurfaceData *this_ptr, Bool p);
	void									(*SetUClosed)(xNurbsSurfaceData *this_ptr, Bool c);
	void 									(*SetVClosed)(xNurbsSurfaceData *this_ptr, Bool c);
	Bool									(*ResizeObject5)(xNurbsSurfaceData *this_ptr, LONG ucount, LONG vcount, LONG udegree, LONG vdegree);
	void									(*SetUParameterRange)(xNurbsSurfaceData *this_ptr, Real min, Real max);
	void									(*SetVParameterRange)(xNurbsSurfaceData *this_ptr, Real min, Real max);
	LONG									(*GetUPointCount2)(xNurbsSurfaceData *this_ptr, GeListNode *node);
	LONG									(*GetVPointCount2)(xNurbsSurfaceData *this_ptr, GeListNode *node);
	xNurbsCurvePoint*			(*GetPoint4)(xNurbsSurfaceData *this_ptr, LONG uindex, LONG vindex);

	xMappedCurveData *		(*AllocMapped)(xMappedCurveClass *this_ptr, LONG type);
	Bool									(*Update3)(xMappedCurveClass *this_ptr, GeListNode *node);

	void									(*SetSegmented)(xStandardMappedCurveData *this_ptr, Bool value);

	void									(*SetReversed)(xSegmentMappedCurveData *this_ptr, Bool value);

	xTrimmedSurfaceData *	(*AllocTrimmed)(xTrimmedSurfaceClass *this_ptr, LONG type);
	void									(*SetPrecision4)(xTrimmedSurfaceClass *this_ptr, Real precision);
	Bool									(*Update4)(xTrimmedSurfaceClass *this_ptr, GeListNode *node);

	void									(*SetFirstOuter)(xStandardTrimmedSurfaceData *this_ptr, Bool value);

	Bool									(*xConvertToPolygons)(BaseObject *oroot, BaseObject *destination, LONG flags);
	Bool									(*xConvertToPolygonGroups)(BaseObject *oroot, BaseObject *destination, LONG flags);
	Bool									(*xCenterAxis)(BaseObject *oroot);
	Bool									(*xFilterModelSpaceCurves)(BaseObject *oroot);
};

#define CONVERT_CACHES (1<<0)
#define CONVERT_TOONE  (1<<1)

Bool xConvertToPolygons(BaseObject *oroot, BaseObject *destination, LONG flags);
Bool xConvertToPolygonGroups(BaseObject *oroot, BaseObject *destination, LONG flags);
Bool xCenterAxis(BaseObject *oroot);
Bool xFilterModelSpaceCurves(BaseObject *oroot);

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

#endif //__DWGO_H