/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "voe_volume_control_impl.h"

#include "channel.h"
#include "critical_section_wrapper.h"
#include "output_mixer.h"
#include "trace.h"
#include "transmit_mixer.h"
#include "voe_errors.h"
#include "voice_engine_impl.h"

namespace webrtc {

VoEVolumeControl* VoEVolumeControl::GetInterface(VoiceEngine* voiceEngine)
{
#ifndef WEBRTC_VOICE_ENGINE_VOLUME_CONTROL_API
    return NULL;
#else
    if (NULL == voiceEngine)
    {
        return NULL;
    }
    VoiceEngineImpl* s =
        reinterpret_cast<VoiceEngineImpl*> (voiceEngine);
    VoEVolumeControlImpl* d = s;
    (*d)++;
    return (d);
#endif
}

#ifdef WEBRTC_VOICE_ENGINE_VOLUME_CONTROL_API

VoEVolumeControlImpl::VoEVolumeControlImpl()
{
    WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,-1),
               "VoEVolumeControlImpl::VoEVolumeControlImpl() - ctor");
}

VoEVolumeControlImpl::~VoEVolumeControlImpl()
{
    WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,-1),
               "VoEVolumeControlImpl::~VoEVolumeControlImpl() - dtor");
}

int VoEVolumeControlImpl::Release()
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "VoEVolumeControl::Release()");
    (*this)--;
    int refCount = GetCount();
    if (refCount < 0)
    {
        Reset();  // reset reference counter to zero => OK to delete VE
        _engineStatistics.SetLastError(
            VE_INTERFACE_NOT_FOUND, kTraceWarning);
        return (-1);
    }
    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
               "VoEVolumeControl reference counter = %d", refCount);
    return (refCount);
}

int VoEVolumeControlImpl::SetSpeakerVolume(unsigned int volume)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "SetSpeakerVolume(volume=%u)", volume);
    IPHONE_NOT_SUPPORTED();

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (volume > kMaxVolumeLevel)
    {
        _engineStatistics.SetLastError(
            VE_INVALID_ARGUMENT, kTraceError,
            "SetSpeakerVolume() invalid argument");
        return -1;
    }

    WebRtc_UWord32 maxVol(0);
    WebRtc_UWord32 spkrVol(0);

    // scale: [0,kMaxVolumeLevel] -> [0,MaxSpeakerVolume]
    if (_audioDevicePtr->MaxSpeakerVolume(&maxVol) != 0)
    {
        _engineStatistics.SetLastError(
            VE_MIC_VOL_ERROR, kTraceError,
            "SetSpeakerVolume() failed to get max volume");
        return -1;
    }
    // Round the value and avoid floating computation.
    spkrVol = (WebRtc_UWord32)((volume * maxVol +
        (int)(kMaxVolumeLevel / 2)) / (kMaxVolumeLevel));

    // set the actual volume using the audio mixer
    if (_audioDevicePtr->SetSpeakerVolume(spkrVol) != 0)
    {
        _engineStatistics.SetLastError(
            VE_MIC_VOL_ERROR, kTraceError,
            "SetSpeakerVolume() failed to set speaker volume");
        return -1;
    }
    return 0;
}

int VoEVolumeControlImpl::GetSpeakerVolume(unsigned int& volume)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "GetSpeakerVolume()");
    IPHONE_NOT_SUPPORTED();

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    WebRtc_UWord32 spkrVol(0);
    WebRtc_UWord32 maxVol(0);

    if (_audioDevicePtr->SpeakerVolume(&spkrVol) != 0)
    {
        _engineStatistics.SetLastError(
            VE_GET_MIC_VOL_ERROR, kTraceError,
            "GetSpeakerVolume() unable to get speaker volume");
        return -1;
    }

    // scale: [0, MaxSpeakerVolume] -> [0, kMaxVolumeLevel]
    if (_audioDevicePtr->MaxSpeakerVolume(&maxVol) != 0)
    {
        _engineStatistics.SetLastError(
            VE_GET_MIC_VOL_ERROR, kTraceError,
            "GetSpeakerVolume() unable to get max speaker volume");
        return -1;
    }
    // Round the value and avoid floating computation.
    volume = (WebRtc_UWord32) ((spkrVol * kMaxVolumeLevel +
        (int)(maxVol / 2)) / (maxVol));

    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
               "GetSpeakerVolume() => volume=%d", volume);
    return 0;
}

int VoEVolumeControlImpl::SetSystemOutputMute(bool enable)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "GetSystemOutputMute(enabled=%d)", enable);

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    if (_audioDevicePtr->SetSpeakerMute(enable) != 0)
    {
        _engineStatistics.SetLastError(
            VE_GET_MIC_VOL_ERROR, kTraceError,
            "SpeakerMute() unable to Set speaker mute");
        return -1;
    }

    return 0;
}

int VoEVolumeControlImpl::GetSystemOutputMute(bool& enabled)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "GetSystemOutputMute(enabled=?)");

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    if (_audioDevicePtr->SpeakerMute(&enabled) != 0)
    {
        _engineStatistics.SetLastError(
            VE_GET_MIC_VOL_ERROR, kTraceError,
            "SpeakerMute() unable to get speaker mute state");
        return -1;
    }
    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
               "GetSystemOutputMute() => %d", enabled);
    return 0;
}

int VoEVolumeControlImpl::SetMicVolume(unsigned int volume)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "SetMicVolume(volume=%u)", volume);
    ANDROID_NOT_SUPPORTED(_engineStatistics);
    IPHONE_NOT_SUPPORTED();

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (volume > kMaxVolumeLevel)
    {
        _engineStatistics.SetLastError(
            VE_INVALID_ARGUMENT, kTraceError,
            "SetMicVolume() invalid argument");
        return -1;
    }

    WebRtc_UWord32 maxVol(0);
    WebRtc_UWord32 micVol(0);

    // scale: [0, kMaxVolumeLevel] -> [0,MaxMicrophoneVolume]
    if (_audioDevicePtr->MaxMicrophoneVolume(&maxVol) != 0)
    {
        _engineStatistics.SetLastError(
            VE_MIC_VOL_ERROR, kTraceError,
            "SetMicVolume() failed to get max volume");
        return -1;
    }

    if (volume == kMaxVolumeLevel) {
      // On Linux running pulse, users are able to set the volume above 100%
      // through the volume control panel, where the +100% range is digital
      // scaling. WebRTC does not support setting the volume above 100%, and
      // simply ignores changing the volume if the user tries to set it to
      // |kMaxVolumeLevel| while the current volume is higher than |maxVol|.
      if (_audioDevicePtr->MicrophoneVolume(&micVol) != 0) {
        _engineStatistics.SetLastError(
            VE_GET_MIC_VOL_ERROR, kTraceError,
            "SetMicVolume() unable to get microphone volume");
        return -1;
      }
      if (micVol >= maxVol)
        return 0;
    }

    // Round the value and avoid floating point computation.
    micVol = (WebRtc_UWord32) ((volume * maxVol +
        (int)(kMaxVolumeLevel / 2)) / (kMaxVolumeLevel));

    // set the actual volume using the audio mixer
    if (_audioDevicePtr->SetMicrophoneVolume(micVol) != 0)
    {
        _engineStatistics.SetLastError(
            VE_MIC_VOL_ERROR, kTraceError,
            "SetMicVolume() failed to set mic volume");
        return -1;
    }
    return 0;
}

int VoEVolumeControlImpl::GetMicVolume(unsigned int& volume)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "GetMicVolume()");
    ANDROID_NOT_SUPPORTED(_engineStatistics);
    IPHONE_NOT_SUPPORTED();

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    WebRtc_UWord32 micVol(0);
    WebRtc_UWord32 maxVol(0);

    if (_audioDevicePtr->MicrophoneVolume(&micVol) != 0)
    {
        _engineStatistics.SetLastError(
            VE_GET_MIC_VOL_ERROR, kTraceError,
            "GetMicVolume() unable to get microphone volume");
        return -1;
    }

    // scale: [0, MaxMicrophoneVolume] -> [0, kMaxVolumeLevel]
    if (_audioDevicePtr->MaxMicrophoneVolume(&maxVol) != 0)
    {
        _engineStatistics.SetLastError(
            VE_GET_MIC_VOL_ERROR, kTraceError,
            "GetMicVolume() unable to get max microphone volume");
        return -1;
    }
    if (micVol < maxVol) {
      // Round the value and avoid floating point calculation.
      volume = (WebRtc_UWord32) ((micVol * kMaxVolumeLevel +
          (int)(maxVol / 2)) / (maxVol));
    } else {
      // Truncate the value to the kMaxVolumeLevel.
      volume = kMaxVolumeLevel;
    }

    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
               "GetMicVolume() => volume=%d", volume);
    return 0;
}

int VoEVolumeControlImpl::SetInputMute(int channel, bool enable)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "SetInputMute(channel=%d, enable=%d)", channel, enable);

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (channel == -1)
    {
        // Mute before demultiplexing <=> affects all channels
        return _transmitMixerPtr->SetMute(enable);
    }
    else
    {
        // Mute after demultiplexing <=> affects one channel only
        voe::ScopedChannel sc(_channelManager, channel);
        voe::Channel* channelPtr = sc.ChannelPtr();
        if (channelPtr == NULL)
        {
            _engineStatistics.SetLastError(
                VE_CHANNEL_NOT_VALID, kTraceError,
                "SetInputMute() failed to locate channel");
            return -1;
        }
        return channelPtr->SetMute(enable);
    }
    return 0;
}

int VoEVolumeControlImpl::GetInputMute(int channel, bool& enabled)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "GetInputMute(channel=%d)", channel);

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (channel == -1)
    {
        enabled = _transmitMixerPtr->Mute();
    }
    else
    {
        voe::ScopedChannel sc(_channelManager, channel);
        voe::Channel* channelPtr = sc.ChannelPtr();
        if (channelPtr == NULL)
        {
            _engineStatistics.SetLastError(
                VE_CHANNEL_NOT_VALID, kTraceError,
                "SetInputMute() failed to locate channel");
            return -1;
        }
        enabled = channelPtr->Mute();
    }
    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
               "GetInputMute() => enabled = %d", (int)enabled);
    return 0;
}

int VoEVolumeControlImpl::SetSystemInputMute(bool enable)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "SetSystemInputMute(enabled=%d)", enable);

    if (!_engineStatistics.Initialized())
    {
            _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
            return -1;
    }

    if (_audioDevicePtr->SetMicrophoneMute(enable) != 0)
    {
        _engineStatistics.SetLastError(
            VE_GET_MIC_VOL_ERROR, kTraceError,
            "MicrophoneMute() unable to set microphone mute state");
        return -1;
    }

    return 0;
}

int VoEVolumeControlImpl::GetSystemInputMute(bool& enabled)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "GetSystemInputMute(enabled=?)");

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    if (_audioDevicePtr->MicrophoneMute(&enabled) != 0)
    {
        _engineStatistics.SetLastError(
            VE_GET_MIC_VOL_ERROR, kTraceError,
            "MicrophoneMute() unable to get microphone mute state");
        return -1;
    }
    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
               "GetSystemInputMute() => %d", enabled);
	return 0;
}

int VoEVolumeControlImpl::GetSpeechInputLevel(unsigned int& level)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "GetSpeechInputLevel()");

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    WebRtc_Word8 currentLevel = _transmitMixerPtr->AudioLevel();
    level = static_cast<unsigned int> (currentLevel);
    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
               "GetSpeechInputLevel() => %d", level);
    return 0;
}

int VoEVolumeControlImpl::GetSpeechOutputLevel(int channel,
                                               unsigned int& level)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "GetSpeechOutputLevel(channel=%d, level=?)", channel);
	
    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (channel == -1)
    {
        return _outputMixerPtr->GetSpeechOutputLevel((WebRtc_UWord32&)level);
    }
    else
    {
        voe::ScopedChannel sc(_channelManager, channel);
        voe::Channel* channelPtr = sc.ChannelPtr();
        if (channelPtr == NULL)
        {
            _engineStatistics.SetLastError(
                VE_CHANNEL_NOT_VALID, kTraceError,
                "GetSpeechOutputLevel() failed to locate channel");
            return -1;
        }
        channelPtr->GetSpeechOutputLevel((WebRtc_UWord32&)level);
    }
    return 0;
}

int VoEVolumeControlImpl::GetSpeechInputLevelFullRange(unsigned int& level)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "GetSpeechInputLevelFullRange(level=?)");

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    WebRtc_Word16 currentLevel = _transmitMixerPtr->AudioLevelFullRange();
    level = static_cast<unsigned int> (currentLevel);
    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
               "GetSpeechInputLevelFullRange() => %d", level);
    return 0;
}

int VoEVolumeControlImpl::GetSpeechOutputLevelFullRange(int channel,
                                                        unsigned int& level)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "GetSpeechOutputLevelFullRange(channel=%d, level=?)", channel);

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (channel == -1)
    {
        return _outputMixerPtr->GetSpeechOutputLevelFullRange(
            (WebRtc_UWord32&)level);
    }
    else
    {
        voe::ScopedChannel sc(_channelManager, channel);
        voe::Channel* channelPtr = sc.ChannelPtr();
        if (channelPtr == NULL)
        {
            _engineStatistics.SetLastError(
                VE_CHANNEL_NOT_VALID, kTraceError,
                "GetSpeechOutputLevelFullRange() failed to locate channel");
            return -1;
        }
        channelPtr->GetSpeechOutputLevelFullRange((WebRtc_UWord32&)level);
    }
    return 0;
}

int VoEVolumeControlImpl::SetChannelOutputVolumeScaling(int channel,
                                                        float scaling)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "SetChannelOutputVolumeScaling(channel=%d, scaling=%3.2f)",
               channel, scaling);
    IPHONE_NOT_SUPPORTED();
    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (scaling < kMinOutputVolumeScaling ||
        scaling > kMaxOutputVolumeScaling)
    {
        _engineStatistics.SetLastError(
            VE_INVALID_ARGUMENT, kTraceError,
            "SetChannelOutputVolumeScaling() invalid parameter");
        return -1;
    }
    voe::ScopedChannel sc(_channelManager, channel);
    voe::Channel* channelPtr = sc.ChannelPtr();
    if (channelPtr == NULL)
    {
        _engineStatistics.SetLastError(
            VE_CHANNEL_NOT_VALID, kTraceError,
            "SetChannelOutputVolumeScaling() failed to locate channel");
        return -1;
    }
    return channelPtr->SetChannelOutputVolumeScaling(scaling);
}

int VoEVolumeControlImpl::GetChannelOutputVolumeScaling(int channel,
                                                        float& scaling)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "GetChannelOutputVolumeScaling(channel=%d, scaling=?)", channel);
    IPHONE_NOT_SUPPORTED();
    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    voe::ScopedChannel sc(_channelManager, channel);
    voe::Channel* channelPtr = sc.ChannelPtr();
    if (channelPtr == NULL)
    {
        _engineStatistics.SetLastError(
            VE_CHANNEL_NOT_VALID, kTraceError,
            "GetChannelOutputVolumeScaling() failed to locate channel");
        return -1;
    }
    return channelPtr->GetChannelOutputVolumeScaling(scaling);
}

int VoEVolumeControlImpl::SetOutputVolumePan(int channel,
                                             float left,
                                             float right)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "SetOutputVolumePan(channel=%d, left=%2.1f, right=%2.1f)",
               channel, left, right);
    ANDROID_NOT_SUPPORTED(_engineStatistics);
    IPHONE_NOT_SUPPORTED();

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    bool available(false);
    _audioDevicePtr->StereoPlayoutIsAvailable(&available);
    if (!available)
    {
        _engineStatistics.SetLastError(
            VE_FUNC_NO_STEREO, kTraceError,
            "SetOutputVolumePan() stereo playout not supported");
        return -1;
    }
    if ((left < kMinOutputVolumePanning)  ||
        (left > kMaxOutputVolumePanning)  ||
        (right < kMinOutputVolumePanning) ||
        (right > kMaxOutputVolumePanning))
    {
        _engineStatistics.SetLastError(
            VE_INVALID_ARGUMENT, kTraceError,
            "SetOutputVolumePan() invalid parameter");
        return -1;
    }

    if (channel == -1)
    {
        // Master balance (affectes the signal after output mixing)
        return _outputMixerPtr->SetOutputVolumePan(left, right);
    }
    else
    {
        // Per-channel balance (affects the signal before output mixing)
        voe::ScopedChannel sc(_channelManager, channel);
        voe::Channel* channelPtr = sc.ChannelPtr();
        if (channelPtr == NULL)
        {
            _engineStatistics.SetLastError(
                VE_CHANNEL_NOT_VALID, kTraceError,
                "SetOutputVolumePan() failed to locate channel");
            return -1;
        }
        return channelPtr->SetOutputVolumePan(left, right);
    }
    return 0;
}

int VoEVolumeControlImpl::GetOutputVolumePan(int channel,
                                             float& left,
                                             float& right)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId,-1),
               "GetOutputVolumePan(channel=%d, left=?, right=?)", channel);
    ANDROID_NOT_SUPPORTED(_engineStatistics);
    IPHONE_NOT_SUPPORTED();

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    bool available(false);
    _audioDevicePtr->StereoPlayoutIsAvailable(&available);
    if (!available)
    {
        _engineStatistics.SetLastError(
            VE_FUNC_NO_STEREO, kTraceError,
            "GetOutputVolumePan() stereo playout not supported");
        return -1;
    }

    if (channel == -1)
    {
        return _outputMixerPtr->GetOutputVolumePan(left, right);
    }
    else
    {
        voe::ScopedChannel sc(_channelManager, channel);
        voe::Channel* channelPtr = sc.ChannelPtr();
        if (channelPtr == NULL)
        {
            _engineStatistics.SetLastError(
                VE_CHANNEL_NOT_VALID, kTraceError,
                "GetOutputVolumePan() failed to locate channel");
            return -1;
        }
        return channelPtr->GetOutputVolumePan(left, right);
    }
    return 0;
}

#endif  // #ifdef WEBRTC_VOICE_ENGINE_VOLUME_CONTROL_API

}  // namespace webrtc
