#ifndef SHAPE_RENDERING_H
#define SHAPE_RENDERING_H

#include <i3d/image3d.h>

#include "../settings.h"

/**
 * Take two binary images and align (following PCA results)
 * the secodn one according to the first one.
 *
 * \param[in] firstMask		reference image
 * \param[in,out] secondMask	image to be aligned
 */
void AlignMasks(const i3d::Image3d<bool> &firstMask,
					 i3d::Image3d<bool> &secondMask);

/**
 * Generate a black cell mask with a given resolution.
 * The image variable 'mask' needn't be initialized as
 * the function will take care of it.
 *
 * \param[in] res	required resolution of newly created image
 * \param[out]	mask	newly created image with a cell mask inside
 * \param[in] cellSize size of the cell mask that should be generated
 */
void RenderBlankCellMask(const i3d::Vector3d<float> &res,
								 i3d::Image3d<bool> &mask,
								 size_t cellSize,
								 float shape_variance = 16.0);

/**
 * Take an image a draw an generic ellipsoid inside.
 *
 * \param[in,out] img	prepared and allocated free image buffer
 * \param[in] center	position of center of ellipsoid
 * \param[in] radius size of semiaxes of ellipsoid
 * \param[in] angle_xy angle of rotation of ellipsoid in xy plane 
 * \param[in] angle_xz angle of rotation of ellipsoid in xz plane
 * \param[in] foregoundIntensity intensity/color of ellipsoid voxels
 */
template <class VOXEL> void RenderEllipsoid(
		i3d::Image3d<VOXEL> &img,
		const i3d::Vector3d<float> &center,
		const i3d::Vector3d<float> &radius,
		const float angle_xy,
		const float angle_xz,
		const VOXEL foregroundIntensity);

/**
 * Copy out the mask from the labeled image + remeber offset
 *
 * \param[in] img original image with labeled objects
 * \param[in] label selected label
 * \param[out] mask object with given label extracted from the original image
 */
template <class T> void GetLabelMask(const i3d::Image3d<T> &img,
												 T label,
												 i3d::Image3d<bool> &mask);
/**
 * Add an image 'imgProjected' to another image 'imgBase'
 * respecting the overlaps.
 *
 * \param[in,out] imgBase an image into which the projection should be stored
 * \param[in] imgProjected an image that should be projected
 */
void AddImageRespectingItsOffset(i3d::Image3d<bool> &imgBase, 
											const i3d::Image3d<bool> &imgProjected);

/**
 * Subtract an image 'imgProjected' from another image 'imgBase'
 * respecting the overlaps.
 *
 * \param[in,out] imgBase an image into which the projection should be stored
 * \param[in] imgProjected an image that should be projected
 */
void SubtractImageRespectingItsOffset(i3d::Image3d<bool> &imgBase, 
												  const i3d::Image3d<bool> &imgProjected);
#endif
