/*======================================================================================

	Program:		Range Imaging Toolkit (RITK)
	Module:			ritkRImageIOManager.h
	Version:		$Revision: 1761 $
	Date:			$Date: 2011-09-23 17:25:41 +0200 (Fr, 23 Sep 2011) $

	Copyright (c) 2010-2011
	Pattern Recognition Lab, 
    University Erlangen-Nuremberg, Germany
    All rights reserved.

	This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
	See RITKCopyright.txt for more information.

	http://www5.informatik.uni-erlangen.de/research/software/ritk

========================================================================================*/

#ifndef RIMAGEIOMANAGER_H__
#define RIMAGEIOMANAGER_H__

#include "ritkCommon.h"

#include "ritkRImage.h"
#include "ritkRImageIOBase.h"

#include <utility>
#include <list>

namespace ritk
{

/**	@ingroup	Common
 *	@class		RImageIOManager
 *	@author		Jakob Wasza
 *	@brief		Class to manage objects that I/O range images
 *
 *	@details
 *	This class manages objects that read(input) or write(output) range images from/to a file. 
 *	However, these objects are NOT image sources (i.e. part of an image pipeline) but have to 
 *	be used by an image source: the file source determines the type (string identifier in the
 *	file's header) of the range image and requests the corresponding IO object from the RImageIOManager.
 *	Reading and/or writing of single frames is thus supported in a generic manner without the need
 *	to modify the image pipeline. This scheme also supports novel/custom file formats.
 *	@todo	Requested IO objects become invalid if the IO object is unregistered
 */
template<class RImageType>
class RImageIOManager
{
public:
	/**	@name Typedefs for the IO-objects */
	//@{
	typedef RImageIOBase<RImageType>			RImageIOBaseType;
	typedef typename RImageIOBaseType::Pointer	RImageIOBasePointer;
	//@}

	/// Singleton access
	static RImageIOManager& GetInstance();

	/** @name (Un)Register an IO object */
	//@{
	bool RegisterIOObject(RImageIOBaseType *Object); 
	bool UnRegisterIOObject(RImageIOBaseType *Object);
	//@}

	/**	@brief	Request an IO object to process the given range image type
	 *	@param	RImageIdentifier	The identifier of the range image
	 *	@return	A pointer to an IO object if the the range image type is registered, NULL otherwise
	 *
	 *	@details
	 */
	RImageIOBasePointer RequestIOObject(const char *RImageIdentifier);

protected:
	/**	@name Container that holds the RImage IO objects */
	//@{
	typedef std::list<RImageIOBasePointer> IOObjectContainer;
	IOObjectContainer m_IOObjects;
	//@}


private:
	/// Constructor 
	RImageIOManager();
	/// Destructor
	~RImageIOManager();
	/// Prevent copy-construction
	RImageIOManager(const RImageIOManager&);
	/// Prevent assignment
	RImageIOManager& operator=(const RImageIOManager&);
};

/** @name Template instantiations */
//@{
typedef RImageIOManager<RImageF2> RImageIOManagerF2;
//@}

} // end namespace ritk

#endif // RIMAGEIOMANAGER_H__