/*
 * 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);

        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
    }
}
