/* ImLib3D
 * Copyright (c) 2001, ULP-IPB Strasbourg.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 * 
 * 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 the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
/*!  \file   Image3DSet.hpp */

#ifndef _Image3DSet_hpp
#define _Image3DSet_hpp

#include<ImLib3D/Image3D.hpp>
#include<vector>
#include<string>

//! A class for handling a set of images
/*!
  The image set can be be disk resident, in which case images are read into memory
  or flushed back to disk as needed.  <BR>
 */
template <class ImageType>
class Image3DSet
{
public:
	Image3DSet(const vector<string> & _fileNames,bool _fileIsReadOnly=true,bool _isMemOnly=false);
	Image3DSet(bool _fileIsReadOnly=true,bool _isMemOnly=false);
	Image3DSet(const Image3DSet<ImageType>& _other); 
	virtual ~Image3DSet();
public:
	typedef typename ImageType::value_type Im3DValue;
	typedef typename ImageType::value_type value_type;
	enum ImageStatus
	{
		ON_FILE,
		IN_MEM
	};

protected:
	vector<string>      fileNames;
	vector<ImageType*>  images;
	vector<ImageStatus> status;
	int  nbImages;
	bool fileIsReadOnly;
	bool isMemOnly;

	int lruGap;
	//! Start of lru timing
	double startTime;
	//! last acces time , for lru
	vector<double> lastTimeUsed;

	void DeleteImages();
	void FlushToDisk(int i);
	void LoadImage(int i);
	void LoadAllImages();
	void FlushAllToDisk();
	int LeastRecentlyUsed();
	bool Fits(int i){return true;/*FIXME*/}
public:
	//! erases all images from image set
	virtual void Clear(bool _fileIsReadOnly=true,bool _isMemOnly=false);
	//! get a reference to an image from the image set
	ImageType &operator[](int position){return GetImage(position);}
	ImageType &GetImage(int position);
	string GetFilename(int position){return fileNames[position];}
	bool   IsEmpty() const {return nbImages==0;}
	int Size() const {return nbImages;}
	Im3DValue &operator()(int x,int y,int z,int pos){return GetImage(pos)(x,y,z);}
	Im3DValue Value(int x,int y,int z,int pos){return GetImage(pos)(x,y,z);}
	int AddImage(ImageType *image,const string &fileName="");
	int GetPosition(const string &filename);
	ImageType* RemoveImage(const string &filename);
	ImageType* RemoveImage(int position);
	bool IsAllSameSize();
	vector<string> ImagesThatAreAlike();
	vector<string> GetFileList(){return fileNames;}
	friend ostream& operator<<<>(ostream& s, const Image3DSet<ImageType>& set);
};

typedef Image3DSet<Image3Df> Image3DfSet;
#include<ImLib3D/Image3DSet.hxx>

#endif //_Image3DSet_hpp
