/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: b2irange.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: kz $ $Date: 2005/11/02 13:55:11 $
 *
 *  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_B2IRANGE_HXX
#define _BGFX_RANGE_B2IRANGE_HXX

#ifndef _BGFX_POINT_B2IPOINT_HXX
#include <basegfx/point/b2ipoint.hxx>
#endif
#ifndef _BGFX_POINT_B2DPOINT_HXX
#include <basegfx/point/b2dpoint.hxx>
#endif
#ifndef _BGFX_TUPLE_B2ITUPLE_HXX
#include <basegfx/tuple/b2ituple.hxx>
#endif
#ifndef _BGFX_TUPLE_B2I64TUPLE_HXX
#include <basegfx/tuple/b2i64tuple.hxx>
#endif

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

#include <vector>


namespace basegfx
{
	class B2IRange
	{
	public:		
        typedef sal_Int32 		ValueType;
        typedef Int32Traits 	TraitsType;

		B2IRange() 
		{
		}
		
		explicit B2IRange(const B2ITuple& rTuple)
		:	maRangeX(rTuple.getX()),
			maRangeY(rTuple.getY())
		{
		}
		
		B2IRange(sal_Int32 x1,
                 sal_Int32 y1,
                 sal_Int32 x2,
                 sal_Int32 y2)
		:	maRangeX(x1),
			maRangeY(y1)
		{
			maRangeX.expand(x2);
			maRangeY.expand(y2);
		}
		
		B2IRange(const B2ITuple& rTuple1,
                 const B2ITuple& rTuple2)
		:	maRangeX(rTuple1.getX()),
			maRangeY(rTuple1.getY())
		{
            expand( rTuple2 );
		}
		
		B2IRange(const B2IRange& rRange)
		:	maRangeX(rRange.maRangeX),
			maRangeY(rRange.maRangeY)
		{
		}

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

		void reset() 
		{ 
			maRangeX.reset(); 
			maRangeY.reset(); 
		}

		bool operator==( const B2IRange& rRange ) const 
		{ 
			return (maRangeX == rRange.maRangeX 
				&& maRangeY == rRange.maRangeY); 
		}

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

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

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

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

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

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

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

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

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

		B2I64Tuple getRange() const
		{
			return B2I64Tuple(
				maRangeX.getRange(),
				maRangeY.getRange()
				);
		}
	
		B2DPoint getCenter() const
		{
			return B2DPoint(
				maRangeX.getCenter(),
				maRangeY.getCenter()
				);
		}
	
		bool isInside(const B2ITuple& rTuple) const
		{
			return (
				maRangeX.isInside(rTuple.getX()) 
				&& maRangeY.isInside(rTuple.getY())
				);
		}

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

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

		void expand(const B2ITuple& rTuple)
		{
			maRangeX.expand(rTuple.getX());
			maRangeY.expand(rTuple.getY());
		}

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

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

		void grow(sal_Int32 nValue)
		{
			maRangeX.grow(nValue); 
			maRangeY.grow(nValue); 
		}

    private:
        typedef ::basegfx::BasicRange< ValueType, TraitsType >	MyBasicRange;

		MyBasicRange		maRangeX;
		MyBasicRange		maRangeY;
	};

    /** Compute the set difference of the two given ranges

    	This method calculates the symmetric difference (aka XOR)
    	between the two given ranges, and returning the resulting
    	ranges. Thus, the result will contain all areas where one, but
    	not both ranges lie.

    	@param o_rResult
        Result vector. The up to four difference ranges are returned
        within this vector

        @param rFirst
        The first range

        @param rSecond
        The second range

        @return the input vector
     */
    ::std::vector< B2IRange >& computeSetDifference( ::std::vector< B2IRange >&	o_rResult,
                                                     const B2IRange&			rFirst,
                                                     const B2IRange&			rSecond );

} // end of namespace basegfx

#endif /* _BGFX_RANGE_B2IRANGE_HXX */
