#include "stdafx.h"
#include "ModelMovements.h"

const GLfloat startMoveTime = 0.1f;
const GLfloat moveTimeDuration = 0.40f;
const GLfloat endMoveTime = startMoveTime + moveTimeDuration;

const GLfloat legsDistance = 0.1f;		// Расстояние оборота ноги
const GLfloat turnsNumber = 3.0f;		// Количество оборотов ноги
const GLfloat turnTime = 1.0f / turnsNumber;	// Относительное время оборота ноги
const GLfloat halfTurnTime = turnTime / 2.0f;


GLfloat GetDisplacementFromRelativeTime(GLfloat moveTimeRelative, bool isLeft)
{
	GLfloat displ = moveTimeRelative * transitionDistance;
	if(isLeft)
		return displ;
	else
		return -displ;
}

GLfloat GetMoveTimeRelative(GLfloat curTime)
{
	if(curTime < startMoveTime)
		return 0.0f;
	
	if(curTime <= endMoveTime)
		return (curTime - startMoveTime) / moveTimeDuration;

	if(curTime > endMoveTime)
		return 1.0f;
}

GLfloat GetXDisplacement(GLfloat curTime, bool isLeft)
{
	GLfloat relTime = GetMoveTimeRelative(curTime);

	return GetDisplacementFromRelativeTime(relTime, isLeft);
}


void PerformLeftHandTransitionAndRotation(GLfloat curTime) 
{
	Displacement displacement;
	Rotation rotation;
	ZeroMemory(&displacement, sizeof(Displacement));
	ZeroMemory(&rotation, sizeof(Rotation));

	displacement.x = GetXDisplacement(curTime, true);

	int tmp;
	GLfloat angleIndex;
	rotation.z = 1;
	if(curTime < startMoveTime + 0.2f || curTime > endMoveTime)
		rotation.angle = -45.0f;
	else
	{
		tmp = curTime / 0.1;
		angleIndex = curTime - tmp * 0.1f;
		rotation.angle = 45.0f - 90.0f / 0.1f * angleIndex;
	}

	glTranslatef(displacement.x, displacement.y, displacement.z);
	glRotatef(rotation.angle, rotation.x, rotation.y, rotation.z);
}

void PerformLeftTransition(GLfloat curTime) 
{
	Displacement displacement;
	ZeroMemory(&displacement, sizeof(Displacement));

	displacement.x = GetXDisplacement(curTime, true);

	glTranslatef(displacement.x, displacement.y, displacement.z);
}


void PerformRightBodyTransition(GLfloat curTime, bool isLeftPart) 
{
	Displacement displacement;
	Rotation rotation;
	ZeroMemory(&displacement, sizeof(Displacement));
	ZeroMemory(&rotation, sizeof(Rotation));

	displacement.x = GetXDisplacement(curTime, false);
	glTranslatef(displacement.x, displacement.y, displacement.z);

	GLfloat timeFromMoveEnd = curTime - endMoveTime;
	if(timeFromMoveEnd >= 0)
	{
		if(isLeftPart)
		{
			displacement.y = timeFromMoveEnd * 2;
			displacement.x = timeFromMoveEnd * 2;
			displacement.z = timeFromMoveEnd * 7;
			rotation.angle = timeFromMoveEnd * 180 * 8;

		}
		else
		{
			displacement.y = timeFromMoveEnd * 3;
			displacement.x = timeFromMoveEnd * 2;
			displacement.z = - timeFromMoveEnd * 6;
			rotation.angle = timeFromMoveEnd * 180 * 4;
		}
		rotation.z = 1;
		glTranslatef(displacement.x, displacement.y, displacement.z);
		glRotatef(rotation.angle, rotation.x, rotation.y, rotation.z);
	}
}

void PerformRightHornsTransition(GLfloat curTime, bool isLeftHorn) 
{
	Displacement displacement;
	Rotation rotation;
	ZeroMemory(&displacement, sizeof(Displacement));
	ZeroMemory(&rotation, sizeof(Rotation));

	displacement.x = GetXDisplacement(curTime, false);
	glTranslatef(displacement.x, displacement.y, displacement.z);

	GLfloat timeFromMoveEnd = curTime - endMoveTime;
	if(timeFromMoveEnd >= 0)
	{
		if(isLeftHorn)
		{
			displacement.y = timeFromMoveEnd * 4;
			displacement.x = - timeFromMoveEnd / 2;
			displacement.z = timeFromMoveEnd * 6;
			rotation.angle = (timeFromMoveEnd / 0.2f - floor(timeFromMoveEnd / 0.2f)) * 360.0f;

		}
		else
		{
			displacement.y = -timeFromMoveEnd * 2;
			displacement.x = timeFromMoveEnd * 1.7f;
			displacement.z = -timeFromMoveEnd * 7;
			rotation.angle = (timeFromMoveEnd / 0.2f - floor(timeFromMoveEnd / 0.2f)) * 360.0f;
		}
		rotation.z = 1;
		rotation.x = 1;
		rotation.y = 1;		
		
		glTranslatef(displacement.x, displacement.y, displacement.z);
		glRotatef(rotation.angle, rotation.x, rotation.y, rotation.z);
	}
}

void PerformRightHeadTransition(GLfloat curTime) 
{
	Displacement displacement;
	Rotation rotation;
	ZeroMemory(&displacement, sizeof(Displacement));
	ZeroMemory(&rotation, sizeof(Rotation));

	displacement.x = GetXDisplacement(curTime, false);
	glTranslatef(displacement.x, displacement.y, displacement.z);

	GLfloat timeFromMoveEnd = curTime - endMoveTime;
	if(timeFromMoveEnd >= 0)
	{
		displacement.y = timeFromMoveEnd * 2;
		displacement.x = timeFromMoveEnd * 5;
		displacement.z = -timeFromMoveEnd * 8;
		rotation.angle = timeFromMoveEnd * 180 * 5;
		
		rotation.z = 1.0f;
		rotation.x = 1.0f;

		glTranslatef(displacement.x, displacement.y, displacement.z);
		glRotatef(rotation.angle, rotation.x, rotation.y, rotation.z);
	}
}

void PerformRightHandTransitionAndRotation(GLfloat curTime) 
{
	Displacement displacement;
	Rotation rotation;
	ZeroMemory(&displacement, sizeof(Displacement));
	ZeroMemory(&rotation, sizeof(Rotation));
	rotation.z = 1;

	displacement.x = GetXDisplacement(curTime, false);
	glTranslatef(displacement.x, displacement.y, displacement.z);

	if(curTime < startMoveTime + 0.2f)
		rotation.angle = 45.0f;
	else if(curTime < endMoveTime)
	{
		int tmp = curTime / 0.1;
		GLfloat angleIndex = curTime - tmp * 0.1f;
		rotation.angle = 45.0f - 90.0f / 0.1f * angleIndex;
	}	
	glRotatef(rotation.angle, rotation.x, rotation.y, rotation.z);

	// -------------

	GLfloat timeFromMoveEnd = curTime - endMoveTime;
	if(timeFromMoveEnd >= 0)
	{
		displacement.y = timeFromMoveEnd * 2;
		displacement.x = -timeFromMoveEnd * 6;
		displacement.z = -timeFromMoveEnd * 6;
		rotation.angle = timeFromMoveEnd * 180 * 2;

		glTranslatef(displacement.x, displacement.y, displacement.z);
		glRotatef(rotation.angle, rotation.x, rotation.y, rotation.z);
	}
}

void PerformLegsTransition(GLfloat curTime, bool isLeftRobot, bool isLeftLeg)
{
	Displacement displacement;
	Rotation rotation;
	ZeroMemory(&displacement, sizeof(Displacement));
	ZeroMemory(&rotation, sizeof(Rotation));

	displacement.x = GetXDisplacement(curTime, isLeftRobot);
	glTranslatef(displacement.x, displacement.y, displacement.z);

	if(curTime >= startMoveTime && curTime <= endMoveTime)
	{
		GLfloat curMoveRelativeTime = GetMoveTimeRelative(curTime);
		int tmp = curMoveRelativeTime / turnTime;						// номер оборота ноги

		GLfloat displacementIndex = curMoveRelativeTime - tmp * turnTime;  // прогресс оборота ноги

		if(displacementIndex >= 0.0f && displacementIndex < halfTurnTime)
			displacement.x = legsDistance / halfTurnTime * displacementIndex;
		else
			displacement.x = (legsDistance - legsDistance / halfTurnTime * (displacementIndex - halfTurnTime));

		if(isLeftLeg == false)
			displacement.x *= -1;

		glTranslatef(displacement.x, displacement.y, displacement.z);
	}

	if(isLeftRobot == false)	// Right Robot
	{
		GLfloat timeFromMoveEnd = curTime - endMoveTime;
		if(timeFromMoveEnd >= 0)
		{
			if(isLeftLeg)
			{
				displacement.y = timeFromMoveEnd * 5;
				displacement.x = -timeFromMoveEnd * 4;
				displacement.z = -timeFromMoveEnd * 2;
				rotation.angle = timeFromMoveEnd * 180 * 7;
			}
			else
			{
				displacement.y = timeFromMoveEnd * 5;
				displacement.x = timeFromMoveEnd * 4;
				displacement.z = timeFromMoveEnd * 2;
				rotation.angle = timeFromMoveEnd * 180 * 8;
			}			
			rotation.x = rotation.y = rotation.z = 1.0f;
			glTranslatef(displacement.x, displacement.y, displacement.z);
			glRotatef(rotation.angle, rotation.x, rotation.y, rotation.z);
		}
	}
}

void PerformLegsTurns(GLfloat curTime, bool isLeftRobot, bool isLeftLeg)
{
	Displacement displacement;
	ZeroMemory(&displacement, sizeof(Displacement));

	if(curTime >= startMoveTime && curTime <= endMoveTime)
	{
		GLfloat curMoveRelativeTime = GetMoveTimeRelative(curTime);
		int tmp = curMoveRelativeTime / turnTime;						// номер оборота ноги

		GLfloat displacementIndex = curMoveRelativeTime - tmp * turnTime;  // прогресс оборота ноги

		if(displacementIndex >= 0.0f && displacementIndex < halfTurnTime)
			displacement.x = legsDistance / halfTurnTime * displacementIndex;
		else
			displacement.x = (legsDistance - legsDistance / halfTurnTime * (displacementIndex - halfTurnTime));

		if(isLeftLeg == false)
			displacement.x *= -1;

		glTranslatef(displacement.x, displacement.y, displacement.z);
	}
}


void PerformLeftHandRotation(GLfloat curTime) 
{
	Displacement displacement;
	Rotation rotation;
	ZeroMemory(&displacement, sizeof(Displacement));
	ZeroMemory(&rotation, sizeof(Rotation));

	int tmp;
	GLfloat angleIndex;
	rotation.z = 1;
	if(curTime < startMoveTime + 0.2f || curTime > endMoveTime)
		rotation.angle = -45.0f;
	else
	{
		tmp = curTime / 0.1;
		angleIndex = curTime - tmp * 0.1f;
		rotation.angle = 45.0f - 90.0f / 0.1f * angleIndex;
	}

	glRotatef(rotation.angle, rotation.x, rotation.y, rotation.z);
}