// This file is part of ThriceBall.
//
// Author: Kai Hillenbrand (AnTeevY)
// © Copyright, 2009 by Kai Hillenbrand, http://www.anteevy.de

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

#include "platform.h"

CPlatform::CPlatform(CRenderer *renderer, CLevel *level, NxOgre::Scene *scene, OGRE3DRenderSystem *rendersys)
	: m_pRenderer(renderer), m_pLevel(level), m_pScene(scene), m_pRenderSystem(rendersys),
	m_pSceneMgr(renderer->getSceneManager()), m_pPlayer(renderer->getPlayer()),
	m_fSpeed(1), m_fXPos1(0), m_fYPos1(0), m_fZPos1(0), m_fXPos2(0), m_fYPos2(0), m_fZPos2(0),
	m_fXScale(1), m_fYScale(1), m_fZScale(1), m_bForward(true), m_vDirection(NxOgre::Vec3(0,0,0)),
	m_fWaitCounter(0), m_bWait(false), m_fWaitCounterMax(0)
{
}

void CPlatform::create(float x1, float y1, float z1, float x2, float y2, float z2, float speed, float wait,
					   float sX, float sY, float sZ)
{
	// apply the variables
	m_fXPos1 = x1;
	m_fYPos1 = y1;
	m_fZPos1 = z1;
	m_fXPos2 = x2;
	m_fYPos2 = y2;
	m_fZPos2 = z2;
	m_fSpeed = speed;
	m_fXScale = sX;
	m_fYScale = sY;
	m_fZScale = sZ;
	m_fWaitCounterMax = m_fWaitCounter = wait;
	m_vDirection = NxOgre::Vec3(m_fXPos2 - m_fXPos1, m_fYPos2 - m_fYPos1, m_fZPos2 - m_fZPos1);
	m_fDistance = Vector3(m_vDirection.x, m_vDirection.y, m_vDirection.z).length();
	
	// normalise the vector so that the distance between the start and end does not influence the move speed
	m_vDirection.normalise();

	// create the kinematic body and scale it
	m_pPlatformBody = m_pRenderSystem->createKinematicBody(new NxOgre::Box(m_fXScale, m_fYScale, m_fZScale), 
		NxOgre::Real3(m_fXPos1, m_fYPos1, m_fZPos1), "cube.1m.mesh");
	m_pPlatformBody->getEntity()->getParentSceneNode()->scale(m_fXScale, m_fYScale, m_fZScale);
}

void CPlatform::move()
{
	// if platform should really move
	if (!m_bWait)
	{
		if (m_bForward)
		{
			// move the platform in direction to the end (forward)
			m_pPlatformBody->moveGlobalPosition(m_pPlatformBody->getGlobalPosition() + m_vDirection * 0.01 * m_fSpeed);

			// calculate the distance between current location and starting point (X1|Y1|Z1)
			float fDistToXYZ1 = Vector3(m_pPlatformBody->getGlobalPosition().x - m_fXPos1, 
				m_pPlatformBody->getGlobalPosition().y - m_fYPos1, 
				m_pPlatformBody->getGlobalPosition().z - m_fZPos1).length();

			// if that distance is larger than the distance between start and end, reverse the direction
			if (fDistToXYZ1 > m_fDistance)
			{
				m_bForward = false;
				m_bWait = true;
			}
		}
		else
		{
			// move the platform in direction to the start (backward)
			m_pPlatformBody->moveGlobalPosition(m_pPlatformBody->getGlobalPosition() - m_vDirection * 0.01 * m_fSpeed);

			// calculate the distance between current location and ending point (X2|Y2|Z2)
			float fDistToXYZ2 = Vector3(m_pPlatformBody->getGlobalPosition().x - m_fXPos2, 
				m_pPlatformBody->getGlobalPosition().y - m_fYPos2, 
				m_pPlatformBody->getGlobalPosition().z - m_fZPos2).length();
			
			// if that distance is larger than the distance between start and end, reverse the direction
			if (fDistToXYZ2 > m_fDistance)
			{
				m_bForward = true;
				m_bWait = true;
			}
		}
	}
	else // m_bWait is true -> platform should wait
	{
		m_fWaitCounter--;	// lower the counter

		if (m_fWaitCounter <= 0)	// if counter hits zero...
		{
			m_fWaitCounter = m_fWaitCounterMax;	// ...reset it...
			m_bWait = false;					// ...and stop waiting
		}
	}
}