/* +------------------------------------------------------------------------+
   |                     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/gui/CDisplayWindowPlots.h>
#include <mrpt/math/TObject2D.h>
#include <mrpt/math/TPolygon2D.h>
#include <mrpt/math/geometry.h>

#include <iostream>

static void polygonClippingExample()
{
  // Define the polygons:
  const mrpt::math::TPolygon2D subject = {
      {{0.0, 0.0}, {5.0, 0.0}, {7.0, 3.0}, {3.0, 6.0}, {-4.0, 4.0}, {-1.0, -1.0}}
  };

  const mrpt::math::TPolygon2D clipping = {
      {{-6.0, 0.5}, {8.0, 2.0}, {10.0, 4.0}, {-7.0, 3.0}}
  };

  // Compute intersection:
  mrpt::math::TObject2D clippedObj;
  bool doIntersect = mrpt::math::intersect(subject, clipping, clippedObj);
  ASSERT_(doIntersect);

  mrpt::math::TPolygon2D clippedPoly;
  bool isPoly = clippedObj.getPolygon(clippedPoly);
  ASSERT_(isPoly);

  // GUI:
  mrpt::gui::CDisplayWindowPlots winIn("Inputs (red:subject, blue:clipping)", 500, 500);
  winIn.setPos(20, 50);

  const auto [x1, y1] = subject.getPlotData();
  winIn.plot(x1, y1, "-r3");
  winIn.hold_on();

  const auto [x2, y2] = clipping.getPlotData();
  winIn.plot(x2, y2, ":b2");

  mrpt::gui::CDisplayWindowPlots winOut("Result", 500, 500);
  winOut.setPos(600, 50);

  winOut.plot(x2, y2, ":b2");
  winOut.hold_on();

  const auto [xp, yp] = clippedPoly.getPlotData();
  winOut.plot(xp, yp, "-r3");

  winIn.axis_equal();
  winOut.axis_equal();

  std::cout << "Press any key on input window or close it to end program.\n";
  winIn.waitForKey();
}

int main(int argc, char** argv)
{
  try
  {
    polygonClippingExample();
    return 0;
  }
  catch (const std::exception& e)
  {
    std::cout << e.what() << std::endl;
    return 1;
  }
}
