/*
 * 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] 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] AsyncOperationCompletedHandler<TResult> *handler);
            [propget] HRESULT Completed([out, retval] 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);

        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 count, [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(bbe1fa4c-b0e3-4583-baef-1f1b2e483e56)
            ]
            interface IVectorView<T> : IInspectable
            {
                HRESULT GetAt([in] ULONG index, [out, retval] T *value);
                [propget] HRESULT Size([out, retval] ULONG *value);
                HRESULT IndexOf([in, optional] T element, [out] ULONG *index, [out, retval] BOOLEAN *value);
                HRESULT GetMany([in] ULONG start_index, [out] T *items, [out, retval] ULONG *value);
            }
        }
#endif
    }
}
