/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * 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 
 * OpenSceneGraph Public License for more details.
*/
//osgParticle - Copyright (C) 2002 Marco Jez

#ifndef OSGPARTICLE_RANGE
#define OSGPARTICLE_RANGE 1

// include Export simply to disable Visual Studio silly warnings.
#include <osgParticle/Export>

#include <stdlib.h>

#include <osg/Vec2>
#include <osg/Vec3>
#include <osg/Vec4>

namespace osgParticle
{

    /**
        A simple struct template useful to store ranges of values as min/max pairs.
        This struct template helps storing min/max ranges for values of any kind; class <CODE>ValueType</CODE> is
        the type of values to be stored, and it must support operations <CODE>ValueType + ValueType</CODE>, <CODE>ValueType - ValueType</CODE>, 
        and <CODE>ValueType * float</CODE>, otherwise the <CODE>geValueTyperandom()</CODE> method will not compile.
        This struct could be extended to customize the random number generator (now it uses only 
        <CODE>std::rand()</CODE>).
    */
    template<class ValueType> struct range
    {
    
        /// Lower bound.
        ValueType minimum;
        
        /// Higher bound.
        ValueType maximum;

        /// Construct the object by calling default constructors for min and max.
        range() : minimum(ValueType()), maximum(ValueType()) {}
        
        /// Construct and initialize min and max directly.
        range(const ValueType& mn, const ValueType& mx) : minimum(mn), maximum(mx) {}

        /// Set min and max.
        void set(const ValueType& mn, const ValueType& mx) { minimum = mn; maximum = mx; }

        /// Get a random value between min and max.
        ValueType get_random() const
        {
            return minimum + (maximum - minimum) * rand() / RAND_MAX;
        }

        /// Get a random square root value between min and max.
        ValueType get_random_sqrtf() const
        {
            return minimum + (maximum - minimum) * sqrtf( static_cast<float>(rand()) / static_cast<float>(RAND_MAX) );
        }
        
        ValueType mid() const
        {
            return (minimum+maximum)*0.5f;
        }

    };

    /// Range of floats.
    typedef range<float> rangef;
    
    /// Range of osg::Vec2s.
    typedef range<osg::Vec2> rangev2;
    
    /// Range of osg::Vec3s.
    typedef range<osg::Vec3> rangev3;
    
    /// Range of osg::Vec4s.
    typedef range<osg::Vec4> rangev4;

}

#endif
