Index: trunk/nv/fmod/fmod_audio.hh
===================================================================
--- trunk/nv/fmod/fmod_audio.hh	(revision 328)
+++ trunk/nv/fmod/fmod_audio.hh	(revision 329)
@@ -23,20 +23,7 @@
 		class audio;
 
-		class sound : public nv::sound
+		struct sound_info
 		{
-		private:
-			friend class nv::fmod::audio;
-			sound( void* data ) : m_sound( data ) {}
-		public:
-			virtual ~sound();
-		private:
-			void* m_sound;
-		};
-
-		class channel : public nv::channel
-		{
-		private:
-			friend class nv::fmod::audio;
-			virtual ~channel() {}
+			void* fmod_sound;
 		};
 
@@ -45,9 +32,11 @@
 		public:
 			audio();
-			virtual nv::channel* play_sound( nv::sound* a_sound );
-			virtual nv::sound* load_sound( const std::string& a_path );
+			virtual channel play_sound( sound a_sound );
+			virtual sound load_sound( const std::string& a_path );
+			virtual void release( sound a_sound );
 			virtual void update();
 			virtual ~audio();
 		private:
+			entity_store< sound_info, sound >     m_sounds;
 			void* m_system;
 		};
Index: trunk/nv/interface/audio.hh
===================================================================
--- trunk/nv/interface/audio.hh	(revision 328)
+++ trunk/nv/interface/audio.hh	(revision 329)
@@ -15,24 +15,21 @@
 #include <nv/core/common.hh>
 #include <nv/core/math.hh>
+#include <nv/core/handle.hh>
 
 namespace nv
 {
-	class sound
-	{
-	public:
-		virtual ~sound() {}
-	};
 
-	class channel
-	{
-	public:
-		virtual ~channel() {}
-	};
-
+	struct sound_tag {};
+	struct channel_tag {};
+	typedef handle< uint32, 16, 16, sound_tag >       sound;
+	typedef handle< uint32, 16, 16, channel_tag >     channel;
+	
 	class audio
 	{
 	public:
-		virtual channel* play_sound( sound* a_sound ) = 0;
-		virtual sound* load_sound( const std::string& a_path ) = 0;
+		virtual channel play_sound( sound a_sound ) = 0;
+		// temporary - use streams later
+		virtual sound load_sound( const std::string& a_path ) = 0;
+		virtual void release( sound a_sound ) = 0;
 		virtual void update() {}
 		virtual ~audio() {}
Index: trunk/nv/sdl/sdl_audio.hh
===================================================================
--- trunk/nv/sdl/sdl_audio.hh	(revision 328)
+++ trunk/nv/sdl/sdl_audio.hh	(revision 329)
@@ -21,22 +21,7 @@
 	namespace sdl
 	{
-		class audio;
-
-		class sound : public nv::sound
+		struct sound_info
 		{
-		private:
-			friend class nv::sdl::audio;
-			sound( void* data ) : m_sound( data ) {}
-		public:
-			virtual ~sound();
-		private:
-			void* m_sound;
-		};
-
-		class channel : public nv::channel
-		{
-		private:
-			friend class nv::sdl::audio;
-			virtual ~channel() {}
+			void* sdl_sound;
 		};
 
@@ -45,8 +30,11 @@
 		public:
 			audio();
-			virtual nv::channel* play_sound( nv::sound* a_sound );
-			virtual nv::sound* load_sound( const std::string& a_path );
+			virtual channel play_sound( sound a_sound );
+			virtual sound load_sound( const std::string& a_path );
+			virtual void release( sound a_sound );
 			virtual void update();
 			virtual ~audio();
+		private:
+			entity_store< sound_info, sound >     m_sounds;
 		};
 	}
Index: trunk/src/fmod/fmod_audio.cc
===================================================================
--- trunk/src/fmod/fmod_audio.cc	(revision 328)
+++ trunk/src/fmod/fmod_audio.cc	(revision 329)
@@ -37,27 +37,44 @@
 
 
-nv::channel* fmod::audio::play_sound( nv::sound* a_sound )
+nv::channel fmod::audio::play_sound( nv::sound a_sound )
 {
-	FMOD_SYSTEM* system = (FMOD_SYSTEM*)m_system;
-	FMOD_SOUND* sample  = (FMOD_SOUND*)( down_cast< fmod::sound >( a_sound )->m_sound );
-	FMOD_RESULT result  = FMOD_System_PlaySound( system, FMOD_CHANNEL_FREE, sample, false, 0 );
-	if ( result != FMOD_OK )
+	sound_info* info = m_sounds.get( a_sound );
+	if ( info )
 	{
-		NV_LOG( LOG_WARNING, "FMOD failed to play sound -- " << FMOD_ErrorString( result ) );
+		FMOD_SYSTEM* system = (FMOD_SYSTEM*)m_system;
+		FMOD_SOUND* sample  = (FMOD_SOUND*)( info->fmod_sound );
+		FMOD_RESULT result  = FMOD_System_PlaySound( system, FMOD_CHANNEL_FREE, sample, false, 0 );
+		if ( result != FMOD_OK )
+		{
+			NV_LOG( LOG_WARNING, "FMOD failed to play sound -- " << FMOD_ErrorString( result ) );
+		}
 	}
-	return nullptr;
+	return channel();
 }
 
-nv::sound* fmod::audio::load_sound( const std::string& a_path )
+nv::sound fmod::audio::load_sound( const std::string& a_path )
 {
 	FMOD_SYSTEM* system = (FMOD_SYSTEM*)m_system;
 	FMOD_SOUND* sample;
-	FMOD_RESULT result = FMOD_System_CreateSound( system, a_path.c_str(), FMOD_DEFAULT, 0, &sample );
-	if ( result != FMOD_OK )
+	FMOD_RESULT fm_result = FMOD_System_CreateSound( system, a_path.c_str(), FMOD_DEFAULT, 0, &sample );
+	if ( fm_result != FMOD_OK )
 	{
-		NV_LOG( LOG_ERROR, "FMOD failed to load sample '" << a_path << "' -- " << FMOD_ErrorString( result ) );
-		return nullptr;
+		NV_LOG( LOG_ERROR, "FMOD failed to load sample '" << a_path << "' -- " << FMOD_ErrorString( fm_result ) );
+		return sound();
 	}
-	return new fmod::sound( sample );
+	sound result = m_sounds.create();
+	sound_info* info = m_sounds.get( result );
+	info->fmod_sound = sample;
+	return result;
+}
+
+void nv::fmod::audio::release( sound a_sound )
+{
+	sound_info* info = m_sounds.get( a_sound );
+	if ( info )
+	{
+		FMOD_Sound_Release( (FMOD_SOUND*)info->fmod_sound );
+		m_sounds.destroy( a_sound );
+	}
 }
 
@@ -70,9 +87,7 @@
 fmod::audio::~audio()
 {
+	while ( m_sounds.size() > 0 )
+		release( m_sounds.get_handle(0) );
 	FMOD_System_Release( (FMOD_SYSTEM*)m_system );
 }
 
-fmod::sound::~sound()
-{
-	FMOD_Sound_Release( (FMOD_SOUND*)m_sound );
-}
Index: trunk/src/sdl/sdl_audio.cc
===================================================================
--- trunk/src/sdl/sdl_audio.cc	(revision 328)
+++ trunk/src/sdl/sdl_audio.cc	(revision 329)
@@ -32,14 +32,18 @@
 
 
-nv::channel* sdl::audio::play_sound( nv::sound* a_sound )
+nv::channel sdl::audio::play_sound( sound a_sound )
 {
-	if ( Mix_PlayChannel(-1, (Mix_Chunk*)( down_cast< sdl::sound >( a_sound )->m_sound), 0) == -1 )
+	sound_info* info = m_sounds.get( a_sound );
+	if ( info )
 	{
-		NV_LOG( LOG_WARNING, "SDL_mixer failed to play -- " << Mix_GetError() );
+		if ( Mix_PlayChannel(-1, (Mix_Chunk*)( info->sdl_sound), 0) == -1 )
+		{
+			NV_LOG( LOG_WARNING, "SDL_mixer failed to play -- " << Mix_GetError() );
+		}
 	}
-	return nullptr;
+	return channel();
 }
 
-nv::sound* nv::sdl::audio::load_sound( const std::string& a_path )
+nv::sound nv::sdl::audio::load_sound( const std::string& a_path )
 {
 	// TODO: this is a really wierd error - if we remove this check, all hell gets loose
@@ -52,7 +56,10 @@
 	{
 		NV_LOG( LOG_ERROR, "SDL_mixer failed to load sample '" << a_path << "' -- " << Mix_GetError() );
-		return nullptr;
+		return sound();
 	}
-	return new sdl::sound( sample );
+	sound result = m_sounds.create();
+	sound_info* info = m_sounds.get( result );
+	info->sdl_sound = sample;
+	return result;
 }
 
@@ -64,4 +71,6 @@
 nv::sdl::audio::~audio()
 {
+	while ( m_sounds.size() > 0 )
+		release( m_sounds.get_handle(0) );
 	Mix_CloseAudio();
 	// TODO: should we do it here?
@@ -69,6 +78,12 @@
 }
 
-nv::sdl::sound::~sound()
+void nv::sdl::audio::release( sound a_sound )
 {
-	Mix_FreeChunk( (Mix_Chunk*)m_sound );
+	sound_info* info = m_sounds.get( a_sound );
+	if ( info )
+	{
+		Mix_FreeChunk( (Mix_Chunk*)info->sdl_sound );
+		m_sounds.destroy( a_sound );
+	}
 }
+
Index: trunk/tests/gui_test/test.style.lua
===================================================================
--- trunk/tests/gui_test/test.style.lua	(revision 328)
+++ trunk/tests/gui_test/test.style.lua	(revision 329)
@@ -9,4 +9,9 @@
 		--border_color = { 0.2, 0.2, 0.4, 1.0 },
 		skin = "button.png",
+
+		[":hover"] = {
+			text_color = { 1.0, 1.0, 1.0, 1.0 },
+		}
+
 	}
 }
