/*
 * engine.cxx, now included in digital modulations, was initialy a file from miniDart project
 * Author : Eric Bachard  / lundi 3 octobre 2016, 14:35:03 (UTC+0200)
 * This file is under GPL v2 License
 * See : http://www.gnu.org/licenses/gpl-2.0.html
 */


#include "SDL3/SDL.h"                  // We use SDL3

#include "imgui_impl_sdl3.h"
#include "imgui_impl_opengl3.h"
#include "engine.h"                  // class Engine
#include "application.h"             // WINDOW_WIDTH, WINDOW_HEIGHT,

#include <GL/gl.h>                     // OpenGL

#include "digital_modulation_fr.hpp"

// TODO later : kept for good reasons (the fact is we currently do not cross-compile for MS Windows)
#ifndef NATIVE_BUILD
#define NATIVE_BUILD
#endif

using std::cout;
using std::endl;

void Engine::sdl_application_abort(const char * msg)
{
    std::cout << SDL_GetError() << std::endl;
    SDL_Quit();
    exit (-1);
}

Engine::Engine()
{
    int anErr = init_SDL();

    if (anErr != 0)
    {
        std::cerr << "Cannot initialize SDL or OpenGL. Exiting" << std::endl;
        SDL_Quit();
    }
}


Engine::~Engine()
{
    SDL_GL_DestroyContext(getGL_Context());
    SDL_DestroyWindow(getWindow());
    window = nullptr;
}

int Engine::init_SDL()
{
    std::cout << "\n";
    SDL_Log("AVX     %s\n", SDL_HasAVX()? "detected" : "not detected");
    SDL_Log("AVX2    %s\n", SDL_HasAVX2()? "detected" : "not detected");
    SDL_Log("AVX512F %s\n", SDL_HasAVX512F()? "detected" : "not detected");
    std::cout << "\n";

    // ericb 2022 08 19
    // source :
    // https://answers.opencv.org/question/120699/can-opencv-310-be-set-to-capture-an-rtsp-stream-over-udp/
    //   setenv("OPENCV_FFMPEG_CAPTURE_OPTIONS", "rtsp_transport;udp", 1);

#ifdef NATIVE_BUILD
    // https://github.com/libsdl-org/SDL/issues/2917
    putenv((char *)"SDL_PULSEAUDIO_INCLUDE_MONITORS=true");
#endif
    // https://www.gog.com/forum/thimbleweed_park/linux_unable_to_init_sdl_mixer_alsa_couldnt_open_audio_device_no_such_device
    // https://wiki.libsdl.org/FAQUsingSDL
#ifndef NATIVE_BUILD
    SDL_setenv("SDL_AUDIODRIVER", "DirectSound", true);
    putenv((char *)"SDL_AUDIODRIVER=DirectSound");
#else
    // SDL_setenv("SDL_AUDIODRIVER", "alsa", true);
    putenv((char *)"SDL_AUDIODRIVER=alsa");
//    putenv((char *)"SDL_AUDIODEV=pulse");
#endif

    // --------------------- SDL INIT ---------------------
    // about issues between OpenGL 3.3. and OpenGL 3.0 (only Linux concerned)
    // https://discourse.libsdl.org/t/confused-about-what-opengl-context-is-being-used-with-sdl/22860
    // avoid using compatiblity profile

    if (!SDL_Init(SDL_INIT_VIDEO))
    {
        fprintf(stdout, "SDL init error: %s\n", SDL_GetError());
        return -1;
    }
    //const char* glsl_version = "#version 130";
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    setWindow((SDL_Window*)SDL_CreateWindow(  MAIN_SDL3_WINDOW_NAME,
                                            DEFAULT_SDL_WINDOW_WIDTH,
                                            DEFAULT_SDL_WINDOW_HEIGHT,
                                            SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
                                         ));

    // check whether the SDL3 window exists
    if (getWindow() == nullptr)
        sdl_application_abort("Problem creating the SDL window.\n");
    else
        std::cout << "SDL3 Window created " << "\n";

    gl_context = SDL_GL_CreateContext(getWindow());

    std::cout << "GL_Context   :  " << getGL_Context() << "\n";

    if (getGL_Context() == nullptr)
        sdl_application_abort("Problem creating GL context.\n");
    else
        std::cout << "GL Context created \n" << "\n";

    SDL_GL_MakeCurrent(getWindow(), getGL_Context());

    // 1 == enable VSync ; 0 == disable VSync
    #define USE_VSYNC
    #ifdef USE_VSYNC
    SDL_GL_SetSwapInterval(1);
    #else
    SDL_GL_SetSwapInterval(0);
    #endif

    std::cout << "\nImGui version = " <<  IMGUI_VERSION  << "\n\n";

    return EXIT_SUCCESS;
}





