/*
 * 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

import "inspectable.idl";
import "asyncinfo.idl";
import "eventtoken.idl";
import "windowscontracts.idl";
import "windows.foundation.idl";
import "windows.foundation.numerics.idl";

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;
    }
}
