/*
 * Copyright 2022 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 "windowscontracts.idl";

namespace Windows.Foundation.Collections {
    [contract(Windows.Foundation.FoundationContract, 1.0)]
    enum CollectionChange
    {
        Reset = 0,
        ItemInserted = 1,
        ItemRemoved = 2,
        ItemChanged = 3,
    };
    typedef enum CollectionChange CollectionChange;

    [
        contract(Windows.Foundation.FoundationContract, 1.0),
        uuid(575933df-34fe-4480-af15-07691f3d5d9b),
        pointer_default(unique),
        version(0x06020000 /* NTDDI_WIN8 */),
        object,
    ]
    interface IVectorChangedEventArgs : IInspectable
    {
        [propget] HRESULT CollectionChange([out, retval] CollectionChange *value);
        [propget] HRESULT Index([out, retval] unsigned *value);
    };
}
