#include "VehiclePhysicsComponent.h"
#include "EntityManager.h"

VehiclePhysicsComponent::VehiclePhysicsComponent(Entity* parent) : Component(parent) {
	m_Position = NiPoint3::ZERO;
	m_Rotation = NiQuaternion::IDENTITY;
	m_Velocity = NiPoint3::ZERO;
	m_AngularVelocity = NiPoint3::ZERO;
	m_IsOnGround = true;
	m_IsOnRail = false;
	m_DirtyPosition = true;
	m_DirtyVelocity = true;
	m_DirtyAngularVelocity = true;
}

VehiclePhysicsComponent::~VehiclePhysicsComponent() {

}

void VehiclePhysicsComponent::SetPosition(const NiPoint3& pos) {
	m_Position = pos;
}

void VehiclePhysicsComponent::SetRotation(const NiQuaternion& rot) {
	m_DirtyPosition = true;
	m_Rotation = rot;
}

void VehiclePhysicsComponent::SetVelocity(const NiPoint3& vel) {
	m_DirtyPosition = true;
	m_Velocity = vel;
}

void VehiclePhysicsComponent::SetAngularVelocity(const NiPoint3& vel) {
	m_DirtyPosition = true;
	m_AngularVelocity = vel;
}

void VehiclePhysicsComponent::SetIsOnGround(bool val) {
	m_DirtyPosition = true;
	m_IsOnGround = val;
}

void VehiclePhysicsComponent::SetIsOnRail(bool val) {
	m_DirtyPosition = true;
	m_IsOnRail = val;
}

void VehiclePhysicsComponent::SetDirtyPosition(bool val) {
	m_DirtyPosition = val;
}

void VehiclePhysicsComponent::SetDirtyVelocity(bool val) {
	m_DirtyVelocity = val;
}

void VehiclePhysicsComponent::SetDirtyAngularVelocity(bool val) {
	m_DirtyAngularVelocity = val;
}

void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) {
	outBitStream->Write(bIsInitialUpdate || m_DirtyPosition);

	if (bIsInitialUpdate || m_DirtyPosition) {
		outBitStream->Write(m_Position);

		outBitStream->Write(m_Rotation);

		outBitStream->Write(m_IsOnGround);
		outBitStream->Write(m_IsOnRail);

		outBitStream->Write(bIsInitialUpdate || m_DirtyVelocity);

		if (bIsInitialUpdate || m_DirtyVelocity) {
			outBitStream->Write(m_Velocity);
		}

		outBitStream->Write(bIsInitialUpdate || m_DirtyAngularVelocity);

		if (bIsInitialUpdate || m_DirtyAngularVelocity) {
			outBitStream->Write(m_AngularVelocity);
		}

		outBitStream->Write0();

		outBitStream->Write0();

		outBitStream->Write(0.0f);

		if (!bIsInitialUpdate) {
			outBitStream->Write0();
		}
	}

	if (bIsInitialUpdate) {
		outBitStream->Write<uint8_t>(5);
		outBitStream->Write1();
	}

	outBitStream->Write0();
}

void VehiclePhysicsComponent::Update(float deltaTime) {
	if (m_SoftUpdate > 5) {
		EntityManager::Instance()->SerializeEntity(m_Parent);

		m_SoftUpdate = 0;
	} else {
		m_SoftUpdate += deltaTime;
	}
}