/*
 * Copyright (C) 2020 Igalia S.L. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#if ENABLE(WEBXR)

#include "FakeXRBoundsPoint.h"
#include "FakeXRInputSourceInit.h"
#include "FakeXRViewInit.h"
#include "JSDOMPromiseDeferred.h"
#include "PlatformXR.h"
#include "WebFakeXRInputController.h"
#include "XRVisibilityState.h"
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>

namespace WebCore {
class GraphicsContextGL;

class FakeXRView final : public RefCounted<FakeXRView> {
public:
    static Ref<FakeXRView> create(XREye eye) { return adoptRef(*new FakeXRView(eye)); }
    using Pose = PlatformXR::Device::FrameData::Pose;
    using Fov = PlatformXR::Device::FrameData::Fov;

    XREye eye() const { return m_eye; }
    const Pose& offset() const { return m_offset; }
    const std::array<float, 16>& projection() const { return m_projection; }
    const std::optional<Fov>& fieldOfView() const { return m_fov;}

    void setResolution(FakeXRViewInit::DeviceResolution resolution) { m_resolution = resolution; }
    void setOffset(Pose&& offset) { m_offset = WTFMove(offset); }
    void setProjection(const Vector<float>&);
    void setFieldOfView(const FakeXRViewInit::FieldOfViewInit&);
private:
    FakeXRView(XREye eye)
        : m_eye(eye) { }


    XREye m_eye;
    FakeXRViewInit::DeviceResolution m_resolution;
    Pose m_offset;
    std::array<float, 16> m_projection;
    std::optional<Fov> m_fov;
};

class SimulatedXRDevice final : public PlatformXR::Device {
    WTF_MAKE_FAST_ALLOCATED;
public:
    SimulatedXRDevice();
    ~SimulatedXRDevice();
    void setViews(Vector<FrameData::View>&&);
    void setNativeBoundsGeometry(const Vector<FakeXRBoundsPoint>&);
    void setViewerOrigin(const std::optional<FrameData::Pose>&);
    void setFloorOrigin(std::optional<FrameData::Pose>&& origin) { m_frameData.floorTransform = WTFMove(origin); }
    void setEmulatedPosition(bool emulated) { m_frameData.isPositionEmulated = emulated; }
    void setSupportsShutdownNotification(bool supportsShutdownNotification) { m_supportsShutdownNotification = supportsShutdownNotification; }
    void simulateShutdownCompleted();
    void scheduleOnNextFrame(Function<void()>&&);
    void addInputConnection(Ref<WebFakeXRInputController>&& input) { m_inputConnections.append(WTFMove(input)); };
private:
    WebCore::IntSize recommendedResolution(PlatformXR::SessionMode) final;
    void initializeTrackingAndRendering(PlatformXR::SessionMode) final;
    void shutDownTrackingAndRendering() final;
    bool supportsSessionShutdownNotification() const final { return m_supportsShutdownNotification; }
    void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final { }
    Vector<PlatformXR::Device::ViewData> views(PlatformXR::SessionMode) const final;
    void requestFrame(RequestFrameCallback&&) final;
    std::optional<PlatformXR::LayerHandle> createLayerProjection(uint32_t width, uint32_t height, bool alpha) final;
    void deleteLayer(PlatformXR::LayerHandle) final;

    void stopTimer();
    void frameTimerFired();

    PlatformXR::Device::FrameData m_frameData;
    bool m_supportsShutdownNotification { false };
    Timer m_frameTimer;
    RequestFrameCallback m_FrameCallback;
    RefPtr<WebCore::GraphicsContextGL> m_gl;
    HashMap<PlatformXR::LayerHandle, PlatformGLObject> m_layers;
    uint32_t m_layerIndex { 0 };
    Vector<Ref<WebFakeXRInputController>> m_inputConnections;
};

class WebFakeXRDevice final : public RefCounted<WebFakeXRDevice> {
public:
    static Ref<WebFakeXRDevice> create() { return adoptRef(*new WebFakeXRDevice()); }

    void setViews(const Vector<FakeXRViewInit>&);
    void disconnect(DOMPromiseDeferred<void>&&);
    void setViewerOrigin(FakeXRRigidTransformInit origin, bool emulatedPosition = false);
    void clearViewerOrigin() { m_device.setViewerOrigin(std::nullopt); }
    void simulateVisibilityChange(XRVisibilityState);
    void setBoundsGeometry(Vector<FakeXRBoundsPoint>&& bounds) { m_device.setNativeBoundsGeometry(WTFMove(bounds)); }
    void setFloorOrigin(FakeXRRigidTransformInit);
    void clearFloorOrigin() { m_device.setFloorOrigin(std::nullopt); }
    void simulateResetPose();
    Ref<WebFakeXRInputController> simulateInputSourceConnection(const FakeXRInputSourceInit&);
    static ExceptionOr<Ref<FakeXRView>> parseView(const FakeXRViewInit&);
    SimulatedXRDevice& simulatedXRDevice() { return m_device; }
    void setSupportsShutdownNotification();
    void simulateShutdown();

    static ExceptionOr<PlatformXR::Device::FrameData::Pose> parseRigidTransform(const FakeXRRigidTransformInit&);

private:
    WebFakeXRDevice();

    SimulatedXRDevice m_device;
    PlatformXR::InputSourceHandle mInputSourceHandleIndex { 0 };
};

} // namespace WebCore

#endif // ENABLE(WEBXR)
