/*********************************************************************
 * This file is part of the PRAPI library.
 *
 * Copyright (C) 2001 Topi Mäenpää and Jaakko Viertola
 * All rights reserved.
 *
 * This program is free software. You can redistribute and/or modify
 * it under the terms of the free software licence found in the
 * accompanying file "COPYING". The licence terms must always be
 * redistributed with this source file. The above copyright notice
 * must be reproduced in all modified and unmodified copies of this
 * source file.
 *
 * $Revision: 1.7 $
 *********************************************************************/

#ifndef _CONVOLUTIONMASK_H
#define _CONVOLUTIONMASK_H

#include "graphics/Point.h"
#include <Matrix.h>

namespace prapi
{
	/**
	 * ConvolutionMask is a matrix that can be used for image
	 * convolution operations (filtering). In addition to the data, it
	 * contains coordinates for center point and a divisor.
	 **/
	template <class T> class ConvolutionMask : public util::Matrix<T>
	{
	public:
		/**
		 * All constructors will initially set the origin of the mask to
		 * its center.
		 **/
		ConvolutionMask(int size=1) : util::Matrix<T>(size), _pntOrigin(_iColumns >> 1, _iRows >> 1), _divisor(1) {}
		/**
		 * Constructor which makes empty mask.
		 **/
		ConvolutionMask(int rows, int columns) : util::Matrix<T>(rows,columns), _pntOrigin(_iColumns >> 1, _iRows >> 1), _divisor(1) {}
		/**
		 * Constructor which makes empty mask.
		 **/
		ConvolutionMask(const util::Matrix<T>& mat) : util::Matrix<T>(mat), _pntOrigin(_iColumns >> 1, _iRows >> 1), _divisor(1) {}
		/**
		 * The copy constructor.
		 **/
		ConvolutionMask(const ConvolutionMask& other) : util::Matrix<T>(other), _pntOrigin(other._pntOrigin), _divisor(other._divisor) {}
		/**
		 * Constructor which takes the size of mask and the data array.
		 **/
		ConvolutionMask(int rows, int columns, T* initialData) :
			util::Matrix<T>(rows,columns,initialData), _pntOrigin(_iColumns >> 1, _iRows >> 1), _divisor(1) {}
		
		/**
		 * Substitution operator.
		 **/
		ConvolutionMask& operator= (const ConvolutionMask& other);
		/**
		 * Set the value for all the entries of ConvolutionMask.
		 **/
		ConvolutionMask& operator= (const T value) { util::Matrix<T>::operator=(value); return *this; }
		
		/**
		 * Get the origin of the mask. This is needed only if the mask is
		 * not symmetric.
		 **/
		graphics::Point<int> getOrigin(void) const { return _pntOrigin; }
		/**
		 * Get the origin of the mask. This is needed only if the mask is
		 * not symmetric.
		 **/
		graphics::Point<int>& origin(void) { return _pntOrigin; }
		/**
		 * Set the Origin.
		 **/
		void setOrigin(const graphics::Point<int>& origin) { _pntOrigin = origin; }

		/**
		 * Get the divisor. When convolving an image, the convolution
		 * result is divided by this value. It is thus possible to use
		 * fractions in integer-valued convolutions also. The default
		 * value is 1.
		 **/
		T getDivisor(void) const { return _divisor; }
		/**
		 * Get the divisor reference.
		 **/
		T& divisor(void) { return _divisor; }
		/**
		 * Set the divisor.
		 **/
		void setDivisor(T divisor) { _divisor = divisor; }
		
	private:
		graphics::Point<int> _pntOrigin;
		T _divisor;
	};

	typedef ConvolutionMask<int> IntegerConvolutionMask;
	typedef ConvolutionMask<float> FloatConvolutionMask;
	typedef ConvolutionMask<double> DoubleConvolutionMask;


	template <class T> ConvolutionMask<T>& ConvolutionMask<T>::operator= (const ConvolutionMask<T>& other)
	{
		util::Matrix<T>::operator=(other);
		_pntOrigin = other._pntOrigin;
		_divisor = other._divisor;
		return *this;
	}
}

#endif
