/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: b3drange.hxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: rt $ $Date: 2005/09/07 20:33:39 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _BGFX_RANGE_B3DRANGE_HXX
#define _BGFX_RANGE_B3DRANGE_HXX

#ifndef _BGFX_VECTOR_B3DVECTOR_HXX
#include <basegfx/vector/b3dvector.hxx>
#endif
#ifndef _BGFX_POINT_B3DPOINT_HXX
#include <basegfx/point/b3dpoint.hxx>
#endif
#ifndef _BGFX_TUPLE_B3DTUPLE_HXX
#include <basegfx/tuple/b3dtuple.hxx>
#endif

#ifndef _BGFX_RANGE_BASICRANGE_HXX
#include <basegfx/range/basicrange.hxx>
#endif

namespace basegfx
{
	// predeclarations
	class B3IRange;

	class B3DRange
	{
        typedef ::basegfx::BasicRange< double, DoubleTraits >	MyBasicRange;

		MyBasicRange			maRangeX;
		MyBasicRange			maRangeY;
		MyBasicRange			maRangeZ;

	public:		
		B3DRange() 
		{
		}
		
		explicit B3DRange(const B3DTuple& rTuple)
		:	maRangeX(rTuple.getX()),
			maRangeY(rTuple.getY()),
			maRangeZ(rTuple.getZ())
		{
		}
		
		B3DRange(double x1,
                 double y1,
                 double z1,
                 double x2,
                 double y2,
                 double z2)
		:	maRangeX(x1),
			maRangeY(y1),
			maRangeZ(z1)
		{
			maRangeX.expand(x2);
			maRangeY.expand(y2);
			maRangeZ.expand(z2);
		}

		B3DRange(const B3DTuple& rTuple1,
                 const B3DTuple& rTuple2)
		:	maRangeX(rTuple1.getX()),
			maRangeY(rTuple1.getY()),
			maRangeZ(rTuple1.getZ())
		{
            expand(rTuple2);
		}
		
		B3DRange(const B3DRange& rRange)
		:	maRangeX(rRange.maRangeX),
			maRangeY(rRange.maRangeY),
			maRangeZ(rRange.maRangeZ)
		{
		}

		explicit B3DRange(const B3IRange& rRange);

		bool isEmpty() const 
		{
			return (
				maRangeX.isEmpty() 
				|| maRangeY.isEmpty() 
				|| maRangeZ.isEmpty()
				);
		}

		void reset() 
		{ 
			maRangeX.reset(); 
			maRangeY.reset(); 
			maRangeZ.reset(); 
		}
		
		bool operator==( const B3DRange& rRange ) const 
		{ 
			return (maRangeX == rRange.maRangeX 
				&& maRangeY == rRange.maRangeY
				&& maRangeZ == rRange.maRangeZ); 
		}

		bool operator!=( const B3DRange& rRange ) const 
		{ 
			return (maRangeX != rRange.maRangeX 
				|| maRangeY != rRange.maRangeY
				|| maRangeZ != rRange.maRangeZ); 
		}

		void operator=(const B3DRange& rRange) 
		{ 
			maRangeX = rRange.maRangeX; 
			maRangeY = rRange.maRangeY; 
			maRangeZ = rRange.maRangeZ; 
		}

		bool equal(const B3DRange& rRange) const
        {
			return (maRangeX.equal(rRange.maRangeX) 
                    && maRangeY.equal(rRange.maRangeY)
                    && maRangeZ.equal(rRange.maRangeZ)); 
        }

		bool equal(const B3DRange& rRange, const double& rfSmallValue) const
        {
			return (maRangeX.equal(rRange.maRangeX, rfSmallValue) 
                    && maRangeY.equal(rRange.maRangeY, rfSmallValue)
                    && maRangeZ.equal(rRange.maRangeZ, rfSmallValue)); 
        }

        double getMinX() const
        {
            return maRangeX.getMinimum();
        }

        double getMinY() const
        {
            return maRangeY.getMinimum();
        }

        double getMinZ() const
        {
            return maRangeZ.getMinimum();
        }

        double getMaxX() const
        {
            return maRangeX.getMaximum();
        }

        double getMaxY() const
        {
            return maRangeY.getMaximum();
        }

        double getMaxZ() const
        {
            return maRangeZ.getMaximum();
        }

        double getWidth() const
        {
            return maRangeX.getRange();
        }

        double getHeight() const
        {
            return maRangeY.getRange();
        }

        double getDepth() const
        {
            return maRangeZ.getRange();
        }

		B3DPoint getMinimum() const
		{
			return B3DPoint(
				maRangeX.getMinimum(),
				maRangeY.getMinimum(),
				maRangeZ.getMinimum()
				);
		}
		
		B3DPoint getMaximum() const
		{
			return B3DPoint(
				maRangeX.getMaximum(),
				maRangeY.getMaximum(),
				maRangeZ.getMaximum()
				);
		}

		B3DVector getRange() const
		{
			return B3DVector(
				maRangeX.getRange(),
				maRangeY.getRange(),
				maRangeZ.getRange()
				);
		}
	
		B3DPoint getCenter() const
		{
			return B3DPoint(
				maRangeX.getCenter(),
				maRangeY.getCenter(),
				maRangeZ.getCenter()
				);
		}
	
		double getCenterX() const
		{
			return maRangeX.getCenter();
		}
	
		double getCenterY() const
		{
			return maRangeY.getCenter();
		}
	
		double getCenterZ() const
		{
			return maRangeZ.getCenter();
		}
	
		bool isInside(const B3DTuple& rTuple) const
		{
			return (
				maRangeX.isInside(rTuple.getX()) 
				&& maRangeY.isInside(rTuple.getY())
				&& maRangeZ.isInside(rTuple.getZ())
				);
		}

		bool isInside(const B3DRange& rRange) const
		{
			return (
				maRangeX.isInside(rRange.maRangeX) 
				&& maRangeY.isInside(rRange.maRangeY)
				&& maRangeZ.isInside(rRange.maRangeZ)
				);
		}

		bool overlaps(const B3DRange& rRange) const
		{
			return (
				maRangeX.overlaps(rRange.maRangeX) 
				&& maRangeY.overlaps(rRange.maRangeY)
				&& maRangeZ.overlaps(rRange.maRangeZ)
				);
		}

		void expand(const B3DTuple& rTuple)
		{
			maRangeX.expand(rTuple.getX());
			maRangeY.expand(rTuple.getY());
			maRangeZ.expand(rTuple.getZ());
		}

		void expand(const B3DRange& rRange)
		{
			maRangeX.expand(rRange.maRangeX); 
			maRangeY.expand(rRange.maRangeY); 
			maRangeZ.expand(rRange.maRangeZ); 
		}

		void intersect(const B3DRange& rRange)
		{
			maRangeX.intersect(rRange.maRangeX); 
			maRangeY.intersect(rRange.maRangeY); 
			maRangeZ.intersect(rRange.maRangeZ); 
		}

		void grow(double fValue)
		{
			maRangeX.grow(fValue); 
			maRangeY.grow(fValue); 
			maRangeZ.grow(fValue); 
		}
	};

	/** Round double to nearest integer for 3D range

		@return the nearest integer for this range
	*/
	B3IRange fround(const B3DRange& rRange);
} // end of namespace basegfx


#endif /* _BGFX_RANGE_B3DRANGE_HXX */
