/*
 * 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 "windowscontracts.idl";
/* import "eventtoken.idl"; */

namespace Windows {
    namespace Foundation {

cpp_quote("#ifdef __cplusplus")
cpp_quote("} /* extern \"C\" */")
cpp_quote("namespace ABI { namespace Windows { namespace Foundation { namespace Internal {")
cpp_quote("template <class T> struct GetAbiType { typedef T type; };")
cpp_quote("template <class T> struct GetLogicalType { typedef T type; };")
cpp_quote("template <class L, class A> struct AggregateType {};")
cpp_quote("template <class L, class A> struct GetAbiType<AggregateType<L, A> > { typedef A type; };")
cpp_quote("template <class L, class A> struct GetLogicalType<AggregateType<L, A> > { typedef L type; };")
cpp_quote("}}}}")
cpp_quote("extern \"C\" {")
cpp_quote("#endif")

#ifdef __WIDL__
        [
            contract(Windows.Foundation.FoundationContract, 1.0),
            uuid(9de1c535-6ae1-11e0-84e1-18a905bcc53f)
        ]
        delegate HRESULT EventHandler<T>([in] IInspectable *sender, [in] T args);

        interface IAsyncOperation<TResult>;

        [
            contract(Windows.Foundation.FoundationContract, 1.0),
            uuid(fcdcf02c-e5d8-4478-915a-4d90b74b83a5)
        ]
        delegate HRESULT AsyncOperationCompletedHandler<TResult>([in] Windows.Foundation.IAsyncOperation<TResult> *info,
                                                                 [in] AsyncStatus status);

        [
            contract(Windows.Foundation.FoundationContract, 1.0),
            uuid(9fc2b0bb-e446-44e2-aa61-9cab8f636af2)
        ]
        interface IAsyncOperation<TResult> : IInspectable
        {
            [propput] HRESULT Completed([in] Windows.Foundation.AsyncOperationCompletedHandler<TResult> *handler);
            [propget] HRESULT Completed([out, retval] Windows.Foundation.AsyncOperationCompletedHandler<TResult> **handler);
            HRESULT GetResults([out, retval] TResult *results);
        }

        [
            contract(Windows.Foundation.FoundationContract, 1.0),
            uuid(9de1c534-6ae1-11e0-84e1-18a905bcc53f)
        ]
        delegate HRESULT TypedEventHandler<TSender, TArgs>([in] TSender sender, [in] TArgs args);

        [
            contract(Windows.Foundation.FoundationContract, 1.0),
            uuid(61c17706-2d65-11e0-9ae8-d48564015472)
        ]
        interface IReference<T> : IInspectable
        {
            [propget] HRESULT Value([out, retval] T *value);
        }

        namespace Collections
        {
            [
                contract(Windows.Foundation.FoundationContract, 1.0),
                uuid(6a79e863-4300-459a-9966-cbb660963ee1)
            ]
            interface IIterator<T> : IInspectable
            {
                [propget] HRESULT Current([out, retval] T *value);
                [propget] HRESULT HasCurrent([out, retval] BOOL *value);
                HRESULT MoveNext([out, retval] BOOL *value);
                HRESULT GetMany([in] UINT32 items_size, [out] T *items, [out, retval] UINT32 *value);
            }

            [
                contract(Windows.Foundation.FoundationContract, 1.0),
                uuid(faa585ea-6214-4217-afda-7f46de5869b3)
            ]
            interface IIterable<T> : IInspectable
            {
                HRESULT First([out, retval] Windows.Foundation.Collections.IIterator<T> **value);
            }

            [
                contract(Windows.Foundation.FoundationContract, 1.0),
                uuid(02b51929-c1c4-4a7e-8940-0312b5c18500)
            ]
            interface IKeyValuePair<K, V> : IInspectable
            {
                [propget] HRESULT Key([out, retval] K *key);
                [propget] HRESULT Value([out, retval] V *value);
            }

            [
                contract(Windows.Foundation.FoundationContract, 1.0),
                uuid(e480ce40-a338-4ada-adcf-272272e48cb9)
            ]
            interface IMapView<K, V> : IInspectable
                requires Windows.Foundation.Collections.IIterable<Windows.Foundation.Collections.IKeyValuePair<K, V> *>
            {
                HRESULT Lookup([in] K key, [out, retval] V *value);
                [propget] HRESULT Size([out, retval] unsigned int *size);
                HRESULT HasKey([in] K key, [out, retval] boolean *found);
                HRESULT Split([out] Windows.Foundation.Collections.IMapView<K, V> **first,
                              [out] Windows.Foundation.Collections.IMapView<K, V> **second);
            }

            [
                contract(Windows.Foundation.FoundationContract, 1.0),
                uuid(bbe1fa4c-b0e3-4583-baef-1f1b2e483e56)
            ]
            interface IVectorView<T> : IInspectable
                requires Windows.Foundation.Collections.IIterable<T>
            {
                HRESULT GetAt([in] UINT32 index, [out, retval] T *value);
                [propget] HRESULT Size([out, retval] UINT32 *value);
                HRESULT IndexOf([in, optional] T element, [out] UINT32 *index, [out, retval] BOOLEAN *value);
                HRESULT GetMany([in] UINT32 start_index, [in] UINT32 items_size, [out] T *items, [out, retval] UINT32 *value);
            }

            [
                contract(Windows.Foundation.FoundationContract, 1.0),
                uuid(913337e9-11a1-4345-a3a2-4e7f956e222d)
            ]
            interface IVector<T> : IInspectable
                requires Windows.Foundation.Collections.IIterable<T>
            {
                HRESULT GetAt([in, optional] UINT32 index, [out, retval] T *value);
                [propget] HRESULT Size([out, retval] UINT32 *value);
                HRESULT GetView([out, retval] Windows.Foundation.Collections.IVectorView<T> **value);
                HRESULT IndexOf([in, optional] T element, [out] UINT32 *index, [out, retval] BOOLEAN *value);
                HRESULT SetAt([in] UINT32 index, [in, optional] T value);
                HRESULT InsertAt([in] UINT32 index, [in, optional] T value);
                HRESULT RemoveAt([in] UINT32 index);
                HRESULT Append([in, optional] T value);
                HRESULT RemoveAtEnd();
                HRESULT Clear();
                HRESULT GetMany([in] UINT32 start_index, [in] UINT32 items_size, [out] T *items, [out, retval] UINT32 *value);
                HRESULT ReplaceAll([in] UINT32 count, [in] T *items);
            }
        }
#endif
    }
}
