/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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.
*/

#ifndef OSG_BUFFERED_VALUE
#define OSG_BUFFERED_VALUE 1

#include <osg/DisplaySettings>
#include <vector>

namespace osg {

/** Simple buffered value array which is used for values that need to multibuffered on
  * one per graphics context basis.*/
  
template<class T>
class buffered_value
{
    public:
    
        inline buffered_value():
            _array(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0)
            {}

        buffered_value& operator = (const buffered_value& rhs)
        {
            _array = rhs._array;
            return *this;
        }
        
        inline void setAllElementsTo(const T& t) { std::fill(_array.begin(),_array.end(),t); }

        inline void clear() { _array.clear(); }

        inline bool empty() const { return _array.empty(); }

        inline unsigned int size() const { return _array.size(); }

        inline T& operator[] (unsigned int pos)
        {
            // automatically resize array.
            if (_array.size()<=pos)
                _array.resize(pos+1,0);

            return _array[pos];
        }

        inline T operator[] (unsigned int pos) const
        {
            // automatically resize array.
            if (_array.size()<=pos)
                _array.resize(pos+1,0);

            return _array[pos];
        }

    protected:
    
        mutable std::vector<T> _array;
};

template<class T>
class buffered_object
{
    public:
    
        inline buffered_object():
            _array(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts())
            {}

        buffered_object& operator = (const buffered_object& rhs)
        {
            _array = rhs._array;
            return *this;
        }

        inline void setAllElementsTo(const T& t) { std::fill(_array.begin(),_array.end(),t); }

        inline void clear() { _array.clear(); }

        inline bool empty() const { return _array.empty(); }

        inline unsigned int size() const { return _array.size(); }

        inline T& operator[] (unsigned int pos)
        {
            // automatically resize array.
            if (_array.size()<=pos)
                _array.resize(pos+1);

            return _array[pos];
        }

        inline const T& operator[] (unsigned int pos) const
        {
            // automatically resize array.
            if (_array.size()<=pos)
                _array.resize(pos+1);

            return _array[pos];
        }
        

    protected:
    
        mutable std::vector<T> _array;
};

}

#endif
