/*=========================================================================

  Copyright (c) Kitware, Inc.
  All rights reserved.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkNew.h"
#include "vtkWindows.h"
#include <xaudio2.h>
#include <x3daudio.h>

class vtkFFMPEGVideoSource;
struct vtkFFMPEGVideoSourceAudioCallbackData;
struct StreamingVoiceContext;
class vtkMutexLock;

class mvAudioHandler
{
public:
  mvAudioHandler();
  ~mvAudioHandler();

  // setup and start up audio playback of a file
  void SetupAudioPlayback(vtkFFMPEGVideoSource *);

  // this sets the current up and front vectors for the lister's head
  void SetListenerPose(double *up, double *front);

  // this sets the front and up vectors for the audio stream
  // that is being played
  void SetAudioPose(double *up, double *front);

  // set the volume level 0.0 to 1.0 for the application
  static void SetVolumeLevel(double vol);

protected:
  // recompute the audio settings for new head position
  void UpdatePositions();

  void AudioCallback(vtkFFMPEGVideoSourceAudioCallbackData const &acbd);

  vtkNew<vtkMutexLock> ListenerUpdateMutex;

  IXAudio2* XAudio2;
  IXAudio2MasteringVoice* MasterVoice;
  IXAudio2SourceVoice* SourceVoice;

  X3DAUDIO_HANDLE X3DInstance;
  X3DAUDIO_LISTENER Listener;
  X3DAUDIO_EMITTER Emitter = {0};
  X3DAUDIO_DSP_SETTINGS DSPSettings = {0};
  FLOAT32 *DSPMatrix;

  double AudioUp[3];
  double AudioFront[3];
  double AudioRight[3];

  bool SphericalAudio;

  int CurrentBufferIndex;
  StreamingVoiceContext *Context;

  const int NumberOfOutputChannels = 2;

  // 4 megabytes, seems to handle most cases
  const int AudioBufferSize = 4000000;
  BYTE AudioBuffer[4000000];
  int MaximumBufferCount;
  int MaximumBufferSize;
};
