/* Do not include or call anything defined in this .h file. It is exclusivly for the use of hxa_util_normals.c */
#ifdef NORMAL_FACE

HXATYPE *hxa_util_normal_face_macro(HXANode *node)
{
	HXATYPE v1[3], v2[3], f, *normals, *n, *vertex, *a, *b, *c;
	unsigned int i, j, count;
	int *ref;
	ref = node->content.geometry.corner_stack.layers[HXA_CONVENTION_HARD_BASE_CORNER_LAYER_ID].data.int32_data;
	vertex = node->content.geometry.vertex_stack.layers[HXA_CONVENTION_HARD_BASE_VERTEX_LAYER_ID].data.HXATYPE_DATA;
	n = normals = malloc((sizeof *normals) * node->content.geometry.face_count * 3);
	for(i = 0; i < node->content.geometry.edge_corner_count;)
	{
		if(ref[i + 2] < 0) /* Triangle */
		{
			a = &vertex[hxa_ref(ref, i) * 3];
			b = &vertex[hxa_ref(ref, i + 1) * 3];
			c = &vertex[hxa_ref(ref, i + 2) * 3];
			v1[0] = a[0] - c[0];
			v1[1] = a[1] - c[1];
			v1[2] = a[2] - c[2];
			v2[0] = b[0] - c[0];
			v2[1] = b[1] - c[1];
			v2[2] = b[2] - c[2];
			n[0] = v1[2] * v2[1] - v1[1] * v2[2];
			n[1] = v1[0] * v2[2] - v1[2] * v2[0];
			n[2] = v1[1] * v2[0] - v1[0] * v2[1];
			i += 3;
		}else
		{
			count = node->content.geometry.edge_corner_count - i;
			n[0] = n[1] = n[2] = 0;
			for(j = 0; j < count; j++)
			{
				if(ref[i + j + 2] < 0)
					count = j + 2;
				a = &vertex[hxa_ref(ref, (i + j)) * 3];
				b = &vertex[hxa_ref(ref, (i + (j + 1) % count)) * 3];
				c = &vertex[hxa_ref(ref, (i + (j + 2) % count)) * 3];
				v1[0] = a[0] - c[0];
				v1[1] = a[1] - c[1];
				v1[2] = a[2] - c[2];
				v2[0] = b[0] - c[0];
				v2[1] = b[1] - c[1];
				v2[2] = b[2] - c[2];
				n[0] += v1[2] * v2[1] - v1[1] * v2[2];
				n[1] += v1[0] * v2[2] - v1[2] * v2[0];
				n[2] += v1[1] * v2[0] - v1[0] * v2[1];
			}
			i += count + 1;
		}
		f = sqrtf(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
		n[0] /= f;
		n[1] /= f;
		n[2] /= f;
		n += 3;
	}
	return normals;
}

#endif



#ifdef NORMAL_CORNER

HXATYPE *hxa_util_normal_corner_macro(HXANode *node, 
								unsigned int *neighburs,		
#ifdef HXA_CREASE_TYPE
								HXA_CREASE_TYPE *creases, 
#endif
								HXATYPE *face_normals,
								unsigned int *faces)
{
	HXATYPE *corner_normals, *n, tmp[3], f;
	unsigned int i, r;
	int * ref;
	ref = node->content.geometry.corner_stack.layers[HXA_CONVENTION_HARD_BASE_CORNER_LAYER_ID].data.int32_data;
	corner_normals = malloc((sizeof *corner_normals) * node->content.geometry.edge_corner_count * 3);
	for(i = 0; i < node->content.geometry.edge_corner_count * 3; i++)
		corner_normals[i] = 0;
	for(i = 0; i < node->content.geometry.edge_corner_count; i++)
	{
		if(corner_normals[i * 3] == 0 && corner_normals[i * 3 + 1] == 0 && corner_normals[i * 3 + 2] == 0)
		{
			r = i;
			tmp[0] = tmp[1] = tmp[2] = 0;
			n = &face_normals[faces[r] * 3];
			tmp[0] += n[0];
			tmp[1] += n[1];
			tmp[2] += n[2];

			r = i;
			while(r = neighburs[hxa_corner_get_previous(ref, r)] != -1 && r != i
#ifdef HXA_CREASE_TYPE							
					&& !creases[r]
#endif	
				)
			{
				n = &face_normals[faces[r] * 3];
				tmp[0] += n[0];
				tmp[1] += n[1];
				tmp[2] += n[2];
			}
			if(i != r)
			{
				r = i;
				while(
#ifdef HXA_CREASE_TYPE							
						!creases[r] && 
#endif	
					(r = neighburs[r]) != -1 && (r = hxa_corner_get_next(ref, r)) != i)
				{
						
					n = &face_normals[faces[r] * 3];
					tmp[0] += n[0];
					tmp[1] += n[1];
					tmp[2] += n[2];
				}
			}
			f = sqrt(tmp[0] * tmp[0] + tmp[1] * tmp[1] + tmp[2] * tmp[2]);
			tmp[0] /= f;
			tmp[1] /= f;
			tmp[2] /= f;
			
			corner_normals[i * 3] = tmp[0];
			corner_normals[i * 3 + 1] = tmp[1];
			corner_normals[i * 3 + 2] = tmp[2];

			r = i;
			while(r = neighburs[hxa_corner_get_previous(ref, r)] != -1 && r != i
#ifdef HXA_CREASE_TYPE							
					&& !creases[r]
#endif	
				)
			{
				corner_normals[r * 3] = tmp[0];
				corner_normals[r * 3 + 1] = tmp[1];
				corner_normals[r * 3 + 2] = tmp[2];
			}
			if(i != r)
			{			
				r = i;
				while(
#ifdef HXA_CREASE_TYPE							
						!creases[r] && 
#endif	
					(r = neighburs[r]) != -1 && (r = hxa_corner_get_next(ref, r)) != i)
				{
						
					corner_normals[r * 3] = tmp[0];
					corner_normals[r * 3 + 1] = tmp[1];
					corner_normals[r * 3 + 2] = tmp[2];
				}
			}
		}
	}
	return corner_normals;
}
#endif