#include "effects/TrackWave.h"

#include <algorithm>
#include <math.h>
#include <osg/Drawable>
#include <osg/Geometry>
#include <osg/CullFace>
#include <osg/Depth>

TrackWave::TrackWave(ElectricWave* pElectricWave)
	: DrawDecorate(pElectricWave), m_fHeight(5),m_fBottomRadius(2),m_fTopRadius(5),\
	m_fSpaceHeight(5),m_fLoopHeight(4),m_fdHeight(0),m_vStart(0, 0, 0), m_vEnd(0, 0, 85),\
	m_fUpdateValue(2), m_nCount(0),m_bZ(true)
{
	m_fdRadius = (m_fTopRadius - m_fBottomRadius) / m_fHeight;
}


TrackWave::~TrackWave(void)
{
}

// 设置起始点和终止点
void TrackWave::SetStartAndEnd(const osg::Vec3d& vStart, const osg::Vec3d& vEnd)
{
	m_vStart = vStart;
	m_vEnd = vEnd;

	osg::Vec3d vDir = m_vEnd - m_vStart;
	// 计算长度
	m_fHeight = vDir.length();
	// 归一化
	vDir.normalize();
	m_matrix = osg::Matrix::rotate(osg::Vec3d(0, 0, 1), vDir);

	// 重新计算半径
	ComputeDRadius();

	ForceDraw();
	ForceDrawStyle();
}

// 设置起始点和终止点
void TrackWave::GetStartAndEnd(osg::Vec3d& vStart, osg::Vec3d& vEnd)
{
	vStart = m_vStart;
	vEnd = m_vEnd;
}

// 设置半径
void TrackWave::SetRadius(const double fTopRadius, const double fBottonRadius)
{
	m_fTopRadius = fTopRadius;
	m_fBottomRadius = fBottonRadius;

	// 计算半径变化率
	ComputeDRadius();
}

// 获得半径
void TrackWave::GetRadius(double& fTopRadius, double& fBottonRadius)
{
	fTopRadius = m_fTopRadius;
	fBottonRadius = m_fBottomRadius;
}

// 设置环高度
void TrackWave::SetLoopHeight(const double fLoopHeight)
{
	m_fLoopHeight = fLoopHeight;
}

// 设置间隔高度
void TrackWave::SetSpaceHeight(const double fSpaceHeight)
{
	m_fSpaceHeight = fSpaceHeight;
}

// 设置更新速度
void TrackWave::SetUpdateSpeed(const double fSpeed)
{
	m_fUpdateValue = fSpeed;
}

// 是否是放大波
void TrackWave::SetWaveStyle(bool bZ)
{
	m_bZ = bZ;
	ForceDraw();
}

// 获得是否放大波
bool TrackWave::GetWaveSytle(void) const
{
	return (m_bZ);
}

// 创建渲染体
osg::Drawable* TrackWave::CreateDrawable(void)
{
	// 创建视图
	osg::Drawable* pDrawable = DrawDecorate::CreateDrawable();
	return (pDrawable);
}

// 获得顶点数组
osg::Vec3dArray* TrackWave::GetVertexArrays(void)
{
	osg::Vec3dArray* pVertexArray = new osg::Vec3dArray;

	double dCount = (m_fHeight / (m_fSpaceHeight + m_fLoopHeight));

	// 计算环的个数
	m_nCount = (dCount - (int)dCount >= 0.5f) ? (int)dCount + 1 : (int)dCount;

	for (int index = 0; index < m_nCount; ++index)
	{
		 // 计数从1开始
		CreateSingleVertex(index, pVertexArray);
	}

	return (pVertexArray);
}

void TrackWave::CreatePrimitiveSet(osg::Geometry* pGeometry, int nStart, int nCount)
{
	pGeometry->removePrimitiveSet(0, pGeometry->getNumPrimitiveSets());
	for (int index = 0; index < m_nCount; ++index)
	{
		pGeometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, index * 122, 122));
	}
}

// 创建圆环
void TrackWave::CreateSingleVertex(double index, osg::Vec3dArray* pVertexArray)
{
	// 计算高度
	double fHeight = index * (m_fLoopHeight + m_fSpaceHeight) + m_fLoopHeight + m_fdHeight;
	
	if ((fHeight - m_fLoopHeight) >= m_fHeight)
	{
		fHeight -= m_fHeight; 
	}

	// 计算顶部的半径
	double fTopRadius = CreateTopRadius(fHeight );
	// 计算底部半径
	double fBottonRadius = CreateBottonRadius(fHeight);

	// 临时变量
	double ftemp = 0;
	
	// 更新值
	for (int angle = 0; angle <= 60; ++angle)
	{
		double dTheta = osg::DegreesToRadians(angle * 6.0f);

		double xCos = std::cos(dTheta);
		double ySin = std::sin(dTheta);
		double xt = fTopRadius * xCos;
		double yt = fTopRadius * ySin;

		//ftemp = fHeight;
		 //判断值有效
		ftemp = std::min(fHeight, m_fHeight);
		double zt = ftemp ;

		double xb = fBottonRadius * xCos ;
		double yb = fBottonRadius * ySin ;
		ftemp = fHeight - m_fLoopHeight;

		double zb = ftemp ;

		osg::Vec3d vTop(xt, yt, m_bZ ? zt : (m_fHeight - zt));
		osg::Vec3d vBotton(xb, yb, m_bZ ? zb : (m_fHeight - zb));

		vTop = vTop * m_matrix;
		vBotton = vBotton * m_matrix;

		vTop += m_vStart;
		vBotton += m_vStart;

		pVertexArray->push_back(vTop);
		pVertexArray->push_back(vBotton);
	}
}

// 计算半径
double TrackWave::CreateTopRadius(double fHeight)
{
	// 判断最大有效半径
	fHeight = std::min(m_fHeight, fHeight);

	fHeight = m_bZ ? (fHeight) : (m_fHeight - fHeight);

	// 计算高度
	double fRadius = fHeight * m_fdRadius + m_fBottomRadius; 
	return (fRadius);
}

// 计算底部半径
double TrackWave::CreateBottonRadius(double fHeight)
{
	// 判断最大有效半径

	fHeight = std::min(m_fHeight, fHeight);

	double btLoopHeihgt = m_fHeight - fHeight ;

	if (btLoopHeihgt > 0 )
	{
		btLoopHeihgt += m_fLoopHeight; 
	}
	else
	{
		btLoopHeihgt = 0;
	}

	fHeight = m_bZ ? (fHeight - m_fLoopHeight) : (btLoopHeihgt);
	// 计算高度
	double fRadius = (fHeight) * m_fdRadius + m_fBottomRadius;
	return (fRadius);
}

// 获取两点间的距离
double TrackWave::GetDis(void)
{
	const osg::Vec3d v = m_vEnd - m_vStart;
	return (v.length());
}

// 计算半径斜率
double TrackWave::ComputeDRadius(void)
{
	m_fdRadius = (m_fTopRadius - m_fBottomRadius) / m_fHeight;
	return (m_fdRadius);
}

// 获得环的个数
int TrackWave::GetCount(void)
{
	return (m_nCount);
}

// 更新
void TrackWave::UpdataDrawable(void)
{
	if((m_fdHeight += m_fUpdateValue) > (m_fHeight))
	{
		m_fdHeight = 0;
	}

	ForceDraw();

	DrawDecorate::UpdataDrawable();
}