/*  This file is part of the KDE project.

Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 or 3 of the License.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <EnvironmentalReverbBase.h>
#include "environmentalreverb.h"

QT_BEGIN_NAMESPACE

using namespace Phonon;
using namespace Phonon::MMF;

/*! \class MMF::EnvironmentalReverb
  \internal
*/

// Define functions which depend on concrete native effect class name
PHONON_MMF_DEFINE_EFFECT_FUNCTIONS(EnvironmentalReverb)

enum Parameters
{
    DecayHFRatio = AbstractAudioEffect::ParameterBase,
    DecayTime,
    Density,
    Diffusion,
    ReflectionsDelay,
    ReflectionsLevel,
    ReverbDelay,
    ReverbLevel,
    RoomHFLevel,
    RoomLevel
};

EnvironmentalReverb::EnvironmentalReverb(QObject *parent, const QList<EffectParameter>& parameters)
    :   AbstractAudioEffect::AbstractAudioEffect(parent, parameters)
{

}

int EnvironmentalReverb::effectParameterChanged(const EffectParameter &param,
                                      const QVariant &value)
{
    const qreal externalLevel = value.toReal();
    const int internalLevel = param.toInternalValue(externalLevel);

    TInt err = 0;

    switch(param.id()) {
    case DecayHFRatio:
        TRAP(err, concreteEffect()->SetDecayHFRatioL(internalLevel));
        break;
    case DecayTime:
        TRAP(err, concreteEffect()->SetDecayTimeL(internalLevel));
        break;
    case Density:
        TRAP(err, concreteEffect()->SetDensityL(internalLevel));
        break;
    case Diffusion:
        TRAP(err, concreteEffect()->SetDiffusionL(internalLevel));
        break;
    case ReflectionsDelay:
        TRAP(err, concreteEffect()->SetReflectionsDelayL(internalLevel));
        break;
    case ReflectionsLevel:
        TRAP(err, concreteEffect()->SetReflectionsLevelL(internalLevel));
        break;
    case ReverbDelay:
        TRAP(err, concreteEffect()->SetReverbDelayL(internalLevel));
        break;
    case ReverbLevel:
        TRAP(err, concreteEffect()->SetReverbLevelL(internalLevel));
        break;
    case RoomHFLevel:
        TRAP(err, concreteEffect()->SetRoomHFLevelL(internalLevel));
        break;
    case RoomLevel:
        TRAP(err, concreteEffect()->SetRoomLevelL(internalLevel));
        break;
    default:
        Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown parameter");
    }

    return err;
}


//-----------------------------------------------------------------------------
// Static functions
//-----------------------------------------------------------------------------

const char* EnvironmentalReverb::description()
{
    return "Reverb";
}

// Internal helper function
Phonon::MMF::EffectParameter createParameter(int id, const QString &name,
    int defaultValue, int minValue, int maxValue,
    Phonon::EffectParameter::Hint hint = Phonon::EffectParameter::IntegerHint)
{
    const qreal externalDefaultValue =
        Phonon::MMF::EffectParameter::toExternalValue
            (defaultValue, minValue, maxValue);

    Phonon::MMF::EffectParameter param(id, name, hint,
        /* defaultValue */       QVariant(externalDefaultValue),
        /* minimumValue */       QVariant(qreal(-1.0)),
        /* maximumValue */       QVariant(qreal(+1.0)));

    param.setInternalRange(minValue, maxValue);
    return param;
}

bool EnvironmentalReverb::getParameters(CMdaAudioOutputStream *stream,
    QList<EffectParameter>& parameters)
{
    bool supported = false;

    QScopedPointer<CEnvironmentalReverb> effect;
    TRAPD(err, effect.reset(CEnvironmentalReverb::NewL(*stream)));

    if (KErrNone == err) {
        supported = true;

        TInt32 min, max;
        TUint32 umin, umax;

        effect->DecayHFRatioRange(umin, umax);
        //: DecayHFRatio: Ratio of high-frequency decay time to the value specified by
        //: DecayTime.
        parameters.append(createParameter(
            DecayHFRatio, tr("Decay HF ratio (%)"), effect->DecayHFRatio(),
            umin, umax));

        effect->DecayTimeRange(umin, umax);
        //: DecayTime: Time over which reverberation is diminished.
        parameters.append(createParameter(
            DecayTime, tr("Decay time (ms)"), effect->DecayTime(),
            umin, umax));

        //: Density Delay between first and subsequent reflections.
        //: Note that the S60 platform documentation does not make clear
        //: the distinction between this value and the Diffusion value.
        parameters.append(createParameter(
            Density, tr("Density (%)"), effect->Density(), 0, 100));

        //: Diffusion: Delay between first and subsequent reflections.
        //: Note that the S60 platform documentation does not make clear
        //: the distinction between this value and the Density value.
        parameters.append(createParameter(
            Diffusion, tr("Diffusion (%)"), effect->Diffusion(), 0, 100));

        //: ReflectionsDelay: Amount of delay between the arrival the direct
        //: path from the source and the arrival of the first reflection.
        parameters.append(createParameter(
            ReflectionsDelay, tr("Reflections delay (ms)"),
            effect->ReflectionsDelay(), 0, effect->ReflectionsDelayMax()));

        effect->ReflectionLevelRange(min, max);
        //: ReflectionsLevel: Amplitude of reflections. This value is
        //: corrected by the RoomLevel to give the final reflection amplitude.
        parameters.append(createParameter(
            ReflectionsLevel, tr("Reflections level (mB)"),
            effect->ReflectionsLevel(),
            min, max, EffectParameter::LogarithmicHint));

        //: ReverbDelay: Amount of time between arrival of the first
        //: reflection and start of the late reverberation.
        parameters.append(createParameter(
            ReverbDelay, tr("Reverb delay (ms)"), effect->ReverbDelay(),
            0, effect->ReverbDelayMax()));

        effect->ReverbLevelRange(min, max);
        //: ReverbLevel Amplitude of reverberations.  This value is
        //: corrected by the RoomLevel to give the final reverberation
        //: amplitude.
        parameters.append(createParameter(
            ReverbLevel, tr("Reverb level (mB)"), effect->ReverbLevel(),
            min, max, EffectParameter::LogarithmicHint));

        effect->RoomHFLevelRange(min, max);
        //: RoomHFLevel: Amplitude of low-pass filter used to attenuate the
        //: high frequency component of reflected sound.
        parameters.append(createParameter(
            RoomHFLevel, tr("Room HF level"), effect->RoomHFLevel(),
            min, max));

        effect->RoomLevelRange(min, max);
        //: RoomLevel: Master volume control for all reflected sound.
        parameters.append(createParameter(
            RoomLevel, tr("Room level (mB)"), effect->RoomLevel(),
            min, max, EffectParameter::LogarithmicHint));
    }

    return supported;
}

QT_END_NAMESPACE
