/*
 * Copyright 2024 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.applicationmodel.idl";
import "windows.applicationmodel.activation.idl";
import "windows.applicationmodel.core.idl";
import "windows.foundation.numerics.idl";
import "windows.graphics.imaging.idl";
import "windows.ui.idl";
import "windows.ui.composition.idl";
import "windows.ui.core.idl";
import "windows.ui.input.idl";
import "windows.ui.xaml.interop.idl";

namespace Windows.UI.Xaml {
    interface IDataTemplateKey;
    interface IDependencyObject;
    interface IDependencyProperty;
    interface IDependencyPropertyChangedEventArgs;
    interface IDependencyPropertyStatics;
    interface IPropertyMetadata;
    interface IPropertyMetadataFactory;
    interface IPropertyMetadataStatics;

    runtimeclass DataTemplateKey;
    runtimeclass DependencyObject;
    runtimeclass DependencyProperty;
    runtimeclass DependencyPropertyChangedEventArgs;
    runtimeclass PropertyMetadata;

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        uuid(d6ecb12c-15b5-4ec8-b95c-cdd208f08153)
    ]
    delegate HRESULT CreateDefaultValueCallback([out, retval] IInspectable **result);

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        uuid(45883d16-27bf-4bc1-ac26-94c1601f3a49)
    ]
    delegate HRESULT DependencyPropertyChangedCallback([in] Windows.UI.Xaml.DependencyObject *sender, [in] Windows.UI.Xaml.DependencyProperty *dp);

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        uuid(5a9f8a25-d142-44a4-8231-fd676724f29b)
    ]
    delegate HRESULT PropertyChangedCallback([in] Windows.UI.Xaml.DependencyObject *obj, [in] Windows.UI.Xaml.DependencyPropertyChangedEventArgs *args);

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Xaml.DataTemplateKey),
        uuid(873b6c28-cceb-4b61-86fa-b2cec39cc2fa)
    ]
    interface IDataTemplateKey : IInspectable
    {
        [propget] HRESULT DataType([out, retval] IInspectable **value);
        [propput] HRESULT DataType([in] IInspectable *value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Xaml.DataTemplateKey),
        uuid(e96b2959-d982-4152-91cb-de0e4dfd7693)
    ]
    interface IDataTemplateKeyFactory : IInspectable
    {
        HRESULT CreateInstance([in] IInspectable *base_interface, [out] IInspectable **inner_interface, [out, retval] Windows.UI.Xaml.DataTemplateKey **value);
        HRESULT CreateInstanceWithType([in] IInspectable *data_type, [in] IInspectable *base_interface, [out] IInspectable **inner_interface, [out, retval] Windows.UI.Xaml.DataTemplateKey **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Xaml.DependencyObject),
        uuid(5c526665-f60e-4912-af59-5fe0680f089d)
    ]
    interface IDependencyObject : IInspectable
    {
        HRESULT GetValue([in] Windows.UI.Xaml.DependencyProperty *dp, [out, retval] IInspectable **result);
        HRESULT SetValue([in] Windows.UI.Xaml.DependencyProperty *dp, [in] IInspectable *value);
        HRESULT ClearValue([in] Windows.UI.Xaml.DependencyProperty *dp);
        HRESULT ReadLocalValue([in] Windows.UI.Xaml.DependencyProperty *dp, [out, retval] IInspectable **result);
        HRESULT GetAnimationBaseValue([in] Windows.UI.Xaml.DependencyProperty *dp, [out, retval] IInspectable **result);
        [propget] HRESULT Dispatcher([out, retval] Windows.UI.Core.CoreDispatcher **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Xaml.DependencyObject),
        uuid(29fed85d-3d22-43a1-add0-17027c08b212)
    ]
    interface IDependencyObject2 : IInspectable
    {
        HRESULT RegisterPropertyChangedCallback([in] Windows.UI.Xaml.DependencyProperty *dp, [in] Windows.UI.Xaml.DependencyPropertyChangedCallback *callback, [out, retval] INT64 *result);
        HRESULT UnregisterPropertyChangedCallback([in] Windows.UI.Xaml.DependencyProperty *dp, [in] INT64 token);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Xaml.DependencyObject),
        uuid(9a03af92-7d8a-4937-884f-ecf34fe02acb)
    ]
    interface IDependencyObjectFactory : IInspectable
    {
        HRESULT CreateInstance([in] IInspectable *base_interface, [out] IInspectable **inner_interface, [out, retval] Windows.UI.Xaml.DependencyObject **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Xaml.DependencyProperty),
        uuid(85b13970-9bc4-4e96-acf1-30c8fd3d55c8)
    ]
    interface IDependencyProperty : IInspectable
    {
        HRESULT GetMetadata([in] Windows.UI.Xaml.Interop.TypeName type, [out, retval] Windows.UI.Xaml.PropertyMetadata **result);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Xaml.DependencyPropertyChangedEventArgs),
        uuid(81212c2b-24d0-4957-abc3-224470a93a4e)
    ]
    interface IDependencyPropertyChangedEventArgs : IInspectable
    {
        [propget] HRESULT Property([out, retval] Windows.UI.Xaml.DependencyProperty **value);
        [propget] HRESULT OldValue([out, retval] IInspectable **value);
        [propget] HRESULT NewValue([out, retval] IInspectable **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Xaml.DependencyProperty),
        uuid(49e5f28f-8259-4d5c-aae0-83d56dbb68d9)
    ]
    interface IDependencyPropertyStatics : IInspectable
    {
        [propget] HRESULT UnsetValue([out, retval] IInspectable **value);
        HRESULT Register([in] HSTRING name, [in] Windows.UI.Xaml.Interop.TypeName property_type, [in] Windows.UI.Xaml.Interop.TypeName owner_type, [in] Windows.UI.Xaml.PropertyMetadata *type_metadata, [out, retval] Windows.UI.Xaml.DependencyProperty **result);
        HRESULT RegisterAttached([in] HSTRING name, [in] Windows.UI.Xaml.Interop.TypeName property_type, [in] Windows.UI.Xaml.Interop.TypeName owner_type, [in] Windows.UI.Xaml.PropertyMetadata *default_metadata, [out, retval] Windows.UI.Xaml.DependencyProperty **result);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Xaml.PropertyMetadata),
        uuid(814ef30d-8d18-448a-8644-f2cb51e70380)
    ]
    interface IPropertyMetadata : IInspectable
    {
        [propget] HRESULT DefaultValue([out, retval] IInspectable **value);
        [propget] HRESULT CreateDefaultValueCallback([out, retval] Windows.UI.Xaml.CreateDefaultValueCallback **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Xaml.PropertyMetadata),
        uuid(c1b81cc0-57cd-4f2f-b0a9-e1801b28f76b)
    ]
    interface IPropertyMetadataFactory : IInspectable
    {
        HRESULT CreateInstanceWithDefaultValue([in] IInspectable *default_value, [in] IInspectable *base_interface, [out] IInspectable **inner_interface, [out, retval] Windows.UI.Xaml.PropertyMetadata **value);
        HRESULT CreateInstanceWithDefaultValueAndCallback([in] IInspectable *default_value, [in] Windows.UI.Xaml.PropertyChangedCallback *property_changed_callback, [in] IInspectable* base_interface, [out] IInspectable **inner_interface, [out, retval] Windows.UI.Xaml.PropertyMetadata **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Xaml.PropertyMetadata),
        uuid(3b01077a-6e06-45e9-8b5c-af243458c062)
    ]
    interface IPropertyMetadataStatics : IInspectable
    {
        [default_overload] [overload("Create")] HRESULT CreateWithDefaultValue([in] IInspectable *default_value, [out, retval] Windows.UI.Xaml.PropertyMetadata **result);
        [default_overload] [overload("Create")] HRESULT CreateWithDefaultValueAndCallback([in] IInspectable *default_value, [in] Windows.UI.Xaml.PropertyChangedCallback *property_changed_callback, [out, retval] Windows.UI.Xaml.PropertyMetadata **result);
        [overload("Create")] HRESULT CreateWithFactory([in] Windows.UI.Xaml.CreateDefaultValueCallback *create_default_value_callback, [out, retval] Windows.UI.Xaml.PropertyMetadata **result);
        [overload("Create")] HRESULT CreateWithFactoryAndCallback([in] Windows.UI.Xaml.CreateDefaultValueCallback *create_default_value_callback, [in] Windows.UI.Xaml.PropertyChangedCallback *property_changed_callback, [out, retval] Windows.UI.Xaml.PropertyMetadata **result);
    }


    [
        composable(Windows.UI.Xaml.IDataTemplateKeyFactory, public, Windows.Foundation.UniversalApiContract, 1.0),
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile),
        threading(both)
    ]
    runtimeclass DataTemplateKey
    {
        [default] interface Windows.UI.Xaml.IDataTemplateKey;
    }

    [
        composable(Windows.UI.Xaml.IDependencyObjectFactory, protected, Windows.Foundation.UniversalApiContract, 1.0),
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile),
        threading(both)
    ]
    runtimeclass DependencyObject
    {
        [default] interface Windows.UI.Xaml.IDependencyObject;
        [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.UI.Xaml.IDependencyObject2;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile),
        static(Windows.UI.Xaml.IDependencyPropertyStatics, Windows.Foundation.UniversalApiContract, 1.0),
        threading(both)
    ]
    runtimeclass DependencyProperty
    {
        [default] interface Windows.UI.Xaml.IDependencyProperty;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass DependencyPropertyChangedEventArgs
    {
        [default] interface Windows.UI.Xaml.IDependencyPropertyChangedEventArgs;
    }

    [
        composable(Windows.UI.Xaml.IPropertyMetadataFactory, public, Windows.Foundation.UniversalApiContract, 1.0),
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile),
        static(Windows.UI.Xaml.IPropertyMetadataStatics, Windows.Foundation.UniversalApiContract, 1.0),
        threading(both)
    ]
    runtimeclass PropertyMetadata
    {
        [default] interface Windows.UI.Xaml.IPropertyMetadata;
    }
}
