// -*- C++ -*-
#ifndef RIINTERVAL_H
#define RIINTERVAL_H
/* Copyright 1996 
 * Mon Mar 24 15:58:05 1997  Brian Edward Smits  (bes@burn.cs.utah.edu)
 * 
 * RiInterval.H
 * 
 *	
 * 
 * $Id: RiInterval.H,v 1.4 1997/09/19 01:40:08 bes Exp $ 
 * 
 */
#ifndef RICOMMON_H
#include <RiCommon.H>
#endif

#ifndef RIMATH_H
#include <RiMath.H>
#endif

/***************************************************************
CLASS
    RiInterval
     Single continuous interval in R1

DESCRIPTION
     An interval which can be used to represent a range of values.  Intervals can
     be unioned and intesected.  They also have the common math operation defined on
     them.

****************************************************************/

class RiInterval {
  public:
				// GROUP: Constructors
				////  Constructs an empty interval (max < min)
    RiInterval();
				//// Constructs an interval with zero width
    RiInterval(RiReal val);
				//// Constructs an interval. If min>max then the interval is empty.
    RiInterval(RiReal min, RiReal max);
				// GROUP: Accessors
				//// 
    RiReal Min()      const;
				////
    RiReal Max()      const;
				//// Returns true if interval is empty (min > max)
    bool   IsEmpty()  const;
				//// Size of the interval
    RiReal Width()    const;
				//// Center of the interval
    RiReal Center()   const;
				//// Returns true if value is in the interval
    bool   In(RiReal) const;
				// GROUP: Set operators
				////
    const  RiInterval &operator&=(const RiInterval &);
				////
    const  RiInterval &operator|=(const RiInterval &);
				// GROUP: Arithmetic operators
				////
    const RiInterval &operator+=(const RiInterval &);
				////
    const RiInterval &operator-=(const RiInterval &);
				////
    const RiInterval &operator*=(const RiInterval &);
				////
    const RiInterval &operator/=(RiReal f);
				////
    RiInterval        operator-() const;
    
  private:
    RiReal min;
    RiReal max;
};

/**********************************************************
// FUNCTION GROUP: Set operations
//// Intersection of two intervals
// ********************************************************/

inline RiInterval  operator&(const RiInterval &a, const RiInterval &b);

//// Union of two intervals
inline RiInterval  operator|(const RiInterval &a, const RiInterval &b);


/**********************************************************
// FUNCTION GROUP: Arithmetic operators
//
// ********************************************************/

////
RiInterval operator+(const RiInterval &lhs, const RiInterval &rhs);
////
RiInterval operator-(const RiInterval &lhs, const RiInterval &rhs);
////
RiInterval operator*(const RiInterval &lhs, const RiInterval &rhs);
////
RiInterval operator/(const RiInterval &lhs, RiReal f);


class ostream;

/**********************************************************
//   FUNCTION GROUP: Output operators
//// Output operator
// ********************************************************/

ostream 	  &operator<<(ostream &o, const RiInterval &a);





/**********************************************************
 * Inlined functions
 *
 **********************************************************/

inline RiInterval::RiInterval()
{
    min =  HUGE;
    max = -HUGE;
}

inline RiInterval::RiInterval(RiReal val)
{
    min = max = val;
}

inline RiInterval::RiInterval(RiReal mn, RiReal mx)
{
    min = mn; max = mx;
}

inline RiReal RiInterval::Min() const
{
    return min;
}

inline RiReal RiInterval::Max() const
{
    return max;
}

inline bool RiInterval::IsEmpty() const
{
    return (min > max);
}

inline RiReal RiInterval::Width() const
{
    return max - min;
}

inline RiReal RiInterval::Center() const
{
    return (max + min) * .5;
}

inline bool RiInterval::In(RiReal v) const
{
    return (v <= max && v >= min);
}

inline const RiInterval &RiInterval::operator&=(const RiInterval &a)
{
    min = RiMax(min, a.min);
    max = RiMin(max, a.max);
    return *this;
}
    
inline const RiInterval	&RiInterval::operator|=(const RiInterval &a)
{
    min = RiMin(min, a.min);
    max = RiMax(max, a.max);
    return *this;
}
    

inline RiInterval  operator&(const RiInterval &a, const RiInterval &b)
{
    return RiInterval(RiMax(a.Min(), b.Min()), RiMin(a.Max(), b.Max()));
}

inline RiInterval  operator|(const RiInterval &a, const RiInterval &b)
{
    return RiInterval(RiMin(a.Min(), b.Min()), RiMax(a.Max(), b.Max()));
}


#endif /* RIINTERVAL_H */

