/* 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   Filter.hpp */
#ifndef _Filter_hpp
#define _Filter_hpp

#include<iterator>
#include<ImLib3D/Image3Dlinear.hpp>

//  #include<newmat/newmatap.h>
//  #include<newmat/newmatio.h>
//  using namespace NEWMAT;


// ****************** Filter ************************ 
//! Image3Df for filtering
/*! There are two kinds of filters: separable and not separable. The separable ones are defined as 3 vectors, a center and a size in the class "SeparableFilter". The nonseparable filters are directly inherited from the class "Image3Df". Later on there will be functions for converting between the to filters (as far as possible)
*/
// **************************************************
class Filter : public Image3Df
{
private:
//	Vect3Di center;
public:

	Filter(const Filter&  fi, const Vect3Di& centerpoint):Image3Df(fi)
	{properties.iCenter=new Vect3Di(centerpoint);}
	Filter(const Size3D & size, const Vect3Di& centerpoint):Image3Df(size)
	{properties.iCenter=new Vect3Di(centerpoint);}
	Filter(int _cubeSideSize, const Vect3Di& centerpoint):Image3Df(_cubeSideSize)
	{properties.iCenter=new Vect3Di(centerpoint);}
	Filter(int _width, int _height, int _depth, const Vect3Di centerpoint):Image3Df(_width, _height, _depth)
	{properties.iCenter=new Vect3Di(centerpoint);}
	Filter(const string& fname):Image3Df()
	{Streamable::ReadFromFile(fname);}

	Vect3Di GetCenter() const {return *properties.iCenter;}
	void SetCenter(const Vect3Di& centerpoint){*properties.iCenter = centerpoint;}
};


class SeparableFilter
{
protected:
	void Resize()
	{
		xcomponent.assign(size.width,0);
		ycomponent.assign(size.height,0);
		zcomponent.assign(size.depth,0);
	}
public:
	SeparableFilter(Size3D  _size,Vect3Di _iCenter):size(_size),iCenter(_iCenter){Resize();}
	SeparableFilter(Vect3Di _size,Vect3Di _iCenter):size(_size),iCenter(_iCenter){Resize();}
	vector<float> xcomponent;
	vector<float> ycomponent;
	vector<float> zcomponent;
	Size3D size;
	Vect3Di iCenter;
};


inline ostream& operator<<(ostream& s, SeparableFilter& filt)
{
	s << "xVect: " << endl;
	copy(filt.xcomponent.begin(),filt.xcomponent.end(),ostream_iterator<float>(s));
	s << endl;
	s << "yVect: " << endl;
	copy(filt.ycomponent.begin(),filt.ycomponent.end(),ostream_iterator<float>(s));
	s << endl;
	s << "zVect: " << endl;
	copy(filt.zcomponent.begin(),filt.zcomponent.end(),ostream_iterator<float>(s));
	s << endl;
  	s << "Center: " << filt.iCenter << endl;
  	return s;
}


#endif //_Filter_hpp
