/*
 * Copyright 2025 Zhiyi Zhang 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.system.idl";
import "windows.ui.idl";
import "windows.ui.composition.idl";

namespace Windows.UI.WindowManagement
{
    typedef enum WindowingEnvironmentKind WindowingEnvironmentKind;

    interface IDisplayRegion;
    interface IWindowingEnvironment;
    interface IWindowingEnvironmentAddedEventArgs;
    interface IWindowingEnvironmentChangedEventArgs;
    interface IWindowingEnvironmentRemovedEventArgs;
    interface IWindowingEnvironmentStatics;

    runtimeclass DisplayRegion;
    runtimeclass WindowingEnvironment;
    runtimeclass WindowingEnvironmentAddedEventArgs;
    runtimeclass WindowingEnvironmentChangedEventArgs;
    runtimeclass WindowingEnvironmentRemovedEventArgs;

    declare {
        interface Windows.Foundation.Collections.IIterable<Windows.UI.WindowManagement.DisplayRegion *>;
        interface Windows.Foundation.Collections.IIterable<Windows.UI.WindowManagement.WindowingEnvironment *>;
        interface Windows.Foundation.Collections.IIterator<Windows.UI.WindowManagement.DisplayRegion *>;
        interface Windows.Foundation.Collections.IIterator<Windows.UI.WindowManagement.WindowingEnvironment *>;
        interface Windows.Foundation.Collections.IVectorView<Windows.UI.WindowManagement.DisplayRegion *>;
        interface Windows.Foundation.Collections.IVectorView<Windows.UI.WindowManagement.WindowingEnvironment *>;
        interface Windows.Foundation.TypedEventHandler<Windows.UI.WindowManagement.DisplayRegion *, IInspectable *>;
        interface Windows.Foundation.TypedEventHandler<Windows.UI.WindowManagement.WindowingEnvironment *, Windows.UI.WindowManagement.WindowingEnvironmentChangedEventArgs *>;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 8.0)
    ]
    enum WindowingEnvironmentKind
    {
        Unknown = 0,
        Overlapped = 1,
        Tiled = 2,
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 8.0),
        exclusiveto(Windows.UI.WindowManagement.DisplayRegion),
        uuid(db50c3a2-4094-5f47-8cb1-ea01ddafaa94)
    ]
    interface IDisplayRegion : IInspectable
    {
        [propget] HRESULT DisplayMonitorDeviceId([out, retval] HSTRING *value);
        [propget] HRESULT IsVisible([out, retval] boolean *value);
        [propget] HRESULT WorkAreaOffset([out, retval] Windows.Foundation.Point *value);
        [propget] HRESULT WorkAreaSize([out, retval] Windows.Foundation.Size *value);
        [propget] HRESULT WindowingEnvironment([out, retval] Windows.UI.WindowManagement.WindowingEnvironment **value);
        [eventadd] HRESULT Changed([in] Windows.Foundation.TypedEventHandler<Windows.UI.WindowManagement.DisplayRegion *, IInspectable *> *handler, [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT Changed([in] EventRegistrationToken token);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 8.0),
        exclusiveto(Windows.UI.WindowManagement.WindowingEnvironment),
        uuid(264363c0-2a49-5417-b3ae-48a71c63a3bd)
    ]
    interface IWindowingEnvironment : IInspectable
    {
        [propget] HRESULT IsEnabled([out, retval] boolean *value);
        [propget] HRESULT Kind([out, retval] Windows.UI.WindowManagement.WindowingEnvironmentKind *value);
        HRESULT GetDisplayRegions([out, retval] Windows.Foundation.Collections.IVectorView<Windows.UI.WindowManagement.DisplayRegion *> **result);
        [eventadd] HRESULT Changed([in] Windows.Foundation.TypedEventHandler<Windows.UI.WindowManagement.WindowingEnvironment *, Windows.UI.WindowManagement.WindowingEnvironmentChangedEventArgs *> *handler, [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT Changed([in] EventRegistrationToken token);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 8.0),
        exclusiveto(Windows.UI.WindowManagement.WindowingEnvironmentAddedEventArgs),
        uuid(ff2a5b7f-f183-5c66-99b2-429082069299)
    ]
    interface IWindowingEnvironmentAddedEventArgs : IInspectable
    {
        [propget] HRESULT WindowingEnvironment([out, retval] Windows.UI.WindowManagement.WindowingEnvironment **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 8.0),
        exclusiveto(Windows.UI.WindowManagement.WindowingEnvironmentChangedEventArgs),
        uuid(4160cfc6-023d-5e9a-b431-350e67dc978a)
    ]
    interface IWindowingEnvironmentChangedEventArgs : IInspectable
    {
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 8.0),
        exclusiveto(Windows.UI.WindowManagement.WindowingEnvironmentRemovedEventArgs),
        uuid(2e5b5473-beff-5e53-9316-7e775fe568b3)
    ]
    interface IWindowingEnvironmentRemovedEventArgs : IInspectable
    {
        [propget] HRESULT WindowingEnvironment([out, retval] Windows.UI.WindowManagement.WindowingEnvironment **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 8.0),
        exclusiveto(Windows.UI.WindowManagement.WindowingEnvironment),
        uuid(874e9fb7-c642-55ab-8aa2-162f734a9a72)
    ]
    interface IWindowingEnvironmentStatics : IInspectable
    {
        [overload("FindAll")] HRESULT FindAll([out, retval] Windows.Foundation.Collections.IVectorView<Windows.UI.WindowManagement.WindowingEnvironment *> **result);
        [overload("FindAll")] HRESULT FindAllWithKind([in] Windows.UI.WindowManagement.WindowingEnvironmentKind kind, [out, retval] Windows.Foundation.Collections.IVectorView<Windows.UI.WindowManagement.WindowingEnvironment *> **result);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 8.0),
        marshaling_behavior(agile)
    ]
    runtimeclass DisplayRegion
    {
        [default] interface Windows.UI.WindowManagement.IDisplayRegion;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 8.0),
        marshaling_behavior(agile),
        static(Windows.UI.WindowManagement.IWindowingEnvironmentStatics, Windows.Foundation.UniversalApiContract, 8.0),
        threading(both)
    ]
    runtimeclass WindowingEnvironment
    {
        [default] interface Windows.UI.WindowManagement.IWindowingEnvironment;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 8.0),
        marshaling_behavior(agile)
    ]
    runtimeclass WindowingEnvironmentAddedEventArgs
    {
        [default] interface Windows.UI.WindowManagement.IWindowingEnvironmentAddedEventArgs;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 8.0),
        marshaling_behavior(agile)
    ]
    runtimeclass WindowingEnvironmentChangedEventArgs
    {
        [default] interface Windows.UI.WindowManagement.IWindowingEnvironmentChangedEventArgs;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 8.0),
        marshaling_behavior(agile)
    ]
    runtimeclass WindowingEnvironmentRemovedEventArgs
    {
        [default] interface Windows.UI.WindowManagement.IWindowingEnvironmentRemovedEventArgs;
    }
}
