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

	Program:		Range Imaging Toolkit (RITK)
	Module:			ritkRImageIO.h
	Version:		$Revision: 1761 $
	Date:			$Date: 2011-09-23 17:25:41 +0200 (Fri, 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 RIMAGEIO_H__
#define RIMAGEIO_H__

#include <iostream>
#include <fstream>
#include "ritkRImageIOBase.h"

namespace ritk
{

/**	@ingroup	Common
 *	@class		RImageIO
 *	@author		Jakob Wasza
 *	@brief		IO functionality for RImage
 *
 *	@details
 *	This class provides IO functionality for the RImage base class. It will write the timestamp and the following range subimages 
 *	to the disk in the following order: \n
 *		TimeStamp of the frame (RImageBaseType::TimeStampType) \n
 *		RGB \n
 *		Range \n
 *		Flags \n
 *
 *	@sa RImageIOBase
 *	@sa	RImageIOManager
 *	@sa	RImageFileSource
 */
template<class TRImageBase>
class RImageIO: public RImageIOBase<TRImageBase>
{
public:
	/** @name Standard typedefs */
	//@{
	typedef RImageIO					Self;
	typedef RImageIOBase<TRImageBase>	Superclass;
	typedef itk::SmartPointer<Self>		Pointer;
	//@}

	/**	@name RImage typedefs */
	//@{
	typedef typename Superclass::RImageBaseType		RImageBaseType;
	typedef typename RImageBaseType::Pointer		RImageBasePointer;
	typedef typename RImageBaseType::ConstPointer	RImageBaseConstPointer;
	//@}

	/// RTTI
	itkTypeMacro(RImageIOBase, itk::LightProcessObject);

	/// Object creation
	itkNewMacro(Self);

	/** @name Set/Get the name of the file to be read/written. Will just access the member*/
	//@{
	virtual void SetFileName(std::string FileName);
	virtual std::string GetFileName();
	//@}

	/// Return the class name of the range image that this IO object can process
	const char* GetRImageClassName();

	/// Return the number of frames that are available
	unsigned int GetNumberOfFrames();

	/// The resolution of the frames
	void GetResolution(unsigned int *SX, unsigned int *SY);

	/// Write a frame
	void WriteFrame(RImageBaseConstPointer Frame);

	/// Read a frame
	RImageBasePointer ReadFrame(unsigned int FrameID);

	/// Close the input/output stream
	void Close();

protected:
	/// Constructor
	RImageIO();
	/// Destructor
	virtual ~RImageIO();

	/** @name	Struct for the header of an input file */
	//@{
	/// The struct
	typedef struct
	{
		/// The version of the format
		float FormatVersion; 
		/// The camera parameters
		CameraParameters CurrCameraParameters;
		/// The number of frames stored in this file
		unsigned int NumFrames; 
	} HeaderStruct;
	//@}

	/** @brief	Open the file and read the header
	 *	
	 *	After calling this method, the input filestream m_InputFile
	 *	will be ready to use and the header will be available
	 *	in the member m_CurrentHeader and the stream position will be
	 *	set to the beginning of the data section. \n
	 *	The method also takes care of the filename dirty flag. If a file was opened previously
	 *	it will be closed;
	 */
	void OpenFileStreamAndReadHeader();

	/// Helper function to initialize the time stamp vector
	void InitTimeStamps();


protected:
	/// Flag that indicates that the filename has changed
	bool m_FileNameDirtyFlag;
	/**	@name Filestream for the data */
	//@{
	std::ofstream m_OutputStream;
	std::ifstream m_InputStream;
	//@}
	/// End of header position
	unsigned long m_HeaderEndPos;
	/// The current index
	long m_Index;
	/// The current header
	HeaderStruct *m_CurrentHeader;

private:
	/// purposely not implemented
	RImageIO(Self&); 
	/// purposely not implemented
	void operator=(const Self&); 
};

/// Template instantiation
typedef RImageIO<RImageF2> RImageIOF2;

} // end namespace ritk

#endif // RIMAGEIO_H__
