/*
 * 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 makedep header install winmd
#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;
    }
}
