/*
 * ExNihilo 3D Engine
 * 
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Please read AUTHORS file !!!
 * 
 * $Id: ExCGizmoLineBezier.cpp,v 1.5 2002/08/14 15:20:54 data Exp $
 *
 */

#include "ExCGizmoLineBezier.h"

ExCGizmoLineBezier::ExCGizmoLineBezier(void)
{
	SetName("ExCGizmoLineBezier");
	SetType(typeid(this).name());
	m_OriginePoint.SetValue(0.0f,0.0f,100.0f);
	m_ControlPoint1.SetValue(0.0f,100.0f,100.0f);
	m_ControlPoint2.SetValue(0.0f,200.0f,500.0f);
	m_EndPoint.SetValue(200.0f,300.0f,500.0f);
	m_Color.SetValue(0.5,1,0.5);
}

ExCGizmoLineBezier::ExCGizmoLineBezier(ExCVec3D Origine,ExCVec3D Ctrl1,ExCVec3D Ctrl2,ExCVec3D End)
{
	SetName("ExCGizmoLineBezier");
	SetType(typeid(this).name());

}

ExCGizmoLineBezier::~ExCGizmoLineBezier(void)
{
}

ExCVec3D ExCGizmoLineBezier::PointOnCurve(float t)
{
	ExCVec3D vPoint;
/*

	double plouf=pow((1-t),3);
	//double plouf=pow((1-t),3);
	vPoint.m_Vector[0]=m_OriginePoint.GetX()*plouf;//pow(t,0)*pow((1-t),m_VectorPoint.size()-1);
	vPoint.m_Vector[1]=m_OriginePoint.GetY()*plouf;//pow(t,0)*pow((1-t),m_VectorPoint.size()-1);
	vPoint.m_Vector[2]=m_OriginePoint.GetZ()*plouf;//pow(t,0)*pow((1-t),m_VectorPoint.size()-1);

	//for(i=1,j=m_VectorPoint.size()-2;i<m_VectorPoint.size()-1;i++,j--)
	
	plouf=pow(t,1)*pow((1-t),2)*4;
	vPoint.m_Vector[0]+=m_ControlPoint1.GetX()*plouf;//pow(t,i)*pow((1-t),j)*3;
	vPoint.m_Vector[1]+=m_ControlPoint1.GetY()*plouf;//pow(t,i)*pow((1-t),j)*3;
	vPoint.m_Vector[2]+=m_ControlPoint1.GetZ()*plouf;//pow(t,i)*pow((1-t),j)*3;

	plouf=pow(t,2)*pow((1-t),1)*4;
	vPoint.m_Vector[0]+=m_ControlPoint2.GetX()*plouf;//pow(t,i)*pow((1-t),j)*3;
	vPoint.m_Vector[1]+=m_ControlPoint2.GetY()*plouf;//pow(t,i)*pow((1-t),j)*3;
	vPoint.m_Vector[2]+=m_ControlPoint2.GetZ()*plouf;//pow(t,i)*pow((1-t),j)*3;
		
	vPoint.m_Vector[0]+=m_EndPoint.GetX()*pow(t,3);//*pow((1-t),j);
	vPoint.m_Vector[1]+=m_EndPoint.GetY()*pow(t,3);//*pow((1-t),j);
	vPoint.m_Vector[2]+=m_EndPoint.GetZ()*pow(t,3);//*pow((1-t),j);
*/
	
	float var1, var2, var3;


	var1 = 1 - t;


	var2 = var1 * var1 * var1;


	var3 = t * t * t;

	vPoint.m_Vector[0] = var2*m_OriginePoint.GetX() + 3*t*var1*var1*m_ControlPoint1.GetX() + 3*t*t*var1*m_ControlPoint2.GetX() + var3*m_EndPoint.GetX();
	vPoint.m_Vector[1]= var2*m_OriginePoint.GetY() + 3*t*var1*var1*m_ControlPoint1.GetY() + 3*t*t*var1*m_ControlPoint2.GetY() + var3*m_EndPoint.GetY();
	vPoint.m_Vector[2]= var2*m_OriginePoint.GetZ() + 3*t*var1*var1*m_ControlPoint1.GetZ() + 3*t*t*var1*m_ControlPoint2.GetZ() + var3*m_EndPoint.GetZ();


	return vPoint;
}

void ExCGizmoLineBezier::Draw()
{
	if (m_Visible)
	{
		DrawLine();
		DrawControlPoint();
	}
	
}

void ExCGizmoLineBezier::DrawLine()
{
	int plouf;
	plouf=100;
	glColor3fv(m_Color.m_Vector);
	glBegin(GL_LINE_STRIP);	
		for(float t = 0; t <= (1 + (1.0f / plouf)); t += 1.0f / plouf)
		{
		//vPoint= PointOnCurve(t);
			glVertex3fv(PointOnCurve(t).m_Vector);
		}
	glEnd();
}

void ExCGizmoLineBezier::DrawControlPoint()
{
	glColor3f(1,1,1);

	glPushMatrix();
		glTranslatef(m_OriginePoint.GetX(),m_OriginePoint.GetY(),m_OriginePoint.GetZ());
		glutWireSphere(0.5,4,4);
	glPopMatrix();

	glPushMatrix();
		glTranslatef(m_ControlPoint1.GetX(),m_ControlPoint1.GetY(),m_ControlPoint1.GetZ());
		glutWireSphere(0.5,4,4);
	glPopMatrix();

	glPushMatrix();
		glTranslatef(m_ControlPoint2.GetX(),m_ControlPoint2.GetY(),m_ControlPoint2.GetZ());
		glutWireSphere(0.5,4,4);
	glPopMatrix();

	glPushMatrix();
		glTranslatef(m_EndPoint.GetX(),m_EndPoint.GetY(),m_EndPoint.GetZ());
		glutWireSphere(0.5,4,4);
	glPopMatrix();
}

bool ExCGizmoLineBezier::LoadFile(std::string FileName)
{
Guard(bool ExCGizmoLineBezier::LoadFile(std::string FileName))
	SetFileName(FileName);
	//std::cout<<"Loading ExCGizmoLineBezier"<<std::endl;

	char			buffer[255];
	sprintf(buffer, "../Data/Gizmo/%s", FileName.data());
	std::ifstream fin;
	std::string buffstring;
	char b[256];
	fin.open(buffer,std::ios::in);
	if(fin.is_open())
	{
		try
		{
		
		//----Read Type
		memset(b,0,255);fin.getline(b,256,'\n');
		
		//Control point 1
		memset(b,0,255);fin.getline(b,256,'\n');
		buffstring=ExNihilo::ExtracValueFromSring(b,"<CtrlPoint0>","<#CtrlPoint0>");
		m_OriginePoint.SetValue(ExNihilo::ExtractFloatValueFromSring(buffstring,"<X>","<#X>"),
			ExNihilo::ExtractFloatValueFromSring(buffstring,"<Y>","<#Y>"),
			ExNihilo::ExtractFloatValueFromSring(buffstring,"<Z>","<#Z>"));
		
		//Control point 1
		memset(b,0,255);fin.getline(b,256,'\n');
		buffstring=ExNihilo::ExtracValueFromSring(b,"<CtrlPoint1>","<#CtrlPoint1>");
		m_ControlPoint1.SetValue(ExNihilo::ExtractFloatValueFromSring(buffstring,"<X>","<#X>"),
			ExNihilo::ExtractFloatValueFromSring(buffstring,"<Y>","<#Y>"),
			ExNihilo::ExtractFloatValueFromSring(buffstring,"<Z>","<#Z>"));
		
		//Control point 1
		memset(b,0,255);fin.getline(b,256,'\n');
		buffstring=ExNihilo::ExtracValueFromSring(b,"<CtrlPoint2>","<#CtrlPoint2>");
		m_ControlPoint2.SetValue(ExNihilo::ExtractFloatValueFromSring(buffstring,"<X>","<#X>"),
			ExNihilo::ExtractFloatValueFromSring(buffstring,"<Y>","<#Y>"),
			ExNihilo::ExtractFloatValueFromSring(buffstring,"<Z>","<#Z>"));
		
		//Control point 1
		memset(b,0,255);fin.getline(b,256,'\n');
		buffstring=ExNihilo::ExtracValueFromSring(b,"<CtrlPoint3>","<#CtrlPoint3>");
		m_EndPoint.SetValue(ExNihilo::ExtractFloatValueFromSring(buffstring,"<X>","<#X>"),
			ExNihilo::ExtractFloatValueFromSring(buffstring,"<Y>","<#Y>"),
			ExNihilo::ExtractFloatValueFromSring(buffstring,"<Z>","<#Z>"));
		fin.close();
		

		}catch(...){throw ExCExpFileReadError();}
	}else throw   ExCExpFileNotFound();
	return true;
UnGuard
}
