#ifndef _gpuCacheConfig_h_
#define _gpuCacheConfig_h_
#include <stddef.h>
#include <maya/MColor.h>
#include <maya/MString.h>
#include <maya/MHWGeometry.h>
#include <memory>
#include <functional>
namespace std {
    template <>
    struct hash<MHWRender::MGeometry::Semantic> {
            return std::hash<int>()(k);
        }
    };
    template <>
    struct hash<MHWRender::MGeometry::DataType> {
            return std::hash<int>()(k);
        }
    };
}
namespace GPUCache {
template<typename T>
inline void hash_combine(size_t& seed, const T& v)
{
    std::hash<T> hasher;
    seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
template <class It>
inline std::size_t hash_range(It first, It last)
{
    std::size_t seed = 0;
    for (; first != last; ++first)
    {
        hash_combine(seed, *first);
    }
    return seed;
}
template<class T>
class shared_array : public std::shared_ptr<T>
{
    typedef T element_type;
public:
    explicit shared_array(T* p = 0)
        :std::shared_ptr<T>(p, std::default_delete<T[]>())
    {
    }
    void reset(T* p = 0)
    {
        std::shared_ptr<T>::reset(p, std::default_delete<T[]>());
    }
    element_type& operator[](size_t _Idx) const
    {   
        return (std::shared_ptr<T>::get()[_Idx]);
    }
};
class Config
{
public: 
    static void refresh();
    
    
    static const MColor kDefaultGrayColor;
 
    static const MColor kDefaultTransparency;
 
    
    static const unsigned short kLineStippleShortDashed;
    static const unsigned short kLineStippleDotted;
    
    static const MString kDisplayFilter;
 
    
    enum VP2OverrideAPI {
        kMPxSubSceneOverride,
        kMPxDrawOverride
    };
    
    
    static VP2OverrideAPI vp2OverrideAPI();
    
    
    
    
    
    
    static bool isIgnoringUVs();
    
    
    
    
    
    
    static size_t minVertsForVBOs();
    
    
    
    
    
    
    static size_t maxVBOCount();
    
    
    
    
    
    
    
    
    static size_t maxVBOSize();
    
    
    
    
    
    
    
    static bool useVertexArrayWhenVRAMIsLow();
    
    
    
    
    
    static bool useVertexArrayForGLPicking();
    
    
    
    
    static bool useGLPrimitivesInsteadOfVA();
    
    
    
    
    
    static bool emulateTwoSidedLighting();
    
    
    
    
    
    static size_t openGLPickingWireframeThreshold();
    static size_t openGLPickingSurfaceThreshold();
    
    
    
    
    static bool backgroundReading();
    
    
    
    static size_t backgroundReadingRefresh();
    
    
    
    
    
    
    static bool useHardwareInstancing();
    
    
    static size_t hardwareInstancingThreshold();
    
    
    static void initialize();
private:
    static bool sInitialized;
    static size_t sDefaultVP2OverrideAPI;
    static bool sDefaultIsIgnoringUVs;
    static size_t sDefaultMinVertsForVBOs;
    static size_t sDefaultMaxVBOCount;
    static size_t sDefaultMaxVBOSize;
    static bool sDefaultUseVertexArrayWhenVRAMIsLow;
    static bool sDefaultUseVertexArrayForGLPicking;
    static bool sDefaultUseGLPrimitivesInsteadOfVA;
    static bool sDefaultEmulateTwoSidedLighting;
    static size_t sDefaultOpenGLPickingWireframeThreshold;
    static size_t sDefaultOpenGLPickingSurfaceThreshold;
    static bool sDefaultBackgroundReading;
    static size_t sDefaultBackgroundReadingRefresh;
    static bool sDefaultUseHardwareInstancing;
    static size_t sDefaultHardwareInstancingThreshold;
    static size_t sVP2OverrideAPI;
    static bool sIsIgnoringUVs;
    static size_t sMinVertsForVBOs;
    static size_t sMaxVBOCount;
    static size_t sMaxVBOSize;
    static bool sUseVertexArrayWhenVRAMIsLow;
    static bool sUseVertexArrayForGLPicking;
    static bool sUseGLPrimitivesInsteadOfVA;
    static bool sEmulateTwoSidedLighting;
    static size_t sOpenGLPickingWireframeThreshold;
    static size_t sOpenGLPickingSurfaceThreshold;
    static bool sBackgroundReading;
    static size_t sBackgroundReadingRefresh;
    static bool sUseHardwareInstancing;
    static size_t sHardwareInstancingThreshold;
};
} 
#endif