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

#ifndef DO_NO_IMPORTS
import "inspectable.idl";
import "asyncinfo.idl";
import "eventtoken.idl";
import "windowscontracts.idl";
import "windows.foundation.idl";
import "windows.globalization.idl";
#endif

namespace Windows.System.UserProfile {

    interface IAdvertisingManagerStatics;
    interface IAdvertisingManagerStatics2;
    interface IGlobalizationPreferencesStatics;
    interface IGlobalizationPreferencesStatics2;
    interface IGlobalizationPreferencesStatics3;
    runtimeclass AdvertisingManager;
    runtimeclass GlobalizationPreferences;

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.System.UserProfile.GlobalizationPreferences),
        uuid(01bf4326-ed37-4e96-b0e9-c1340d1ea158)
    ]
    interface IGlobalizationPreferencesStatics : IInspectable
    {
        [propget] HRESULT Calendars([out, retval] Windows.Foundation.Collections.IVectorView<HSTRING> **value);
        [propget] HRESULT Clocks([out, retval] Windows.Foundation.Collections.IVectorView<HSTRING> **value);
        [propget] HRESULT Currencies([out, retval] Windows.Foundation.Collections.IVectorView<HSTRING> **value);
        [propget] HRESULT Languages([out, retval] Windows.Foundation.Collections.IVectorView<HSTRING> **value);
        [propget] HRESULT HomeGeographicRegion([out, retval] HSTRING *value);
        [propget] HRESULT WeekStartsOn([out, retval] Windows.Globalization.DayOfWeek *value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.System.UserProfile.AdvertisingManager),
        uuid(add3468c-a273-48cb-b346-3544522d5581),
    ]
    interface IAdvertisingManagerStatics : IInspectable
    {
        [propget] HRESULT AdvertisingId([out, retval] HSTRING *value);
    }

#ifndef _TWINAPI_APPCORE
    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile),
        static(Windows.System.UserProfile.IGlobalizationPreferencesStatics, Windows.Foundation.UniversalApiContract, 1.0),
        static(Windows.System.UserProfile.IGlobalizationPreferencesStatics2, Windows.Foundation.UniversalApiContract, 5.0),
        static(Windows.System.UserProfile.IGlobalizationPreferencesStatics3, Windows.Foundation.UniversalApiContract, 6.0),
    ]
    runtimeclass GlobalizationPreferences
    {
    }
#endif

#ifndef _WINDOWS_GLOBALIZATION
    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(standard),
        static(Windows.System.UserProfile.IAdvertisingManagerStatics, Windows.Foundation.UniversalApiContract, 1.0),
        static(Windows.System.UserProfile.IAdvertisingManagerStatics2, Windows.Foundation.UniversalApiContract, 3.0),
    ]
    runtimeclass AdvertisingManager
    {
    }
#endif

}
