/*
 * Copyright 2021 Rémi Bernon for CodeWeavers
 *
 * 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 of the License, or (at your option) any later version.
 *
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#ifdef __WIDL__
#pragma winrt ns_prefix
#endif

#ifndef DO_NO_IMPORTS
import "inspectable.idl";
import "asyncinfo.idl";
import "eventtoken.idl";
import "windowscontracts.idl";
import "windows.foundation.idl";
import "windows.foundation.numerics.idl";
#endif

namespace Windows.Gaming.Input.ForceFeedback {
    typedef enum ForceFeedbackEffectAxes ForceFeedbackEffectAxes;
    typedef enum ForceFeedbackEffectState ForceFeedbackEffectState;
    typedef enum ForceFeedbackLoadEffectResult ForceFeedbackLoadEffectResult;
    typedef enum PeriodicForceEffectKind PeriodicForceEffectKind;
    typedef enum ConditionForceEffectKind ConditionForceEffectKind;
    interface IForceFeedbackEffect;
    interface IPeriodicForceEffect;
    interface IPeriodicForceEffectFactory;
    interface IConditionForceEffect;
    interface IConditionForceEffectFactory;
    interface IConstantForceEffect;
    interface IRampForceEffect;
    runtimeclass ForceFeedbackMotor;
    runtimeclass PeriodicForceEffect;
    runtimeclass ConditionForceEffect;
    runtimeclass ConstantForceEffect;
    runtimeclass RampForceEffect;

    declare {
        interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Gaming.Input.ForceFeedback.ForceFeedbackLoadEffectResult>;
        interface Windows.Foundation.IAsyncOperation<Windows.Gaming.Input.ForceFeedback.ForceFeedbackLoadEffectResult>;
        interface Windows.Foundation.Collections.IIterator<Windows.Gaming.Input.ForceFeedback.ForceFeedbackMotor *>;
        interface Windows.Foundation.Collections.IIterable<Windows.Gaming.Input.ForceFeedback.ForceFeedbackMotor *>;
        interface Windows.Foundation.Collections.IVectorView<Windows.Gaming.Input.ForceFeedback.ForceFeedbackMotor *>;
        interface Windows.Foundation.Collections.IVector<Windows.Gaming.Input.ForceFeedback.ForceFeedbackMotor *>;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        flags
    ]
    enum ForceFeedbackEffectAxes
    {
        None = 0x0,
        X    = 0x1,
        Y    = 0x2,
        Z    = 0x4
    };

    [contract(Windows.Foundation.UniversalApiContract, 3.0)]
    enum ForceFeedbackEffectState
    {
        Stopped = 0,
        Running = 1,
        Paused  = 2,
        Faulted = 3,
    };

    [contract(Windows.Foundation.UniversalApiContract, 3.0)]
    enum ForceFeedbackLoadEffectResult
    {
        Succeeded          = 0,
        EffectStorageFull  = 1,
        EffectNotSupported = 2
    };

    [contract(Windows.Foundation.UniversalApiContract, 3.0)]
    enum PeriodicForceEffectKind
    {
        SquareWave       = 0,
        SineWave         = 1,
        TriangleWave     = 2,
        SawtoothWaveUp   = 3,
        SawtoothWaveDown = 4,
    };

    [contract(Windows.Foundation.UniversalApiContract, 3.0)]
    enum ConditionForceEffectKind
    {
        Spring   = 0,
        Damper   = 1,
        Inertia  = 2,
        Friction = 3,
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        uuid(a17fba0c-2ae4-48c2-8063-eabd0777cb89)
    ]
    interface IForceFeedbackEffect : IInspectable
    {
        [propget] HRESULT Gain([out, retval] DOUBLE *value);
        [propput] HRESULT Gain([in] DOUBLE value);
        [propget] HRESULT State([out, retval] Windows.Gaming.Input.ForceFeedback.ForceFeedbackEffectState *value);
        HRESULT Start();
        HRESULT Stop();
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        exclusiveto(Windows.Gaming.Input.ForceFeedback.ForceFeedbackMotor),
        uuid(8d3d417c-a5ea-4516-8026-2b00f74ef6e5)
    ]
    interface IForceFeedbackMotor : IInspectable
    {
        [propget] HRESULT AreEffectsPaused([out, retval] boolean *value);
        [propget] HRESULT MasterGain([out, retval] DOUBLE *value);
        [propput] HRESULT MasterGain([in] DOUBLE value);
        [propget] HRESULT IsEnabled([out, retval] boolean *value);
        [propget] HRESULT SupportedAxes([out, retval] Windows.Gaming.Input.ForceFeedback.ForceFeedbackEffectAxes *value);
        HRESULT LoadEffectAsync([in] Windows.Gaming.Input.ForceFeedback.IForceFeedbackEffect *effect,
                                [out, retval] Windows.Foundation.IAsyncOperation<Windows.Gaming.Input.ForceFeedback.ForceFeedbackLoadEffectResult> **async_op);
        HRESULT PauseAllEffects();
        HRESULT ResumeAllEffects();
        HRESULT StopAllEffects();
        HRESULT TryDisableAsync([out, retval] Windows.Foundation.IAsyncOperation<boolean> **async_op);
        HRESULT TryEnableAsync([out, retval] Windows.Foundation.IAsyncOperation<boolean> **async_op);
        HRESULT TryResetAsync([out, retval] Windows.Foundation.IAsyncOperation<boolean> **async_op);
        HRESULT TryUnloadEffectAsync([in] Windows.Gaming.Input.ForceFeedback.IForceFeedbackEffect *effect,
                                     [out, retval] Windows.Foundation.IAsyncOperation<boolean> **async_op);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        exclusiveto(Windows.Gaming.Input.ForceFeedback.PeriodicForceEffect),
        uuid(5c5138d7-fc75-4d52-9a0a-efe4cab5fe64)
    ]
    interface IPeriodicForceEffect : IInspectable
        requires Windows.Gaming.Input.ForceFeedback.IForceFeedbackEffect
    {
        [propget] HRESULT Kind([out, retval] Windows.Gaming.Input.ForceFeedback.PeriodicForceEffectKind *value);
        HRESULT SetParameters([in] Windows.Foundation.Numerics.Vector3 vector, [in] FLOAT frequency, [in] FLOAT phase,
                              [in] FLOAT bias, [in] Windows.Foundation.TimeSpan duration);
        HRESULT SetParametersWithEnvelope([in] Windows.Foundation.Numerics.Vector3 vector, [in] FLOAT frequency, [in] FLOAT phase,
                                          [in] FLOAT bias, [in] FLOAT attack_gain, [in] FLOAT sustain_gain, [in] FLOAT release_gain,
                                          [in] Windows.Foundation.TimeSpan start_delay, [in] Windows.Foundation.TimeSpan attack_duration,
                                          [in] Windows.Foundation.TimeSpan sustain_duration, [in] Windows.Foundation.TimeSpan release_duration,
                                          [in] UINT32 repeat_count);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        exclusiveto(Windows.Gaming.Input.ForceFeedback.PeriodicForceEffect),
        uuid(6f62eb1a-9851-477b-b318-35ecaa15070f)
    ]
    interface IPeriodicForceEffectFactory : IInspectable
    {
        HRESULT CreateInstance([in] Windows.Gaming.Input.ForceFeedback.PeriodicForceEffectKind kind,
                               [out, retval] Windows.Gaming.Input.ForceFeedback.PeriodicForceEffect **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        exclusiveto(Windows.Gaming.Input.ForceFeedback.ConditionForceEffect),
        uuid(32d1ea68-3695-4e69-85c0-cd1944189140)
    ]
    interface IConditionForceEffect : IInspectable
        requires Windows.Gaming.Input.ForceFeedback.IForceFeedbackEffect
    {
        [propget] HRESULT Kind([out, retval] Windows.Gaming.Input.ForceFeedback.ConditionForceEffectKind *value);
        HRESULT SetParameters([in] Windows.Foundation.Numerics.Vector3 direction, [in] FLOAT positive_coeff,
                              [in] FLOAT negative_coeff, [in] FLOAT max_positive_magnitude, [in] FLOAT max_negative_magnitude,
                              [in] FLOAT deadzone, [in] FLOAT bias);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        exclusiveto(Windows.Gaming.Input.ForceFeedback.ConditionForceEffect),
        uuid(91a99264-1810-4eb6-a773-bfd3b8cddbab)
    ]
    interface IConditionForceEffectFactory : IInspectable
    {
        HRESULT CreateInstance([in] Windows.Gaming.Input.ForceFeedback.ConditionForceEffectKind kind,
                               [out, retval] Windows.Gaming.Input.ForceFeedback.ConditionForceEffect **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        exclusiveto(Windows.Gaming.Input.ForceFeedback.ConstantForceEffect),
        uuid(9bfa0140-f3c7-415c-b068-0f068734bce0)
    ]
    interface IConstantForceEffect : IInspectable
        requires Windows.Gaming.Input.ForceFeedback.IForceFeedbackEffect
    {
        HRESULT SetParameters([in] Windows.Foundation.Numerics.Vector3 vector, [in] Windows.Foundation.TimeSpan duration);
        HRESULT SetParametersWithEnvelope([in] Windows.Foundation.Numerics.Vector3 vector, [in] FLOAT attack_gain,
                                          [in] FLOAT sustain_gain, [in] FLOAT release_gain, [in] Windows.Foundation.TimeSpan start_delay,
                                          [in] Windows.Foundation.TimeSpan attack_duration, [in] Windows.Foundation.TimeSpan sustain_duration,
                                          [in] Windows.Foundation.TimeSpan release_duration, [in] UINT32 repeat_count);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        exclusiveto(Windows.Gaming.Input.ForceFeedback.RampForceEffect),
        uuid(f1f81259-1ca6-4080-b56d-b43f3354d052)
    ]
    interface IRampForceEffect : IInspectable
        requires Windows.Gaming.Input.ForceFeedback.IForceFeedbackEffect
    {
        HRESULT SetParameters([in] Windows.Foundation.Numerics.Vector3 start_vector, [in] Windows.Foundation.Numerics.Vector3 end_vector,
                              [in] Windows.Foundation.TimeSpan duration);
        HRESULT SetParametersWithEnvelope([in] Windows.Foundation.Numerics.Vector3 start_vector, [in] Windows.Foundation.Numerics.Vector3 end_vector,
                                          [in] FLOAT attack_gain, [in] FLOAT sustain_gain, [in] FLOAT release_gain, [in] Windows.Foundation.TimeSpan start_delay,
                                          [in] Windows.Foundation.TimeSpan attack_duration, [in] Windows.Foundation.TimeSpan sustain_duration,
                                          [in] Windows.Foundation.TimeSpan release_duration, [in] UINT32 repeat_count);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        marshaling_behavior(agile),
        threading(both)
    ]
    runtimeclass ForceFeedbackMotor
    {
        [default] interface Windows.Gaming.Input.ForceFeedback.IForceFeedbackMotor;
    }

    [
        activatable(Windows.Gaming.Input.ForceFeedback.IPeriodicForceEffectFactory, Windows.Foundation.UniversalApiContract, 3.0),
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        marshaling_behavior(agile),
        threading(both)
    ]
    runtimeclass PeriodicForceEffect
    {
        [default] interface Windows.Gaming.Input.ForceFeedback.IForceFeedbackEffect;
        interface Windows.Gaming.Input.ForceFeedback.IPeriodicForceEffect;
    }

    [
        activatable(Windows.Gaming.Input.ForceFeedback.IConditionForceEffectFactory, Windows.Foundation.UniversalApiContract, 3.0),
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        marshaling_behavior(agile),
        threading(both)
    ]
    runtimeclass ConditionForceEffect
    {
        [default] interface Windows.Gaming.Input.ForceFeedback.IForceFeedbackEffect;
        interface Windows.Gaming.Input.ForceFeedback.IConditionForceEffect;
    }

    [
        activatable(Windows.Foundation.UniversalApiContract, 3.0),
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        marshaling_behavior(agile),
        threading(both)
    ]
    runtimeclass ConstantForceEffect
    {
        [default] interface Windows.Gaming.Input.ForceFeedback.IForceFeedbackEffect;
        interface Windows.Gaming.Input.ForceFeedback.IConstantForceEffect;
    }

    [
        activatable(Windows.Foundation.UniversalApiContract, 3.0),
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        marshaling_behavior(agile),
        threading(both)
    ]
    runtimeclass RampForceEffect
    {
        [default] interface Windows.Gaming.Input.ForceFeedback.IForceFeedbackEffect;
        interface Windows.Gaming.Input.ForceFeedback.IRampForceEffect;
    }
}
