///////////////////////////////////////////////////////////////////////////////
/// @file deLine_priv.hpp
///
/// @brief Private Mathematical Line Representations header
///
/// @author Assassin
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Jul 2002
/// @author Assassin
/// @remarks Creation
///
///////////////////////////////////////////////////////////////////////////////

#ifndef DELINE_PRIV_HPP
#define DELINE_PRIV_HPP

#include "deLine.hpp"

class deLine : public IdeLine
{
public:
	long Release();

	// feed it a float between 0.0 and 1.0
	void GetPointOnLine(deDouble Fraction, deVec3d & point);
	void GetTangentAtPoint(deDouble Fraction, deVec3d & point);
	// GetLength only useful for combined lines, but very useful there
	long GetLength();

	long GetNumCVs();
	void GetCVList(deVec3d buffer[]);
	deVec3d GetCV(long num);
	void SetCV(long num, deVec3d & CV);
	void SetCVList(long num, deVec3d CVList[]);
	void AddCV(deVec3d & point);

	IdeLine * Copy();

protected:
	deLine();
	virtual ~deLine();

	virtual void InterpolateLine(deDouble Fraction, deVec3d & point) = 0;
	virtual void InterpolateTangent(deDouble Fraction, deVec3d & point) = 0;
	virtual IdeLine * CopyLine() = 0;

	long m_CVNum;
	deTArray <deVec3d> m_CVList;
	long m_Length;
	deBoolean m_Changed;
};

//=======================================================
class GroupLine : public deLine
{
public:
	GroupLine();
	~GroupLine();

	deBoolean AddLine(IdeLine * line);
	long RemoveLine();

protected:
	void InterpolateLine(deDouble Fraction, deVec3d & point);
	virtual void InterpolateTangent(deDouble Fraction, deVec3d & point);
	IdeLine * CopyLine();

private:
	deTArray <IdeLine*> m_Lines;
};

//=======================================================
class StraightLine : public deLine
{
public:
	StraightLine();
	~StraightLine();

protected:
	void InterpolateLine(deDouble Fraction, deVec3d & point);
	virtual void InterpolateTangent(deDouble Fraction, deVec3d & point);
	IdeLine * CopyLine();
};


//=======================================================
class BezierLine : public deLine
{
public:
	BezierLine();
	~BezierLine();

protected:
	void InterpolateLine(deDouble Fraction, deVec3d & point);
	virtual void InterpolateTangent(deDouble Fraction, deVec3d & point);
	IdeLine * CopyLine();

private:
	// k is from 0->degree-1, 0 <= t <= 1
	deDouble F(long k, deDouble t);
	deDouble D(long k, deDouble t);
};

class ArcLine : public deLine
{
public:
	ArcLine();
	~ArcLine();

protected:
	void InterpolateLine(deDouble Fraction, deVec3d & point);
	virtual void InterpolateTangent(deDouble Fraction, deVec3d & point);
	IdeLine * CopyLine();

private:
	deTransform m_transform;
	deDouble m_Degree;
	deDouble m_Radius;
};

#endif