namespace Windows.Devices.Geolocation
{
    public sealed class CivicAddress : ICivicAddress
    {
        // Properties
        public string City { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public string Country { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public string PostalCode { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public string State { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public DateTime TimeStamp { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public string Windows.Devices.Geolocation.ICivicAddress.City { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public string Windows.Devices.Geolocation.ICivicAddress.Country { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public string Windows.Devices.Geolocation.ICivicAddress.PostalCode { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public string Windows.Devices.Geolocation.ICivicAddress.State { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public DateTime Windows.Devices.Geolocation.ICivicAddress.TimeStamp { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
    }

    public sealed class Geocoordinate : IGeocoordinate
    {
        // Properties
        public double Accuracy { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double Altitude { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double AltitudeAccuracy { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double Heading { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double Latitude { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double Longitude { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double Speed { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public DateTime TimeStamp { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double Windows.Devices.Geolocation.IGeocoordinate.Accuracy { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double Windows.Devices.Geolocation.IGeocoordinate.Altitude { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double Windows.Devices.Geolocation.IGeocoordinate.AltitudeAccuracy { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double Windows.Devices.Geolocation.IGeocoordinate.Heading { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double Windows.Devices.Geolocation.IGeocoordinate.Latitude { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double Windows.Devices.Geolocation.IGeocoordinate.Longitude { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double Windows.Devices.Geolocation.IGeocoordinate.Speed { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public DateTime Windows.Devices.Geolocation.IGeocoordinate.TimeStamp { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
    }

    public sealed class Geolocator : IGeolocator
    {
        // Events
        public event PositionChangedHandler PositionChanged;
        public event StatusChangedHandler StatusChanged;
        public event PositionChangedHandler Windows.Devices.Geolocation.IGeolocator.PositionChanged;
        public event StatusChangedHandler Windows.Devices.Geolocation.IGeolocator.StatusChanged;

        // Methods
        [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)]
        public Geolocator();
        [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)]
        public GetGeopositionOperation GetGeopositionAsync();

        // Properties
        public PositionAccuracy DesiredAccuracy { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; [param: In] [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] set; }
        public PositionStatus LocationStatus { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double MovementThreshold { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; [param: In] [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] set; }
        public uint ReportInterval { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; [param: In] [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] set; }
        public PositionAccuracy Windows.Devices.Geolocation.IGeolocator.DesiredAccuracy { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; [param: In] [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] set; }
        public PositionStatus Windows.Devices.Geolocation.IGeolocator.LocationStatus { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public double Windows.Devices.Geolocation.IGeolocator.MovementThreshold { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; [param: In] [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] set; }
        public uint Windows.Devices.Geolocation.IGeolocator.ReportInterval { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; [param: In] [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] set; }
    }

    public sealed class Geoposition : IGeoposition
    {
        // Properties
        public CivicAddress CivicAddress { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public Geocoordinate Coordinate { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public CivicAddress Windows.Devices.Geolocation.IGeoposition.CivicAddress { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public Geocoordinate Windows.Devices.Geolocation.IGeoposition.Coordinate { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
    }

    public delegate void GetGeopositionCompletedHandler([In] IGetGeopositionOperation asyncInfo);

    public sealed class GetGeopositionOperation : IGetGeopositionOperation, IAsyncInfo
    {
        // Methods
        [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)]
        public void Cancel();
        [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)]
        public void Close();
        [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)]
        public Geoposition GetResults();
        [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)]
        public void Start();

        // Properties
        public GetGeopositionCompletedHandler Completed { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; [param: In] [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] set; }
        public HResult ErrorCode { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public uint Id { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public AsyncStatus Status { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public GetGeopositionCompletedHandler Windows.Devices.Geolocation.IGetGeopositionOperation.Completed { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; [param: In] [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] set; }
        public HResult Windows.Foundation.IAsyncInfo.ErrorCode { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public uint Windows.Foundation.IAsyncInfo.Id { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public AsyncStatus Windows.Foundation.IAsyncInfo.Status { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
    }

    public interface ICivicAddress
    {
        // Properties
        string City { get; }
        string Country { get; }
        string PostalCode { get; }
        string State { get; }
        DateTime TimeStamp { get; }
    }

    public interface IGeocoordinate
    {
        // Properties
        double Accuracy { get; }
        double Altitude { get; }
        double AltitudeAccuracy { get; }
        double Heading { get; }
        double Latitude { get; }
        double Longitude { get; }
        double Speed { get; }
        DateTime TimeStamp { get; }
    }

    public interface IGeolocator
    {
        // Events
        event PositionChangedHandler PositionChanged;
        event StatusChangedHandler StatusChanged;

        // Methods
        GetGeopositionOperation GetGeopositionAsync();

        // Properties
        PositionAccuracy DesiredAccuracy { get; [param: In] set; }
        PositionStatus LocationStatus { get; }
        double MovementThreshold { get; [param: In] set; }
        uint ReportInterval { get; [param: In] set; }
    }

    public interface IGeoposition
    {
        // Properties
        CivicAddress CivicAddress { get; }
        Geocoordinate Coordinate { get; }
    }

    public interface IGetGeopositionOperation : IAsyncInfo
    {
        // Methods
        Geoposition GetResults();

        // Properties
        GetGeopositionCompletedHandler Completed { get; [param: In] set; }
    }

    public interface IPositionChangedEventArgs
    {
        // Properties
        Geoposition Position { get; }
    }

    public interface IStatusChangedEventArgs
    {
        // Properties
        PositionStatus Status { get; }
    }

    public enum PositionAccuracy
    {
        Default,
        High
    }

    public sealed class PositionChangedEventArgs : IPositionChangedEventArgs
    {
        // Properties
        public Geoposition Position { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public Geoposition Windows.Devices.Geolocation.IPositionChangedEventArgs.Position { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
    }

    public delegate void PositionChangedHandler([In] Geolocator sender, [In] PositionChangedEventArgs e);

    public enum PositionStatus
    {
        Ready,
        Initializing,
        NoData,
        Disabled
    }

    public sealed class StatusChangedEventArgs : IStatusChangedEventArgs
    {
        // Properties
        public PositionStatus Status { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
        public PositionStatus Windows.Devices.Geolocation.IStatusChangedEventArgs.Status { [MethodImpl(0x0, MethodCodeType=MethodCodeType.Runtime)] get; }
    }

    public delegate void StatusChangedHandler([In] Geolocator sender, [In] StatusChangedEventArgs e);
}