/*
 * Copyright 2023 Fabian Maurer
 *
 * 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";
#endif

namespace Windows.Devices.Geolocation {

    typedef enum PositionAccuracy PositionAccuracy;
    typedef enum PositionStatus PositionStatus;

    interface IGeolocator;
    interface IGeoposition;
    interface IGeocoordinate;
    interface IPositionChangedEventArgs;
    interface IStatusChangedEventArgs;
    interface ICivicAddress;

    runtimeclass Geolocator;
    runtimeclass Geoposition;
    runtimeclass Geocoordinate;
    runtimeclass PositionChangedEventArgs;
    runtimeclass StatusChangedEventArgs;
    runtimeclass CivicAddress;

    declare {
        interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Devices.Geolocation.Geoposition*>;
        interface Windows.Foundation.IAsyncOperation<Windows.Devices.Geolocation.Geoposition*>;
        interface Windows.Foundation.TypedEventHandler<Windows.Devices.Geolocation.Geolocator*, Windows.Devices.Geolocation.PositionChangedEventArgs*>;
        interface Windows.Foundation.TypedEventHandler<Windows.Devices.Geolocation.Geolocator*, Windows.Devices.Geolocation.StatusChangedEventArgs*>;
    }

    [contract(Windows.Foundation.UniversalApiContract, 1.0)]
    enum PositionAccuracy
    {
        Default = 0,
        High    = 1,
    };

    [contract(Windows.Foundation.UniversalApiContract, 1.0)]
    enum PositionStatus
    {
        Ready          = 0,
        Initializing   = 1,
        NoData         = 2,
        Disabled       = 3,
        NotInitialized = 4,
        NotAvailable   = 5,
    };

    /* Interfaces */

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Devices.Geolocation.Geolocator),
        uuid(a9c3bf62-4524-4989-8aa9-de019d2e551f)
    ]
    interface IGeolocator : IInspectable
    {
        [propget] HRESULT DesiredAccuracy([out, retval] Windows.Devices.Geolocation.PositionAccuracy *value);
        [propput] HRESULT DesiredAccuracy([in] Windows.Devices.Geolocation.PositionAccuracy value);
        [propget] HRESULT MovementThreshold([out, retval] DOUBLE *value);
        [propput] HRESULT MovementThreshold([in] DOUBLE value);
        [propget] HRESULT ReportInterval([out, retval] UINT32 *value);
        [propput] HRESULT ReportInterval([in] UINT32 value);
        [propget] HRESULT LocationStatus([out, retval] Windows.Devices.Geolocation.PositionStatus *value);
        [overload("GetGeopositionAsync")]
        HRESULT GetGeopositionAsync([out, retval] Windows.Foundation.IAsyncOperation<Windows.Devices.Geolocation.Geoposition*> **value);
        [overload("GetGeopositionAsync")]
        HRESULT GetGeopositionAsyncWithAgeAndTimeout([in] Windows.Foundation.TimeSpan maximum_age,
                [in] Windows.Foundation.TimeSpan timeout,
                [out, retval] Windows.Foundation.IAsyncOperation<Windows.Devices.Geolocation.Geoposition*> **value);
        [eventadd] HRESULT PositionChanged([in] Windows.Foundation.TypedEventHandler<Windows.Devices.Geolocation.Geolocator*, Windows.Devices.Geolocation.PositionChangedEventArgs*> *handler,
                [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT PositionChanged([in] EventRegistrationToken token);
        [eventadd] HRESULT StatusChanged([in] Windows.Foundation.TypedEventHandler<Windows.Devices.Geolocation.Geolocator*, Windows.Devices.Geolocation.StatusChangedEventArgs*> *handler,
                [out, retval] EventRegistrationToken *token);
        [eventremove] HRESULT StatusChanged([in] EventRegistrationToken token);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Devices.Geolocation.Geoposition),
        uuid(c18d0454-7d41-4ff7-a957-9dffb4ef7f5b)
    ]
    interface IGeoposition : IInspectable
    {
        [propget] HRESULT Coordinate([out, retval] Windows.Devices.Geolocation.Geocoordinate **value);
        [propget] HRESULT CivicAddress([out, retval] Windows.Devices.Geolocation.CivicAddress **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Devices.Geolocation.Geocoordinate),
        uuid(ee21a3aa-976a-ac70-803d-083ea55bcbc4)
    ]
    interface IGeocoordinate : IInspectable
    {
        [deprecated("Use Point.Position.Latitude", deprecate, Windows.Foundation.UniversalApiContract, 1.0)]
        [propget] HRESULT Latitude([out, retval] DOUBLE *value);
        [deprecated("Use Point.Position.Longitude", deprecate, Windows.Foundation.UniversalApiContract, 1.0)]
        [propget] HRESULT Longitude([out, retval] DOUBLE *value);
        [deprecated("Use Point.Position.Altitude", deprecate, Windows.Foundation.UniversalApiContract, 1.0)]
        [propget] HRESULT Altitude([out, retval] Windows.Foundation.IReference<DOUBLE> **value);
        [propget] HRESULT Accuracy([out, retval] DOUBLE *value);
        [propget] HRESULT AltitudeAccuracy([out, retval] Windows.Foundation.IReference<DOUBLE> **value);
        [propget] HRESULT Heading([out, retval] Windows.Foundation.IReference<DOUBLE> **value);
        [propget] HRESULT Speed([out, retval] Windows.Foundation.IReference<DOUBLE> **value);
        [propget] HRESULT Timestamp([out, retval] Windows.Foundation.DateTime *value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Devices.Geolocation.PositionChangedEventArgs),
        uuid(37859ce5-9d1e-46c5-bf3b-6ad8cac1a093)
    ]
    interface IPositionChangedEventArgs : IInspectable
    {
        [propget] HRESULT Position([out, retval] Windows.Devices.Geolocation.Geoposition **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Devices.Geolocation.StatusChangedEventArgs),
        uuid(3453d2da-8c93-4111-a205-9aecfc9be5c0)
    ]
    interface IStatusChangedEventArgs : IInspectable
    {
        [propget] HRESULT Status([out, retval] Windows.Devices.Geolocation.PositionStatus *value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Devices.Geolocation.CivicAddress),
        uuid(a8567a1a-64f4-4d48-bcea-f6b008eca34c)
    ]
    interface ICivicAddress : IInspectable
    {
        [propget] HRESULT Country([out, retval] HSTRING *value);
        [propget] HRESULT State([out, retval] HSTRING *value);
        [propget] HRESULT City([out, retval] HSTRING *value);
        [propget] HRESULT PostalCode([out, retval] HSTRING *value);
        [propget] HRESULT Timestamp([out, retval] Windows.Foundation.DateTime *value);
    }

    /* Runtime Classes */

    [
        activatable(Windows.Foundation.UniversalApiContract, 1.0),
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile),
        threading(both)
    ]
    runtimeclass Geolocator
    {
        [default] interface Windows.Devices.Geolocation.IGeolocator;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass Geoposition
    {
        [default] interface Windows.Devices.Geolocation.IGeoposition;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass Geocoordinate
    {
        [default] interface Windows.Devices.Geolocation.IGeocoordinate;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass PositionChangedEventArgs
    {
        [default] interface Windows.Devices.Geolocation.IPositionChangedEventArgs;
    }

    [
        marshaling_behavior(agile)
    ]
    runtimeclass StatusChangedEventArgs
    {
        [default] interface Windows.Devices.Geolocation.IStatusChangedEventArgs;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass CivicAddress
    {
        [default] interface Windows.Devices.Geolocation.ICivicAddress;
    }
}
