/**
 * \file flow.c
 * \brief This file helps to handle the flow buffer
 *
 *
 *  \ingroup corefiles
 *  \date May 13, 2009
 *  \author Alexander Pimenov
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "global.h"

#include "flow.h"



#ifdef ASSERT
int flowBufferCounter = 0;
#endif

/**
 * \brief This function creates a flow buffer for the given width and height.
 *
 *
 * You should not forget to destroy the created buffer with the call to flowBufferDelete(toDelete)
 *
 * \param h The height of the image to be created.
 * \param w The width of the image to be created.
 *
 * \return a newly created buffer.
 */
FlowBuffer *flowBufferCreate(int h, int w)
{
	int i;
	FlowBuffer *toReturn = (FlowBuffer *) dv_malloc (sizeof (FlowBuffer));
	toReturn->h = h;
	toReturn->w = w;
	toReturn->data = (vector2Ds16 *) dv_calloc(h * w , sizeof(vector2Ds16));
	for (i = 0; i < h * w ; i++)
	{
		toReturn->data[i].x = FLOW_UNKNOWN_X;
		toReturn->data[i].y = FLOW_UNKNOWN_Y;
	}

#ifdef ASSERT
	flowBufferCounter++;
#endif

	return toReturn;
}

/**
 * This function deletes a flow buffer
 *
 *  \param toDelete the buffer to be deleted
 */
void flowBufferDelete(FlowBuffer *toDelete)
{
	if (toDelete->data != NULL)
		dv_free(toDelete->data);
	dv_free(toDelete);


#ifdef ASSERT
	flowBufferCounter--;
#endif

}

/**
 * \brief This function counts the number of points for which the flow is know.
 *
 * \param flow An input flow buffer to count good points for
 * \return number of points for which the flow is known
 *
 */
uint32_t flowCountDensity(FlowBuffer *flow)
{
	int h = flow->h;
	int w = flow->w;
	int count = 0;
	int i,j;
	for (i = 0; i < h ; i++)
	{
		for (j = 0; j < w; j++)
		{
			vector2Ds16 *shift = &(flow->data[i * w + j]);
			if (shift->x != FLOW_UNKNOWN_X && shift->y != FLOW_UNKNOWN_Y)
			{
				count++;
			}
		}
	}

	return count;
}
