/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2024, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */

#include <mrpt/core/exceptions.h>
#include <mrpt/core/lock_helper.h>
#include <mrpt/gui/CDisplayWindowGUI.h>
#include <mrpt/opengl/CGridPlaneXY.h>
#include <mrpt/opengl/stock_objects.h>

#include <iostream>

#if MRPT_HAS_NANOGUI
void TestGUI()
{
  nanogui::init();

  {
    // Create main window:
    mrpt::gui::CDisplayWindowGUI_Params cp;
    // cp.fullscreen = true;

    mrpt::gui::CDisplayWindowGUI win("CDisplayWindowGUI demo", 800, 600, cp);

#if 0
// Define a custom icon image:
		win.setIcon(mrpt::img::CImage::LoadFromFile("/path/to/icon.png"));
#endif
#if 0
		// Define a custom icon from a GIMP header C source data block:
		win.setIconFromData(header_data, 32, 32, 0);
#endif

    nanogui::FormHelper* fh = new nanogui::FormHelper(&win);

    // Add subwindow:
    nanogui::ref<nanogui::Window> subWin2 = fh->addWindow({300, 400}, "Test");
    subWin2->setLayout(new nanogui::GroupLayout());

    mrpt::gui::MRPT2NanoguiGLCanvas* glControl = subWin2->add<mrpt::gui::MRPT2NanoguiGLCanvas>();
    subWin2->setPosition({10, 300});

    {
      auto scene = mrpt::opengl::Scene::Create();
      scene->insert(mrpt::opengl::stock_objects::CornerXYZSimple());

      glControl->camera().setZoomDistance(5.0f);

      auto lck = mrpt::lockHelper(glControl->scene_mtx);
      glControl->scene = std::move(scene);
    }

    // Add subwindow:
    nanogui::ref<nanogui::Window> subWin = fh->addWindow({300, 400}, "Test");
    bool show_corner = true;

    fh->addGroup("Visualization");
    fh->addVariable("Show XYZ corner", show_corner)
        ->setCallback([&](const bool& c) { subWin2->setVisible(c); });

    fh->addButton("Quit", [&]() { win.setVisible(false); });

    subWin->setPosition({10, 10});

    // add a background scene:
    {
      auto scene = mrpt::opengl::Scene::Create();
      scene->insert(mrpt::opengl::CGridPlaneXY::Create());

      std::lock_guard<std::mutex> lck(win.background_scene_mtx);
      win.background_scene = std::move(scene);
    }

    win.performLayout();

    win.camera().setZoomDistance(10.0f);

    // Update view and process events:
    win.drawAll();
    win.setVisible(true);
    nanogui::mainloop();
  }

  nanogui::shutdown();
}
#endif

int main()
{
  try
  {
#if MRPT_HAS_NANOGUI
    TestGUI();
#else
    std::cerr << "This example requires MRPT built with NANOGUI.\n";
#endif
    return 0;
  }
  catch (const std::exception& e)
  {
    std::cerr << mrpt::exception_to_str(e) << std::endl;
    return -1;
  }
}
