// Copyright (c) 2012-2013, IGN France.
// Copyright (c) 2012-2024, Oslandia.
// Copyright (c) 2024-2026, SFCGAL team.
// SPDX-License-Identifier: LGPL-2.0-or-later

#include "SFCGAL/detail/transform/ForceOrderPoints.h"
#include "SFCGAL/Point.h"
#include "SFCGAL/Polygon.h"
#include "SFCGAL/Triangle.h"
#include "SFCGAL/algorithm/orientation.h"

namespace SFCGAL::transform {

ForceOrderPoints::ForceOrderPoints(bool orientCCW) : _orientCCW(orientCCW) {}

void
ForceOrderPoints::transform(Point & /*point*/)
{
}

void
ForceOrderPoints::visit(Triangle &triangle)
{
  if (triangle.isEmpty()) {
    return;
  }

  if (!SFCGAL::algorithm::isCounterClockWiseOriented(triangle)) {
    // not pointing up, reverse
    if (_orientCCW) {
      triangle.reverse();
    }
  } else {
    if (!_orientCCW) {
      triangle.reverse();
    }
  }

  Transform::visit(triangle);
}

void
ForceOrderPoints::visit(Polygon &polygon)
{
  if (polygon.isEmpty()) {
    return;
  }

  LineString &ext = polygon.exteriorRing();

  if (!SFCGAL::algorithm::isCounterClockWiseOriented(polygon.exteriorRing())) {
    // exterior ring not pointing up, reverse
    if (_orientCCW) {
      ext.reverse();
    }
  } else {
    if (!_orientCCW) {
      ext.reverse();
    }
  }
  const bool isCCWO{SFCGAL::algorithm::isCounterClockWiseOriented(ext)};
  for (size_t i = 0; i < polygon.numInteriorRings(); ++i) {
    LineString &inter = polygon.interiorRingN(i);

    if (SFCGAL::algorithm::isCounterClockWiseOriented(inter) == isCCWO) {
      inter.reverse();
    }
  }

  Transform::visit(polygon);
}

} // namespace SFCGAL::transform
