using System;
using Microsoft.DirectX.DirectSound;



using System.Windows.Forms;

namespace DarkStrideToolbox
{
	public class DSSoundWrapper
	{
		#region Properties
		private Microsoft.DirectX.DirectSound.Device m_oDirectSoundDevice = null;
		private bool m_bMuted = false;
		private double m_nVolume = 1;
		#endregion


		public DSSoundWrapper( System.Windows.Forms.Control oControl )
		{
			m_oDirectSoundDevice = new Microsoft.DirectX.DirectSound.Device();
			m_oDirectSoundDevice.SetCooperativeLevel( oControl,CooperativeLevel.Priority );

			DSResourceManager.GetGlobalInstance().OnCreateDevice( m_oDirectSoundDevice );
		}


		public int PlaySound( string sKey )
		{
			LoadedSound oLoadedSound = null;
			SecondaryBuffer oSoundBuffer = null;
			bool bFoundBuffer = false;
			int nVolume = 0;
			int nRetIndex = -1;

			
			oLoadedSound = (LoadedSound)DSResourceManager.GetGlobalInstance().GetLoadedSound( sKey );

			for( int i=0 ; i<oLoadedSound.m_oSoundInstances.Count ; i++ )
			{
				if( i >= oLoadedSound.m_oSoundInstances.Count ){ break; } 
				oSoundBuffer = (SecondaryBuffer)oLoadedSound.m_oSoundInstances[ i ];

				//Is this sound available?
				if( oSoundBuffer.Status.Playing == false )
				{
					nRetIndex = i;
					bFoundBuffer = true;
					break;
				}
			}

			//If we didn't find a buffer than we need to make a new one
			if( bFoundBuffer == false )
			{
				if( oLoadedSound.m_oSoundInstances.Count < oLoadedSound.nMaxSoundBuffers || oLoadedSound.nMaxSoundBuffers == -1 )
				{
					oLoadedSound.oStream.Seek( 0,System.IO.SeekOrigin.Begin ); 
					oSoundBuffer = new SecondaryBuffer( oLoadedSound.oStream,m_oDirectSoundDevice );
					oLoadedSound.m_oSoundInstances.Add( oSoundBuffer );

					nRetIndex = oLoadedSound.m_oSoundInstances.Count-1;
				}
				else
				{
					oSoundBuffer = null;
					nRetIndex = -1;
				}
			}

			if( oSoundBuffer != null )
			{
				nVolume = GetBufferVolume();
				oSoundBuffer.Volume = nVolume;
				oSoundBuffer.Play( 0,BufferPlayFlags.Default );				
			}

			return( nRetIndex );
		}
		
		public bool SoundIsStillPlaying( string sKey,int nIndex )
		{
			SecondaryBuffer oSoundBuffer = null;
			bool bRetVal = false;


			oSoundBuffer = DSResourceManager.GetGlobalInstance().GetSoundBuffer( sKey,nIndex );
			//Is this sound available?
			bRetVal = oSoundBuffer.Status.Playing;


			return( bRetVal );
		}
		public void StopPlayingSound( string sKey,int nIndex )
		{
			SecondaryBuffer oSoundBuffer = null;

			oSoundBuffer = DSResourceManager.GetGlobalInstance().GetSoundBuffer( sKey,nIndex );
			//Is this sound available?
			oSoundBuffer.Stop();
		}


		private void ResetVolumes()
		{
			DSSortedList oLoadedSounds = null;
			LoadedSound oLoadedSound = null;
			SecondaryBuffer oSoundBuffer = null;


			//Go through and shut down all the playing sounds
			oLoadedSounds = DSResourceManager.GetGlobalInstance().LoadedSounds;
			for( int i=0 ; i<oLoadedSounds.Count ; i++ )
			{
				oLoadedSound = (LoadedSound)oLoadedSounds.GetByIndex( i );

				for( int nSoundIndex=0 ; nSoundIndex<oLoadedSound.m_oSoundInstances.Count ; nSoundIndex++ )
				{
					oSoundBuffer = (SecondaryBuffer)oLoadedSound.m_oSoundInstances[ nSoundIndex ];
					if( oSoundBuffer.Status.Playing == true )
					{
						oSoundBuffer.Volume = GetBufferVolume();
					}
				}
			}
		}
		private int GetBufferVolume()
		{
			int nRetVal = 0;


			if( m_bMuted == true )
			{
				nRetVal = -10000;
			}
			else
			{
				nRetVal = (int)(  Math.Pow( m_nVolume,4 ) * 10000 - 10000 );
//Chris
if( nRetVal < -10000 || nRetVal > 10000 )
{
	MessageBox.Show( "xVolume comes out to be wrong..." + m_nVolume.ToString() + "," + nRetVal.ToString() );
	throw new System.Exception( "xVolume comes out to be wrong..." + m_nVolume.ToString() + "," + nRetVal.ToString() );
}
			}


			return( nRetVal );
		}



		#region Properties
		public Microsoft.DirectX.DirectSound.Device DirectSoundDevice
		{
			get
			{
				return( m_oDirectSoundDevice );
			}
		}
		public bool Muted
		{
			get
			{
				return( m_bMuted );
			}
			set
			{
				if( value != m_bMuted )
				{
					m_bMuted = value;
					ResetVolumes();
				}
			}
		}
		public double Volume
		{
			get
			{
				return( m_nVolume );
			}
			set
			{
				if( value != m_nVolume )
				{
					m_nVolume = value;
					ResetVolumes();
				}
			}
		}
		#endregion
	}
}
