/*****************************************************************************
 * $LastChangedDate: 2009-12-28 02:30:09 -0500 (Mon, 28 Dec 2009) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Percent class.
 *//*
 * LEGAL:   COPYRIGHT (C) 2004 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#ifndef BASE_PERCENT_HH
#define BASE_PERCENT_HH 1

namespace base {

////////////////////////////////////////////////////////////////////////////////
/// @brief Percent
///
/// operator+=() clamps for conveniently incrementing
/// (rather than requiring every caller to duplicate clamp code).
/// Assigning an invalid Percent is never clamped: that's always an error.
///
class Percent
{
COPYABLE(Percent)
public:
    Percent( void ) : mPercent(0) { }
    Percent( uint percent ) { Set( percent ); }  // not explicit

    /// Assigning an out-of-range percent is an error.
    void operator=( uint percent ) { Set( percent ); }
    operator uint() const { ASSERT( mPercent <= 100 ); return mPercent; }

    /// These clamp.
    void operator+=( int n ) { SetClamp( int(mPercent) + int(n) ); }
    void operator-=( int n ) { SetClamp( int(mPercent) - int(n) ); }

private:
    /// Set() is strict: it will fail if percent is out-of-range.
    void Set( uint percent )
    {
    ASSERT( percent <= 100 );
        mPercent = percent;
    }

    /// SetClamp() is lenient: it will clamp out-of-range values.
    void SetClamp( int percent )
    {
        if ( percent < 0 )
            mPercent = 0;
        else if ( percent > 100 )
            mPercent = 100;
        else
            mPercent = uint(percent);
    }

private:
    uint    mPercent;
};

} // namespace base

#endif // BASE_PERCENT_HH
