#!/bin/sh
# autopkgtest check: Build and run a program against ign-transport, to verify that the
# headers and pkg-config file are installed correctly
# (C) 2021 Jose Luis Rivero
# Author: Jose Luis Rivero <jrivero@osrfoundation.org>

set -e

WORKDIR=$(mktemp -d)
trap "rm -rf $WORKDIR" 0 INT QUIT ABRT PIPE TERM
cd $WORKDIR
cat <<EOF > ogretest.cc
#include "OgreArchiveManager.h"
#include "OgreCamera.h"
#include "OgreConfigFile.h"
#include "OgreRoot.h"
#include "OgreWindow.h"

#include "OgreHlmsManager.h"
#include "OgreHlmsPbs.h"
#include "OgreHlmsUnlit.h"

#include "Compositor/OgreCompositorManager2.h"

#include "OgreWindowEventUtilities.h"

static void registerHlms( void )
{
    using namespace Ogre;

    String resourcePath = "";
    ConfigFile cf;
    cf.load( resourcePath + "resources2.cfg" );

    String rootHlmsFolder = resourcePath + cf.getSetting( "DoNotUseAsResource", "Hlms", "" );

    if( rootHlmsFolder.empty() )
        rootHlmsFolder = "./";
    else if( *( rootHlmsFolder.end() - 1 ) != '/' )
        rootHlmsFolder += "/";

    // At this point rootHlmsFolder should be a valid path to the Hlms data folder

    HlmsUnlit *hlmsUnlit = 0;
    HlmsPbs *hlmsPbs = 0;

    // For retrieval of the paths to the different folders needed
    String mainFolderPath;
    StringVector libraryFoldersPaths;
    StringVector::const_iterator libraryFolderPathIt;
    StringVector::const_iterator libraryFolderPathEn;

    ArchiveManager &archiveManager = ArchiveManager::getSingleton();

    {
        // Create & Register HlmsUnlit
        // Get the path to all the subdirectories used by HlmsUnlit
        HlmsUnlit::getDefaultPaths( mainFolderPath, libraryFoldersPaths );
        Archive *archiveUnlit =
            archiveManager.load( rootHlmsFolder + mainFolderPath, "FileSystem", true );
        ArchiveVec archiveUnlitLibraryFolders;
        libraryFolderPathIt = libraryFoldersPaths.begin();
        libraryFolderPathEn = libraryFoldersPaths.end();
        while( libraryFolderPathIt != libraryFolderPathEn )
        {
            Archive *archiveLibrary =
                archiveManager.load( rootHlmsFolder + *libraryFolderPathIt, "FileSystem", true );
            archiveUnlitLibraryFolders.push_back( archiveLibrary );
            ++libraryFolderPathIt;
        }

        // Create and register the unlit Hlms
        hlmsUnlit = OGRE_NEW HlmsUnlit( archiveUnlit, &archiveUnlitLibraryFolders );
        Root::getSingleton().getHlmsManager()->registerHlms( hlmsUnlit );
    }

    {
        // Create & Register HlmsPbs
        // Do the same for HlmsPbs:
        HlmsPbs::getDefaultPaths( mainFolderPath, libraryFoldersPaths );
        Archive *archivePbs = archiveManager.load( rootHlmsFolder + mainFolderPath, "FileSystem", true );

        // Get the library archive(s)
        ArchiveVec archivePbsLibraryFolders;
        libraryFolderPathIt = libraryFoldersPaths.begin();
        libraryFolderPathEn = libraryFoldersPaths.end();
        while( libraryFolderPathIt != libraryFolderPathEn )
        {
            Archive *archiveLibrary =
                archiveManager.load( rootHlmsFolder + *libraryFolderPathIt, "FileSystem", true );
            archivePbsLibraryFolders.push_back( archiveLibrary );
            ++libraryFolderPathIt;
        }

        // Create and register
        hlmsPbs = OGRE_NEW HlmsPbs( archivePbs, &archivePbsLibraryFolders );
        Root::getSingleton().getHlmsManager()->registerHlms( hlmsPbs );
    }

    RenderSystem *renderSystem = Root::getSingletonPtr()->getRenderSystem();
    if( renderSystem->getName() == "Direct3D11 Rendering Subsystem" )
    {
        // Set lower limits 512kb instead of the default 4MB per Hlms in D3D 11.0
        // and below to avoid saturating AMD's discard limit (8MB) or
        // saturate the PCIE bus in some low end machines.
        bool supportsNoOverwriteOnTextureBuffers;
        renderSystem->getCustomAttribute( "MapNoOverwriteOnDynamicBufferSRV",
                                          &supportsNoOverwriteOnTextureBuffers );

        if( !supportsNoOverwriteOnTextureBuffers )
        {
            hlmsPbs->setTextureBufferDefaultSize( 512 * 1024 );
            hlmsUnlit->setTextureBufferDefaultSize( 512 * 1024 );
        }
    }
}

class MyWindowEventListener : public Ogre::WindowEventListener
{
    bool mQuit;

public:
    MyWindowEventListener() : mQuit( false ) {}
    virtual void windowClosed( Ogre::Window *rw ) { mQuit = true; }

    bool getQuit( void ) const { return mQuit; }
};

int main( int argc, const char *argv[] )
{
    using namespace Ogre;

    const String pluginsFolder = "./";
    const String writeAccessFolder = pluginsFolder;
    const char *pluginsFile = 0; // TODO
    Root *root = OGRE_NEW Root( pluginsFolder + pluginsFile,     //
                                writeAccessFolder + "ogre.cfg",  //
                                writeAccessFolder + "Ogre.log" );

    if( !root->showConfigDialog() )
        return -1;

    // Initialize Root
    root->getRenderSystem()->setConfigOption( "sRGB Gamma Conversion", "Yes" );
    Window *window = root->initialise( true, "Tutorial 00: Basic" );

    registerHlms();

    // Create SceneManager
    const size_t numThreads = 1u;
    SceneManager *sceneManager = root->createSceneManager( ST_GENERIC, numThreads, "ExampleSMInstance" );

    // Create & setup camera
    Camera *camera = sceneManager->createCamera( "Main Camera" );

    // Position it at 500 in Z direction
    camera->setPosition( Vector3( 0, 5, 15 ) );
    // Look back along -Z
    camera->lookAt( Vector3( 0, 0, 0 ) );
    camera->setNearClipDistance( 0.2f );
    camera->setFarClipDistance( 1000.0f );
    camera->setAutoAspectRatio( true );

    // Setup a basic compositor with a blue clear colour
    CompositorManager2 *compositorManager = root->getCompositorManager2();
    const String workspaceName( "Demo Workspace" );
    const ColourValue backgroundColour( 0.2f, 0.4f, 0.6f );
    compositorManager->createBasicWorkspaceDef( workspaceName, backgroundColour, IdString() );
    compositorManager->addWorkspace( sceneManager, window->getTexture(), camera, workspaceName, true );

    MyWindowEventListener myWindowEventListener;
    WindowEventUtilities::addWindowEventListener( window, &myWindowEventListener );

    bool bQuit = false;

    while( !bQuit )
    {
        WindowEventUtilities::messagePump();
        bQuit |= myWindowEventListener.getQuit();
        if( !bQuit )
            bQuit |= !root->renderOneFrame();
    }

    WindowEventUtilities::removeWindowEventListener( window, &myWindowEventListener );

    OGRE_DELETE root;
    root = 0;

    return 0;
}
EOF

export CXXFLAGS=" -DOGRE_DEBUG_MODE=0"
g++ -o ogretest ogretest.cc `pkg-config --cflags --libs OGRE-Next OGRE-Next-Hlms` $CXXFLAGS
echo "build: OK"
# do not run, needs a display

# CMake
cat <<EOF > CMakeLists.txt
cmake_minimum_required(VERSION 3.5)

project(ign_test VERSION 1.0.0)

find_package(OGRE-Next REQUIRED)
add_executable(ogretest ogretest.cc)
target_link_libraries(ogretest \${OGRE-Next_LIBRARIES}
                               \${OGRE-Next_HlmsPbs_LIBRARIES}
                               \${OGRE-Next_HlmsUnlit_LIBRARIES})
target_include_directories(ogretest PRIVATE \${OGRE-Next_INCLUDE_DIRS}
                                            \${OGRE-Next_HlmsPbs_INCLUDE_DIRS}
                                            \${OGRE-Next_HlmsPbs_INCLUDE_DIRS}/..
                                            \${OGRE-Next_HlmsPbs_INCLUDE_DIRS}/../Common
                                            \${OGRE-Next_HlmsUnlit_INCLUDE_DIRS})
EOF

cmake .
echo "configure cmake with component: OK"
VERBOSE=1 make -j1
echo "build cmake component:OK"
