/*
--------------------------------------------------------------------------------
This source file is part of SkyX.
Visit ---

Copyright (C) 2009 Xavier Verguín González <xavierverguin@hotmail.com>
                                           <xavyiy@gmail.com>

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
--------------------------------------------------------------------------------
*/

#ifndef _SkyX_VClouds_Ellipsoid_H_
#define _SkyX_VClouds_Ellipsoid_H_

#include "SkyxPrerequisites.h"
#include "SkyxDataManager.h"

namespace SkyX
{
	namespace VClouds
	{

	/*!
	Ellipsoid class

	x^2   y^2   z^2
	 /   + /   + /    = 1
	a^2   b^2   c^2
	*/
	class SkyXDllExport Ellipsoid
	{
	public:
	protected:
	private:
		int mA, mB, mC, mA2, mB2, mC2;	//!< Ellipsoid parameters
		int mX, mY, mZ;					//!< Position
		int mNx, mNy, mNz;				//!< Cells size
		Ogre::Real mDensity;			//!< Cloud density

	public:
		/*!
		Constructor
		@param a A constant
		@param b B constant
		@param c C constant
		@param nx X size
		@param ny Y size
		@param nz Z size
		@param x x Coord
		@param y y Coord
		@param z z Coord 
		@param Density Cloud density
		*/
		Ellipsoid(const int& a,  const int& b,  const int& c, 
			      const int& nx, const int& ny, const int& nz,
				  const int& x,  const int& y,  const int& z, 
				  const Ogre::Real& DynLibManager = 1.0f);

		/*!
		Destructor 
		*/
		~Ellipsoid();

		/*!
		Move the ellipsoid
		@param Ax x increment
		@param Ay y increment
		@param Az z increment
		*/
		void move(const int& Ax, const int& Ay, const int& Az);

		/*!
		Get probabilities at a point
		@param x x Coord
		@param y y Coord
		@param z z Coord 
		@return Probabilities (Hum, Ext, Act)
		*/
		const Ogre::Vector3 getProbabilities(const int& x, const int& y, const int& z) const;

		/*!
		Update probabilities
		@param c Cells
		@param nx X complexity
		@param ny Y complexity
		@param nz Z complexity
		*/
		void updateProbabilities(DataManager::Cell ***c, const int &nx, const int &ny, const int &nz);

		/*!
		Determines if the ellipsoid is out of the cells domain and needs to be removed
		*/
		const bool isOutOfCells() const;

		/*!
		Get dimensions
		@return Ellipsoid dimensions
		*/
		inline const Ogre::Vector3 getDimensions() const
		{
			return Ogre::Vector3(Ogre::Real(mA), Ogre::Real(mB), Ogre::Real(mC));
		}

		/*!
		Set dimensions
		@param Dimensions New dimensions
		*/
		void setDimensions(const Ogre::Vector3& Dimensions);
	protected:
	private:
		/*!
		Get length
		@param x x Coord
		@param y y Coord
		@param z z Coord
		@return [0,1] range where 0 is the center of the ellipsoid and 1 the superfice
		*/
		const float _getLength(const int& x, const int& y, const int& z) const;
	};

	}
}

#endif
