using System;
using System.Collections.Generic;

namespace RenderHeads.Media.AVProVideo
{
	public class AudioOutputManager
	{
		private AudioOutputManager()
		{
			this._accessTrackers = new Dictionary<MediaPlayer, HashSet<AudioOutput>>();
			this._pcmData = new Dictionary<MediaPlayer, float[]>();
		}

		public static AudioOutputManager Instance
		{
			get
			{
				if (AudioOutputManager._instance == null)
				{
					AudioOutputManager._instance = new AudioOutputManager();
				}
				return AudioOutputManager._instance;
			}
		}

		public void RequestAudio(AudioOutput _outputComponent, MediaPlayer mediaPlayer, float[] data, int channelMask, int totalChannels, AudioOutput.AudioOutputMode audioOutputMode)
		{
			if (mediaPlayer == null || mediaPlayer.Control == null || !mediaPlayer.Control.IsPlaying())
			{
				return;
			}
			int numAudioChannels = mediaPlayer.Control.GetNumAudioChannels();
			if (numAudioChannels <= 0)
			{
				return;
			}
			if (!this._accessTrackers.ContainsKey(mediaPlayer))
			{
				this._accessTrackers[mediaPlayer] = new HashSet<AudioOutput>();
			}
			if (this._accessTrackers[mediaPlayer].Contains(_outputComponent) || this._accessTrackers[mediaPlayer].Count == 0 || this._pcmData[mediaPlayer] == null)
			{
				this._accessTrackers[mediaPlayer].Clear();
				int num = data.Length / totalChannels * numAudioChannels;
				this._pcmData[mediaPlayer] = new float[num];
				this.GrabAudio(mediaPlayer, this._pcmData[mediaPlayer], numAudioChannels);
				this._accessTrackers[mediaPlayer].Add(_outputComponent);
			}
			int num2 = Math.Min(data.Length / totalChannels, this._pcmData[mediaPlayer].Length / numAudioChannels);
			int num3 = 0;
			int num4 = 0;
			if (audioOutputMode == AudioOutput.AudioOutputMode.Multiple)
			{
				int num5 = Math.Min(numAudioChannels, totalChannels);
				for (int i = 0; i < num2; i++)
				{
					for (int j = 0; j < num5; j++)
					{
						if ((1 << j & channelMask) > 0)
						{
							data[num4 + j] = this._pcmData[mediaPlayer][num3 + j];
						}
					}
					num3 += numAudioChannels;
					num4 += totalChannels;
				}
			}
			else if (audioOutputMode == AudioOutput.AudioOutputMode.Single)
			{
				int num6 = 0;
				for (int k = 0; k < 8; k++)
				{
					if ((channelMask & 1 << k) > 0)
					{
						num6 = k;
						break;
					}
				}
				if (num6 < numAudioChannels)
				{
					for (int l = 0; l < num2; l++)
					{
						for (int m = 0; m < totalChannels; m++)
						{
							data[num4 + m] = this._pcmData[mediaPlayer][num3 + num6];
						}
						num3 += numAudioChannels;
						num4 += totalChannels;
					}
				}
			}
		}

		private void GrabAudio(MediaPlayer player, float[] data, int channels)
		{
			player.Control.GrabAudio(data, data.Length, channels);
		}

		private static AudioOutputManager _instance;

		private Dictionary<MediaPlayer, HashSet<AudioOutput>> _accessTrackers;

		private Dictionary<MediaPlayer, float[]> _pcmData;
	}
}
