/*
 * Copyright (C) 2023 Mohamad Al-Jaf
 *
 * 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 "eventtoken.idl";
import "windowscontracts.idl";
import "windows.foundation.idl";
import "windows.foundation.numerics.idl";
/* import "windows.perception.idl"; */
import "windows.storage.streams.idl";
/* import "windows.system.remotesystems.idl"; */

namespace Windows.Perception.Spatial {
    typedef enum SpatialPerceptionAccessStatus SpatialPerceptionAccessStatus;
    typedef struct SpatialBoundingBox SpatialBoundingBox;
    typedef struct SpatialBoundingFrustum SpatialBoundingFrustum;
    typedef struct SpatialBoundingOrientedBox SpatialBoundingOrientedBox;
    typedef struct SpatialBoundingSphere SpatialBoundingSphere;

    interface ISpatialBoundingVolume;
    interface ISpatialBoundingVolumeStatics;
    interface ISpatialCoordinateSystem;

    runtimeclass SpatialBoundingVolume;
    runtimeclass SpatialCoordinateSystem;

    declare {
        interface Windows.Foundation.Collections.IIterable<Windows.Perception.Spatial.SpatialBoundingVolume *>;
        interface Windows.Foundation.Collections.IIterator<Windows.Perception.Spatial.SpatialBoundingVolume *>;
        interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Perception.Spatial.SpatialPerceptionAccessStatus>;
        interface Windows.Foundation.IAsyncOperation<Windows.Perception.Spatial.SpatialPerceptionAccessStatus>;
        interface Windows.Foundation.IReference<Windows.Perception.Spatial.SpatialBoundingBox>;
        interface Windows.Foundation.IReference<Windows.Perception.Spatial.SpatialBoundingFrustum>;
        interface Windows.Foundation.IReference<Windows.Perception.Spatial.SpatialBoundingOrientedBox>;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 2.0)
    ]
    enum SpatialPerceptionAccessStatus
    {
        Unspecified    = 0,
        Allowed        = 1,
        DeniedByUser   = 2,
        DeniedBySystem = 3,
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 2.0)
    ]
    struct SpatialBoundingBox
    {
        Windows.Foundation.Numerics.Vector3 Center;
        Windows.Foundation.Numerics.Vector3 Extents;
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 2.0)
    ]
    struct SpatialBoundingFrustum
    {
        Windows.Foundation.Numerics.Plane Near;
        Windows.Foundation.Numerics.Plane Far;
        Windows.Foundation.Numerics.Plane Right;
        Windows.Foundation.Numerics.Plane Left;
        Windows.Foundation.Numerics.Plane Top;
        Windows.Foundation.Numerics.Plane Bottom;
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 2.0)
    ]
    struct SpatialBoundingOrientedBox
    {
        Windows.Foundation.Numerics.Vector3 Center;
        Windows.Foundation.Numerics.Vector3 Extents;
        Windows.Foundation.Numerics.Quaternion Orientation;
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 2.0)
    ]
    struct SpatialBoundingSphere
    {
        Windows.Foundation.Numerics.Vector3 Center;
        FLOAT Radius;
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 2.0),
        exclusiveto(Windows.Perception.Spatial.SpatialBoundingVolume),
        uuid(fb2065da-68c3-33df-b7af-4c787207999c)
    ]
    interface ISpatialBoundingVolume : IInspectable
    {
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 2.0),
        exclusiveto(Windows.Perception.Spatial.SpatialBoundingVolume),
        uuid(05889117-b3e1-36d8-b017-566181a5b196)
    ]
    interface ISpatialBoundingVolumeStatics : IInspectable
    {
        HRESULT FromBox(
            [in] Windows.Perception.Spatial.SpatialCoordinateSystem *system,
            [in] Windows.Perception.Spatial.SpatialBoundingBox box,
            [out, retval] Windows.Perception.Spatial.SpatialBoundingVolume **value
        );
        HRESULT FromOrientedBox(
            [in] Windows.Perception.Spatial.SpatialCoordinateSystem *system,
            [in] Windows.Perception.Spatial.SpatialBoundingOrientedBox box,
            [out, retval] Windows.Perception.Spatial.SpatialBoundingVolume **value
        );
        HRESULT FromSphere(
            [in] Windows.Perception.Spatial.SpatialCoordinateSystem *system,
            [in] Windows.Perception.Spatial.SpatialBoundingSphere sphere,
            [out, retval] Windows.Perception.Spatial.SpatialBoundingVolume **value
        );
        HRESULT FromFrustum(
            [in] Windows.Perception.Spatial.SpatialCoordinateSystem *system,
            [in] Windows.Perception.Spatial.SpatialBoundingFrustum frustum,
            [out, retval] Windows.Perception.Spatial.SpatialBoundingVolume **value
        );
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 2.0),
        exclusiveto(Windows.Perception.Spatial.SpatialCoordinateSystem),
        uuid(69ebca4b-60a3-3586-a653-59a7bd676d07)
    ]
    interface ISpatialCoordinateSystem : IInspectable
    {
        HRESULT TryGetTransformTo(
            [in] Windows.Perception.Spatial.SpatialCoordinateSystem *target,
            [out, retval] Windows.Foundation.IReference<Windows.Foundation.Numerics.Matrix4x4> **value
        );
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 2.0),
        marshaling_behavior(agile),
        static(Windows.Perception.Spatial.ISpatialBoundingVolumeStatics, Windows.Foundation.UniversalApiContract, 2.0),
        threading(both)
    ]
    runtimeclass SpatialBoundingVolume
    {
        [default] interface Windows.Perception.Spatial.ISpatialBoundingVolume;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 2.0),
        marshaling_behavior(agile),
        threading(both)
    ]
    runtimeclass SpatialCoordinateSystem
    {
        [default] interface Windows.Perception.Spatial.ISpatialCoordinateSystem;
    }
}
