#pragma OPENCL EXTENSION cl_amd_printf : enable

float PackToFloat(unsigned int x, unsigned int y, unsigned int z)
{
	unsigned int packedColor = (x << 16) | (y << 8) | z;
	float packedFloat = (float) ( ((float)packedColor) / ((float) (1 << 24)) );  

	return packedFloat;
}

__kernel void UpdatePositions(__global float4 *positions, __global float4 *velocities, __global float4 *attributes,__global float4 *forces, __global float4 *spawnPositions, __global float4 *spawnVelocities, __global float4 *spawnAttributes, float deltaTime, float4 limiter)
{
	uint index = get_global_id(0);
	
	//if(index == 0) printf("T: %v4f\n", attributes[0]);
	//Send particle offscreen if it's dead
	if(attributes[index].x < 0.01f)
	{
		positions[index] = (float4)(-999.0, -999.0, -999.0, 1.0);
	}
	else
	{
	//Velocities
	float4 oldVel = velocities[index];
	if(positions[index].x < limiter.x) velocities[index] += forces[index]*deltaTime;

	//Midpoint integration
	positions[index].xyz += 0.5*(oldVel.xyz+velocities[index].xyz)*deltaTime;

	//Life
	attributes[index].x -= deltaTime;
	//if(attributes[index].x < 0.0001) positions[index] = (float4)(-999.0, -999.0, -999.0, 1.0);
	}
}

__kernel void ClearForces(__global float4 *forces)
{
	uint index = get_global_id(0);

	forces[index] = (float4)(0.0,0.0,0.0,0.0);
}

__kernel void ApplyForces(__global float4 *forces, __global float4 *velocities, float4 gravity, float drag)
{
	uint index = get_global_id(0);

	forces[index] = (float4)(0.0,0.0,0.0,0.0);
	forces[index] += gravity;
	forces[index] -= drag*velocities[index];
}

__kernel void SpawnParticles(__global float4 *positions, __global float4 *velocities, __global float4 *attributes, __global float4* spawnPositions, __global float4* spawnVelocities, __global float4* spawnAttributes, int workLimit, int segmentEnd, int segmentLength)
{
	if(get_global_id(0) < workLimit)
	{
		uint index = get_global_id(0);
		if(index >= segmentEnd) index -= segmentLength;

		if(attributes[index].x < 0.0001f)
		{
			positions[index] = spawnPositions[index];
			velocities[index] = spawnVelocities[index];
			//TODO: mark segment?
			attributes[index] = spawnAttributes[index];
		}
	}
	else return;
}