/*
 * Copyright (C) 2024 Zhiyi Zhang 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 "asyncinfo.idl";
import "eventtoken.idl";
import "windowscontracts.idl";
import "windows.foundation.idl";
import "windows.devices.input.idl";
import "windows.system.idl";
import "windows.ui.core.idl";

namespace Windows.UI.Input {
    typedef enum PointerUpdateKind PointerUpdateKind;

    interface IPointerPoint;
    interface IPointerPointProperties;
    interface IPointerPointProperties2;
    interface IPointerPointStatics;
    interface IPointerPointTransform;

    runtimeclass PointerPoint;
    runtimeclass PointerPointProperties;

    declare {
        interface Windows.Foundation.Collections.IVectorView<Windows.UI.Input.PointerPoint *>;
        interface Windows.Foundation.Collections.IVector<Windows.UI.Input.PointerPoint *>;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0)
    ]
    enum PointerUpdateKind
    {
        Other                = 0,
        LeftButtonPressed    = 1,
        LeftButtonReleased   = 2,
        RightButtonPressed   = 3,
        RightButtonReleased  = 4,
        MiddleButtonPressed  = 5,
        MiddleButtonReleased = 6,
        XButton1Pressed      = 7,
        XButton1Released     = 8,
        XButton2Pressed      = 9,
        XButton2Released     = 10
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Input.PointerPoint),
        uuid(e995317d-7296-42d9-8233-c5be73b74a4a)
    ]
    interface IPointerPoint : IInspectable
    {
        [propget] HRESULT PointerDevice([out, retval] Windows.Devices.Input.PointerDevice **value);
        [propget] HRESULT Position([out, retval] Windows.Foundation.Point *value);
        [propget] HRESULT RawPosition([out, retval] Windows.Foundation.Point *value);
        [propget] HRESULT pointer_id([out, retval] UINT32 *value);
        [propget] HRESULT FrameId([out, retval] UINT32 *value);
        [propget] HRESULT Timestamp([out, retval] UINT64 *value);
        [propget] HRESULT IsInContact([out, retval] boolean *value);
        [propget] HRESULT Properties([out, retval] Windows.UI.Input.PointerPointProperties **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Input.PointerPointProperties),
        uuid(c79d8a4b-c163-4ee7-803f-67ce79f9972d)
    ]
    interface IPointerPointProperties : IInspectable
    {
        [propget] HRESULT Pressure([out, retval] FLOAT *value);
        [propget] HRESULT IsInverted([out, retval] boolean *value);
        [propget] HRESULT IsEraser([out, retval] boolean *value);
        [propget] HRESULT Orientation([out, retval] FLOAT *value);
        [propget] HRESULT XTilt([out, retval] FLOAT *value);
        [propget] HRESULT YTilt([out, retval] FLOAT *value);
        [propget] HRESULT Twist([out, retval] FLOAT *value);
        [propget] HRESULT ContactRect([out, retval] Windows.Foundation.Rect *value);
        [propget] HRESULT ContactRectRaw([out, retval] Windows.Foundation.Rect *value);
        [propget] HRESULT TouchConfidence([out, retval] boolean *value);
        [propget] HRESULT IsLeftButtonPressed([out, retval] boolean *value);
        [propget] HRESULT IsRightButtonPressed([out, retval] boolean *value);
        [propget] HRESULT IsMiddleButtonPressed([out, retval] boolean *value);
        [propget] HRESULT MouseWheelDelta([out, retval] INT32 *value);
        [propget] HRESULT IsHorizontalMouseWheel([out, retval] boolean *value);
        [propget] HRESULT IsPrimary([out, retval] boolean *value);
        [propget] HRESULT IsInRange([out, retval] boolean *value);
        [propget] HRESULT IsCanceled([out, retval] boolean *value);
        [propget] HRESULT IsBarrelButtonPressed([out, retval] boolean *value);
        [propget] HRESULT IsXButton1Pressed([out, retval] boolean *value);
        [propget] HRESULT IsXButton2Pressed([out, retval] boolean *value);
        [propget] HRESULT PointerUpdateKind([out, retval] Windows.UI.Input.PointerUpdateKind *value);
        HRESULT HasUsage([in] UINT32 usage_page, [in] UINT32 usage_id, [out, retval] boolean *value);
        HRESULT GetUsageValue([in] UINT32 usage_page, [in] UINT32 usage_id, [out, retval] INT32 *value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Input.PointerPointProperties),
        uuid(22c3433a-c83b-41c0-a296-5e232d64d6af)
    ]
    interface IPointerPointProperties2 : IInspectable
    {
        [propget] HRESULT ZDistance([out, retval] Windows.Foundation.IReference<FLOAT> **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.UI.Input.PointerPoint),
        uuid(a506638d-2a1a-413e-bc75-9f38381cc069)
    ]
    interface IPointerPointStatics : IInspectable
    {
        [overload("GetCurrentPoint")] HRESULT GetCurrentPoint([in] UINT32 pointer_id, [out, retval] Windows.UI.Input.PointerPoint **point);
        [overload("GetIntermediatePoints")] HRESULT GetIntermediatePoints([in] UINT32 pointer_id, [out, retval] Windows.Foundation.Collections.IVector<Windows.UI.Input.PointerPoint *> **points);
        [overload("GetCurrentPoint")] HRESULT GetCurrentPointTransformed([in] UINT32 pointer_id, [in] Windows.UI.Input.IPointerPointTransform *transform, [out, retval] Windows.UI.Input.PointerPoint **point);
        [overload("GetIntermediatePoints")] HRESULT GetIntermediatePointsTransformed([in] UINT32 pointer_id, [in] Windows.UI.Input.IPointerPointTransform *transform, [out, retval] Windows.Foundation.Collections.IVector<Windows.UI.Input.PointerPoint *> **points);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        uuid(4d5fe14f-b87c-4028-bc9c-59e9947fb056)
    ]
    interface IPointerPointTransform : IInspectable
    {
        [propget] HRESULT Inverse([out, retval] Windows.UI.Input.IPointerPointTransform **value);
        HRESULT TryTransform([in] Windows.Foundation.Point in_point, [out] Windows.Foundation.Point *out_point, [out, retval] boolean *value);
        HRESULT TransformBounds([in] Windows.Foundation.Rect rect, [out, retval] Windows.Foundation.Rect *value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(none),
        static(Windows.UI.Input.IPointerPointStatics, Windows.Foundation.UniversalApiContract, 1.0)
    ]
    runtimeclass PointerPoint
    {
        [default] interface Windows.UI.Input.IPointerPoint;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(none)
    ]
    runtimeclass PointerPointProperties
    {
        [default] interface Windows.UI.Input.IPointerPointProperties;
        [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.UI.Input.IPointerPointProperties2;
    }
}
