#include "VentuzLocalPlayer.h"
#include "Runtime/Launch/Resources/Version.h"
#include "VentuzPluginModule.h"

#if ENGINE_MAJOR_VERSION >= 5 
FSceneView* UVentuzLocalPlayer::CalcSceneView( class FSceneViewFamily* ViewFamily, FVector& OutViewLocation, FRotator& OutViewRotation, FViewport* Viewport, class FViewElementDrawer* ViewDrawer /*= NULL*/, int32 StereoViewIndex /*= INDEX_NONE*/ )
#else
FSceneView* UVentuzLocalPlayer::CalcSceneView( class FSceneViewFamily* ViewFamily, FVector& OutViewLocation, FRotator& OutViewRotation, FViewport* Viewport, class FViewElementDrawer* ViewDrawer /*= NULL*/, EStereoscopicPass StereoPass /*= eSSP_FULL */ )
#endif
{
#if ENGINE_MAJOR_VERSION >= 5 
    FSceneView* view = Super::CalcSceneView( ViewFamily, OutViewLocation, OutViewRotation, Viewport, ViewDrawer, StereoViewIndex );
#else
    FSceneView* view = Super::CalcSceneView(ViewFamily, OutViewLocation, OutViewRotation, Viewport, ViewDrawer, StereoPass);
#endif

    if (view)
    {
        if ( !IVentuzPlugin::IsAvailable() )
            return view;
        FVentuzPlugin* plugin = &FModuleManager::LoadModuleChecked<FVentuzPlugin>("VentuzPlugin");
        if ( !plugin )
            return view;

        // for reference:
/*
        FMatrix zReverser;
        zReverser.SetIdentity();
        zReverser.M[2][2] = -1;
        zReverser.M[3][2] = 1;

        FMatrix referenceMatrix = plugin->GetVentuzProjectionMatrix();
        referenceMatrix = referenceMatrix * zReverser;
*/


        FMatrix matrix = view->ViewMatrices.GetProjectionMatrix();
        FMatrix ventuzProjection = plugin->GetVentuzProjectionMatrix();

        bool isOrtho = ventuzProjection.M[3][3] == 1;

        if (!isOrtho)
        {
            FVector2D offset = plugin->GetVentuzProjectionOffset();

            matrix.M[2][0] = offset.X;
            matrix.M[2][1] = offset.Y;
            matrix.M[3][3] = ventuzProjection.M[3][3];


            view->UpdateProjectionMatrix(matrix);
        }
        else
        {
            FMatrix adjustMatrix;
            adjustMatrix.SetIdentity();

            adjustMatrix.M[0][0] = 0.01f;
            adjustMatrix.M[1][1] = 0.01f;
            adjustMatrix.M[2][2] = 0.01f;
            
            //reverse z

            ventuzProjection.M[2][2] = -ventuzProjection.M[2][2];
            ventuzProjection.M[3][2] = 1.0f - ventuzProjection.M[3][2];

            ventuzProjection = adjustMatrix * ventuzProjection ;
            view->UpdateProjectionMatrix(ventuzProjection);
        }

    }

    return view;
}
