Index: /trunk/nv/interface/program.hh
===================================================================
--- /trunk/nv/interface/program.hh	(revision 33)
+++ /trunk/nv/interface/program.hh	(revision 33)
@@ -0,0 +1,166 @@
+// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+/**
+ * @file program.hh
+ * @author Kornel Kisielewicz epyon@chaosforge.org
+ * @brief Program class
+ */
+
+#ifndef NV_PROGRAM_HH
+#define NV_PROGRAM_HH
+
+#include <unordered_map>
+#include <nv/common.hh>
+#include <nv/string.hh>
+#include <nv/types.hh>
+
+namespace nv
+{
+	class attribute
+	{
+	public:
+		attribute( 
+			const string& name,
+			int location,
+			type type,
+			int length ) :
+			m_name( name ),
+			m_location( location ),
+			m_type( type ),
+			m_length( length )
+		{
+
+		}
+
+		const string& get_name() const { return m_name; }
+		int get_location() const { return m_location; }
+		type get_type() const { return m_type; }
+		int get_length() const { return m_length; }
+
+	protected:
+		string m_name;
+		int    m_location;
+		type   m_type;
+		int    m_length;
+	};
+
+	class uniform_base
+	{
+	public: 
+		uniform_base( const string& name, type type, int location, int length ) 
+			: m_name( name ), m_type( type ), m_location(location), m_length( length ), m_dirty( true ) {}
+		type get_type() const { return m_type; }
+		int get_location() const { return m_location; }
+		int get_length() const { return m_length; }
+		bool is_dirty() const { return m_dirty; }
+		void clean() { m_dirty = false; }
+	protected:
+		string m_name;
+		type m_type;
+		int m_location;
+		int m_length;
+		bool m_dirty;
+	};
+
+	template< typename T >
+	class uniform : public uniform_base
+	{
+	public:
+		typename T value_type;
+
+		uniform( const string& name, int location, int length ) 
+			: uniform_base( name, type_to_enum< typename T >::type, location, length ), m_value()
+		{}
+
+		void set_value( const T& value ) 
+		{ 
+			if ( value != m_value )
+			{
+				m_value = value; 
+				m_dirty = true;
+			}
+		}
+
+		const T& get_value() { return m_value; }
+	protected:
+		T m_value;
+	};
+
+	typedef std::unordered_map< string, uniform_base* > uniform_map;
+	typedef std::unordered_map< string, attribute* >    attribute_map;
+
+	class program
+	{
+	public:
+		virtual void bind() = 0;
+		virtual void unbind() = 0;
+		virtual bool is_valid() const = 0;
+		
+		virtual ~program()
+		{
+			for ( attribute_map::iterator i = m_attribute_map.begin(); 
+				i != m_attribute_map.end(); ++i ) delete i->second;
+			for ( uniform_map::iterator i = m_uniform_map.begin(); 
+					i != m_uniform_map.end(); ++i ) delete i->second;
+		}
+		attribute* get_attribute( const string& name ) const
+		{
+			attribute_map::const_iterator i = m_attribute_map.find( name );
+			if ( i != m_attribute_map.end() )
+			{
+				return i->second;
+			}
+			return nullptr;
+		}
+
+		uniform_base* get_uniform( const string& name ) const
+		{
+			uniform_map::const_iterator i = m_uniform_map.find( name );
+			if ( i != m_uniform_map.end() )
+			{
+				return i->second;
+			}
+			return nullptr;
+		}
+
+		template < typename T >
+		void set_uniform( const string& name, const T& value )
+		{
+			uniform_base* base = get_uniform( name );
+			if ( base == nullptr || base->get_type() != type_to_enum<T>::type )
+			{
+				// signal error
+				return;
+			}
+			uniform<T>( base )->set_value( value );
+		}
+	protected:
+		uniform_base* create_uniform( type utype, const string& name, int location, int length )
+		{
+			switch( utype )
+			{
+			case FLOAT          : return new uniform< enum_to_type< FLOAT          >::type >( name, location, length );
+			case INT            : return new uniform< enum_to_type< INT            >::type >( name, location, length );
+			case FLOAT_VECTOR_2 : return new uniform< enum_to_type< FLOAT_VECTOR_2 >::type >( name, location, length );
+			case FLOAT_VECTOR_3 : return new uniform< enum_to_type< FLOAT_VECTOR_3 >::type >( name, location, length );
+			case FLOAT_VECTOR_4 : return new uniform< enum_to_type< FLOAT_VECTOR_4 >::type >( name, location, length );
+			case INT_VECTOR_2   : return new uniform< enum_to_type< INT_VECTOR_2   >::type >( name, location, length );
+			case INT_VECTOR_3   : return new uniform< enum_to_type< INT_VECTOR_3   >::type >( name, location, length );
+			case INT_VECTOR_4   : return new uniform< enum_to_type< INT_VECTOR_4   >::type >( name, location, length );
+			case FLOAT_MATRIX_2 : return new uniform< enum_to_type< FLOAT_MATRIX_2 >::type >( name, location, length );
+			case FLOAT_MATRIX_3 : return new uniform< enum_to_type< FLOAT_MATRIX_3 >::type >( name, location, length );
+			case FLOAT_MATRIX_4 : return new uniform< enum_to_type< FLOAT_MATRIX_4 >::type >( name, location, length );
+			default     : return nullptr;
+			}
+		}
+
+		attribute_map m_attribute_map;
+		uniform_map   m_uniform_map;
+	};
+
+} // namespace nv
+
+#endif // NV_PROGRAM_HH
