#include "VolumeController.h"
#include <windows.h>
#include <combaseapi.h>
#include <AvReceiver.h>
#include <initguid.h>
#include <Functiondiscoverykeys_devpkey.h>

CVolumeController::CVolumeController(QObject *parent) : QObject(parent)
{
    mDeviceEnumerator = NULL;
    mAudioDevice = NULL;
    mEndpointVolume = 0;
    mProgramPtr = 0;
    mVolumeControllerActive = false;
}

CVolumeController::~CVolumeController()
{
    if(mVolumeControllerActive == true)
    {
        if(mEndpointVolume != NULL)
        {
            mEndpointVolume->UnregisterControlChangeNotify(this);
            mEndpointVolume->Release();
        }
        if(mAudioDevice != NULL)
            mAudioDevice->Release();
        if(mDeviceEnumerator != NULL)
            mDeviceEnumerator->Release();

        CoUninitialize();
    }
}

int CVolumeController::Init(CAvReceiver *ProgramPtr)
{
    mProgramPtr = ProgramPtr;
    IPropertyStore *pProps = NULL;
    IMMDeviceCollection *pCollection = NULL;

    CoInitialize(NULL);
    CoCreateGuid(&mMyGUID);

    const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
    const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
    HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL,CLSCTX_ALL, IID_IMMDeviceEnumerator,(void**)&mDeviceEnumerator);

    hr = mDeviceEnumerator->EnumAudioEndpoints(eRender,DEVICE_STATE_ACTIVE,&pCollection);
    unsigned int count;
    hr = pCollection->GetCount(&count);


    //    mDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &mAudioDevice);  // Get the default audio output device

    bool InterfaceFound = false;
    for(unsigned int i = 0; i < count; i++)
    {
        hr = pCollection->Item(i,&mAudioDevice);
        mAudioDevice->OpenPropertyStore(STGM_READ,&pProps);
        PROPVARIANT DevName;
        // Initialize container for property value.
        PropVariantInit(&DevName);
        hr = pProps->GetValue(PKEY_Device_FriendlyName, &DevName);   //Get the friendly name
        QString FriendlyName = QString("%1").arg(DevName.pwszVal);
        PropVariantClear(&DevName);
        qDebug("%s",qPrintable(FriendlyName));
        if(FriendlyName.contains("SPDIF"))
        {
            //We found our interface.
            InterfaceFound = true;
            qDebug("Audio interface found... binding callback.");
            break;
        }
    }
    if(pProps != NULL)
        pProps->Release();

    if(InterfaceFound == false)
    {
        qDebug("Audio interface not found");
        if(mAudioDevice != NULL)
            mAudioDevice->Release();
        if(mDeviceEnumerator != NULL)
            mDeviceEnumerator->Release();
        CoUninitialize();
        return RET_ERROR;
    }

    mAudioDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (void**)&mEndpointVolume); // Activate the endpoint volume interface

    mEndpointVolume->RegisterControlChangeNotify(this);// Set up the volume change callback


    mEndpointVolume->SetMasterVolumeLevelScalar(0.02,&mMyGUID);
    mEndpointVolume->GetMasterVolumeLevelScalar(&mMasterVolume);

   return RET_OK;

}

int CVolumeController::SetMasterVolume(float Volume)
{
    mEndpointVolume->SetMasterVolumeLevelScalar(Volume,&mMyGUID);
    return RET_OK;
}

STDMETHODIMP CVolumeController:: OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify)
{
    if (pNotify)
    {
        if(pNotify->guidEventContext != mMyGUID)
        {
//            qDebug("Volume changed. Current %f, Requested: %f",mMasterVolume,pNotify->fMasterVolume);
          //  float NewVolume;
            if(mMasterVolume > pNotify->fMasterVolume) //Volume decrease
            {
  //              qDebug("Volume Decrease");
                emit ExternalVolumeChanged(-EXTERNAL_VOLUME_INCREMENT);
            }
            else if(mMasterVolume < pNotify->fMasterVolume)   //Volume increase
            {
   //             qDebug("Volume increase");
                emit ExternalVolumeChanged(EXTERNAL_VOLUME_INCREMENT);

            }
//            qDebug("Setting interface volume to %f",NewVolume);
         //   mEndpointVolume->SetMasterVolumeLevelScalar(NewVolume,&mMyGUID);

        }
        else
        {
            mEndpointVolume->GetMasterVolumeLevelScalar(&mMasterVolume);
  //          qDebug("Setting internal master volume: %f",mMasterVolume);
        }
     }
    return RET_OK;
}

