/*
 * Copyright 2023 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 "windows.foundation.idl";
import "windows.storage.idl";
import "windows.system.idl";
import "windows.applicationmodel.idl";
import "windows.applicationmodel.activation.idl";
import "windows.ui.core.idl";

namespace Windows.ApplicationModel.Core {
    runtimeclass CoreApplicationView;
}

namespace Windows.ApplicationModel.Activation {
    interface IActivatedEventArgs;

    runtimeclass BackgroundActivatedEventArgs;

    declare {
        interface Windows.Foundation.EventHandler<Windows.ApplicationModel.Activation.BackgroundActivatedEventArgs *>;
        interface Windows.Foundation.TypedEventHandler<Windows.ApplicationModel.Core.CoreApplicationView *, Windows.ApplicationModel.Activation.IActivatedEventArgs *>;
    }
}

namespace Windows.ApplicationModel {
    runtimeclass AppDisplayInfo;
    runtimeclass EnteredBackgroundEventArgs;
    runtimeclass LeavingBackgroundEventArgs;
    runtimeclass SuspendingEventArgs;

    declare {
        interface Windows.Foundation.EventHandler<Windows.ApplicationModel.EnteredBackgroundEventArgs *>;
        interface Windows.Foundation.EventHandler<Windows.ApplicationModel.LeavingBackgroundEventArgs *>;
        interface Windows.Foundation.EventHandler<Windows.ApplicationModel.SuspendingEventArgs *>;
    }
}

namespace Windows.Foundation {
    interface IGetActivationFactory;
}

namespace Windows.UI.Core {
    runtimeclass CoreDispatcher;
    runtimeclass CoreWindow;
}

namespace Windows.ApplicationModel.Core {
    typedef enum AppRestartFailureReason AppRestartFailureReason;

    interface IAppListEntry;
    interface ICoreApplication;
    interface ICoreApplication2;
    interface ICoreApplication3;
    interface ICoreApplicationExit;
    interface ICoreApplicationUnhandledError;
    interface ICoreApplicationUseCount;
    interface ICoreApplicationView;
    interface ICoreApplicationView2;
    interface ICoreApplicationView3;
    interface ICoreApplicationView5;
    interface ICoreApplicationView6;
    interface ICoreApplicationViewTitleBar;
    interface ICoreImmersiveApplication;
    interface ICoreImmersiveApplication2;
    interface ICoreImmersiveApplication3;
    interface IFrameworkView;
    interface IFrameworkViewSource;
    interface IHostedViewClosingEventArgs;
    interface IUnhandledError;
    interface IUnhandledErrorDetectedEventArgs;

    runtimeclass AppListEntry;
    runtimeclass CoreApplication;
    runtimeclass CoreApplicationView;
    runtimeclass CoreApplicationViewTitleBar;
    runtimeclass HostedViewClosingEventArgs;
    runtimeclass UnhandledError;
    runtimeclass UnhandledErrorDetectedEventArgs;

    declare {
        interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.ApplicationModel.Core.AppRestartFailureReason>;
        interface Windows.Foundation.Collections.IVectorView<Windows.ApplicationModel.Core.CoreApplicationView *>;
        interface Windows.Foundation.EventHandler<Windows.ApplicationModel.Core.UnhandledErrorDetectedEventArgs *>;
        interface Windows.Foundation.IAsyncOperation<Windows.ApplicationModel.Core.AppRestartFailureReason>;
        interface Windows.Foundation.TypedEventHandler<Windows.ApplicationModel.Core.CoreApplicationView *, Windows.ApplicationModel.Core.HostedViewClosingEventArgs *>;
        interface Windows.Foundation.TypedEventHandler<Windows.ApplicationModel.Core.CoreApplicationViewTitleBar *, IInspectable *>;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 5.0)
    ]
    enum AppRestartFailureReason
    {
        RestartPending  = 0,
        NotInForeground = 1,
        InvalidUser     = 2,
        Other           = 3
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.AppListEntry),
        uuid(ef00f07f-2108-490a-877a-8a9f17c25fad)
    ]
    interface IAppListEntry : IInspectable
    {
        [propget] HRESULT DisplayInfo([out, retval] Windows.ApplicationModel.AppDisplayInfo **value);
        HRESULT LaunchAsync([out, retval] Windows.Foundation.IAsyncOperation<boolean> **operation);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplication),
        uuid(0aacf7a4-5e1d-49df-8034-fb6a68bc5ed1)
    ]
    interface ICoreApplication : IInspectable
    {
        [propget] HRESULT Id([out, retval] HSTRING *value);
        [eventadd] HRESULT Suspending([in] Windows.Foundation.EventHandler<Windows.ApplicationModel.SuspendingEventArgs *> *handler, [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT Suspending([in] EventRegistrationToken token);
        [eventadd] HRESULT Resuming([in] Windows.Foundation.EventHandler<IInspectable *> *handler, [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT Resuming([in] EventRegistrationToken token);
        [propget] HRESULT Properties([out, retval] Windows.Foundation.Collections.IPropertySet **value);
        HRESULT GetCurrentView([out, retval] Windows.ApplicationModel.Core.CoreApplicationView **value);
        HRESULT Run([in] Windows.ApplicationModel.Core.IFrameworkViewSource *view_source);
        HRESULT RunWithActivationFactories([in] Windows.Foundation.IGetActivationFactory *factory);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplication),
        uuid(998681fb-1ab6-4b7f-be4a-9a0645224c04)
    ]
    interface ICoreApplication2 : IInspectable
    {
        [eventadd] HRESULT BackgroundActivated([in] Windows.Foundation.EventHandler<Windows.ApplicationModel.Activation.BackgroundActivatedEventArgs *> *handler, [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT BackgroundActivated([in] EventRegistrationToken token);
        [eventadd] HRESULT LeavingBackground([in] Windows.Foundation.EventHandler<Windows.ApplicationModel.LeavingBackgroundEventArgs *> *handler, [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT LeavingBackground([in] EventRegistrationToken token);
        [eventadd] HRESULT EnteredBackground([in] Windows.Foundation.EventHandler<Windows.ApplicationModel.EnteredBackgroundEventArgs *> *handler, [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT EnteredBackground([in] EventRegistrationToken token);
        HRESULT EnablePrelaunch([in] boolean value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 5.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplication),
        uuid(feec0d39-598b-4507-8a67-772632580a57)
    ]
    interface ICoreApplication3 : IInspectable
    {
        HRESULT RequestRestartAsync([in] HSTRING launch_arguments, [out, retval] Windows.Foundation.IAsyncOperation<Windows.ApplicationModel.Core.AppRestartFailureReason> **operation);
        HRESULT RequestRestartForUserAsync([in] Windows.System.User *user, [in] HSTRING launch_arguments, [out, retval] Windows.Foundation.IAsyncOperation<Windows.ApplicationModel.Core.AppRestartFailureReason> **operation);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplication),
        uuid(cf86461d-261e-4b72-9acd-44ed2ace6a29)
    ]
    interface ICoreApplicationExit : IInspectable
    {
        HRESULT Exit();
        [eventadd] HRESULT Exiting([in] Windows.Foundation.EventHandler<IInspectable *> *handler, [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT Exiting([in] EventRegistrationToken token);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        uuid(f0e24ab0-dd09-42e1-b0bc-e0e131f78d7e)
    ]
    interface ICoreApplicationUnhandledError : IInspectable
    {
        [eventadd] HRESULT UnhandledErrorDetected([in] Windows.Foundation.EventHandler<Windows.ApplicationModel.Core.UnhandledErrorDetectedEventArgs *> *handler, [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT UnhandledErrorDetected([in] EventRegistrationToken token);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplication),
        uuid(518dc408-c077-475b-809e-0bc0c57e4b74)
    ]
    interface ICoreApplicationUseCount : IInspectable
    {
        HRESULT IncrementApplicationUseCount();
        HRESULT DecrementApplicationUseCount();
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplicationView),
        uuid(638bb2db-451d-4661-b099-414f34ffb9f1)
    ]
    interface ICoreApplicationView : IInspectable
    {
        [propget] HRESULT CoreWindow([out, retval] Windows.UI.Core.CoreWindow **value);
        [eventadd] HRESULT Activated([in] Windows.Foundation.TypedEventHandler<Windows.ApplicationModel.Core.CoreApplicationView *, Windows.ApplicationModel.Activation.IActivatedEventArgs *> *handler, [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT Activated([in] EventRegistrationToken token);
        [propget] HRESULT IsMain([out, retval] boolean *value);
        [propget] HRESULT IsHosted([out, retval] boolean *value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplicationView),
        uuid(68eb7adf-917f-48eb-9aeb-7de53e086ab1)
    ]
    interface ICoreApplicationView2 : IInspectable
    {
        [propget] HRESULT Dispatcher([out, retval] Windows.UI.Core.CoreDispatcher **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplicationView),
        uuid(07ebe1b3-a4cf-4550-ab70-b07e85330bc8)
    ]
    interface ICoreApplicationView3 : IInspectable
    {
        [propget] HRESULT IsComponent([out, retval] boolean *value);
        [propget] HRESULT TitleBar([out, retval] Windows.ApplicationModel.Core.CoreApplicationViewTitleBar **value);
        [eventadd] HRESULT HostedViewClosing([in] Windows.Foundation.TypedEventHandler<Windows.ApplicationModel.Core.CoreApplicationView *, Windows.ApplicationModel.Core.HostedViewClosingEventArgs *> *handler, [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT HostedViewClosing([in] EventRegistrationToken token);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 4.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplicationView),
        uuid(2bc095a8-8ef0-446d-9e60-3a3e0428c671)
    ]
    interface ICoreApplicationView5 : IInspectable
    {
        [propget] HRESULT Properties([out, retval] Windows.Foundation.Collections.IPropertySet **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 5.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplicationView),
        uuid(c119d49a-0679-49ba-803f-b79c5cf34cca)
    ]
    interface ICoreApplicationView6 : IInspectable
    {
        [propget] HRESULT DispatcherQueue([out, retval] Windows.System.DispatcherQueue **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplicationViewTitleBar),
        uuid(006d35e3-e1f1-431b-9508-29b96926ac53)
    ]
    interface ICoreApplicationViewTitleBar : IInspectable
    {
        [propput] HRESULT ExtendViewIntoTitleBar([in] boolean value);
        [propget] HRESULT ExtendViewIntoTitleBar([out, retval] boolean *value);
        [propget] HRESULT SystemOverlayLeftInset([out, retval] DOUBLE *value);
        [propget] HRESULT SystemOverlayRightInset([out, retval] DOUBLE *value);
        [propget] HRESULT Height([out, retval] DOUBLE *value);
        [eventadd] HRESULT LayoutMetricsChanged([in] Windows.Foundation.TypedEventHandler<Windows.ApplicationModel.Core.CoreApplicationViewTitleBar *, IInspectable *> *handler, [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT LayoutMetricsChanged([in] EventRegistrationToken token);
        [propget] HRESULT IsVisible([out, retval] boolean *value);
        [eventadd] HRESULT IsVisibleChanged([in] Windows.Foundation.TypedEventHandler<Windows.ApplicationModel.Core.CoreApplicationViewTitleBar *, IInspectable *> *handler, [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT IsVisibleChanged([in] EventRegistrationToken token);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplication),
        uuid(1ada0e3e-e4a2-4123-b451-dc96bf800419)
    ]
    interface ICoreImmersiveApplication : IInspectable
    {
        [propget] HRESULT Views([out, retval] Windows.Foundation.Collections.IVectorView<Windows.ApplicationModel.Core.CoreApplicationView *> **value);
        [overload("CreateNewView"), default_overload]
        HRESULT CreateNewView([in] HSTRING runtime_type, [in] HSTRING entry_point, [out, retval] Windows.ApplicationModel.Core.CoreApplicationView **view);
        [propget] HRESULT MainView([out, retval] Windows.ApplicationModel.Core.CoreApplicationView **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplication),
        uuid(828e1e36-e9e3-4cfc-9b66-48b78ea9bb2c)
    ]
    interface ICoreImmersiveApplication2 : IInspectable
    {
        [overload("CreateNewView")]
        HRESULT CreateNewViewFromMainView([out, retval] Windows.ApplicationModel.Core.CoreApplicationView **view);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.CoreApplication),
        uuid(34a05b2f-ee0d-41e5-8314-cf10c91bf0af)
    ]
    interface ICoreImmersiveApplication3 : IInspectable
    {
        [overload("CreateNewView")]
        HRESULT CreateNewViewWithViewSource([in] Windows.ApplicationModel.Core.IFrameworkViewSource *view_source, [out, retval] Windows.ApplicationModel.Core.CoreApplicationView **view);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        uuid(faab5cd0-8924-45ac-ad0f-a08fae5d0324)
    ]
    interface IFrameworkView : IInspectable
    {
        HRESULT Initialize([in] Windows.ApplicationModel.Core.CoreApplicationView *application_view);
        HRESULT SetWindow([in] Windows.UI.Core.CoreWindow *window);
        HRESULT Load([in] HSTRING entry_point);
        HRESULT Run();
        HRESULT Uninitialize();
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        uuid(cd770614-65c4-426c-9494-34fc43554862)
    ]
    interface IFrameworkViewSource : IInspectable
    {
        HRESULT CreateView([out, retval] Windows.ApplicationModel.Core.IFrameworkView **view);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.HostedViewClosingEventArgs),
        uuid(d238943c-b24e-4790-acb5-3e4243c4ff87)
    ]
    interface IHostedViewClosingEventArgs : IInspectable
    {
        HRESULT GetDeferral([out, retval] Windows.Foundation.Deferral **result);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.UnhandledError),
        uuid(9459b726-53b5-4686-9eaf-fa8162dc3980)
    ]
    interface IUnhandledError : IInspectable
    {
        [propget] HRESULT Handled([out, retval] boolean *value);
        HRESULT Propagate();
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.ApplicationModel.Core.UnhandledErrorDetectedEventArgs),
        uuid(679ab78b-b336-4822-ac40-0d750f0b7a2b)
    ]
    interface IUnhandledErrorDetectedEventArgs : IInspectable
    {
        [propget] HRESULT UnhandledError([out, retval] Windows.ApplicationModel.Core.UnhandledError **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile),
        threading(both)
    ]
    runtimeclass AppListEntry
    {
        [default] interface Windows.ApplicationModel.Core.IAppListEntry;
        /* [contract(Windows.Foundation.UniversalApiContract, 5.0)] interface Windows.ApplicationModel.Core.IAppListEntry2; */
        /* [contract(Windows.Foundation.UniversalApiContract, 6.0)] interface Windows.ApplicationModel.Core.IAppListEntry3; */
        /* [contract(Windows.Foundation.UniversalApiContract, 11.0)] interface Windows.ApplicationModel.Core.IAppListEntry4; */
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile),
        static(Windows.ApplicationModel.Core.ICoreApplication, Windows.Foundation.UniversalApiContract, 1.0),
        static(Windows.ApplicationModel.Core.ICoreApplication2, Windows.Foundation.UniversalApiContract, 3.0),
        static(Windows.ApplicationModel.Core.ICoreApplication3, Windows.Foundation.UniversalApiContract, 5.0),
        static(Windows.ApplicationModel.Core.ICoreApplicationExit, Windows.Foundation.UniversalApiContract, 1.0),
        static(Windows.ApplicationModel.Core.ICoreApplicationUnhandledError, Windows.Foundation.UniversalApiContract, 1.0),
        static(Windows.ApplicationModel.Core.ICoreApplicationUseCount, Windows.Foundation.UniversalApiContract, 1.0),
        static(Windows.ApplicationModel.Core.ICoreImmersiveApplication, Windows.Foundation.UniversalApiContract, 1.0),
        static(Windows.ApplicationModel.Core.ICoreImmersiveApplication2, Windows.Foundation.UniversalApiContract, 1.0),
        static(Windows.ApplicationModel.Core.ICoreImmersiveApplication3, Windows.Foundation.UniversalApiContract, 1.0)
    ]
    runtimeclass CoreApplication
    {
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(standard)
    ]
    runtimeclass CoreApplicationView
    {
        [default] interface Windows.ApplicationModel.Core.ICoreApplicationView;
        [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.ApplicationModel.Core.ICoreApplicationView2;
        [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.ApplicationModel.Core.ICoreApplicationView3;
        [contract(Windows.Foundation.UniversalApiContract, 4.0)] interface Windows.ApplicationModel.Core.ICoreApplicationView5;
        [contract(Windows.Foundation.UniversalApiContract, 5.0)] interface Windows.ApplicationModel.Core.ICoreApplicationView6;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(standard)
    ]
    runtimeclass CoreApplicationViewTitleBar
    {
        [default] interface Windows.ApplicationModel.Core.ICoreApplicationViewTitleBar;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass HostedViewClosingEventArgs
    {
        [default] interface Windows.ApplicationModel.Core.IHostedViewClosingEventArgs;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass UnhandledError
    {
        [default] interface Windows.ApplicationModel.Core.IUnhandledError;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass UnhandledErrorDetectedEventArgs
    {
        [default] interface Windows.ApplicationModel.Core.IUnhandledErrorDetectedEventArgs;
    }
}
