// Copyright (C) 2019  Joseph Artsimovich <joseph.artsimovich@gmail.com>, 4lex4 <4lex49@zoho.com>
// Use of this source code is governed by the GNU GPLv3 license that can be found in the LICENSE file.

#include <BinaryImage.h>
#include <SkewFinder.h>

#include <QApplication>
#include <QColor>
#include <QImage>
#include <QPainter>
#include <QTransform>
#include <boost/test/unit_test.hpp>
#include <cmath>
#include <cstdlib>

namespace imageproc {
namespace tests {
BOOST_AUTO_TEST_SUITE(SkewFinderTestSuite)

BOOST_AUTO_TEST_CASE(test_positive_detection) {
  int argc = 1;
  char argv0[] = "test";
  char* argv[1] = {argv0};
  QApplication app(argc, argv);
  QImage image(1000, 800, QImage::Format_ARGB32_Premultiplied);
  image.fill(0xffffffff);
  {
    // Draw parallel strokes in "skewed page" space (no QTextDocument / fonts).
    // Headless RPM/mock chroots often have no fonts; QPainter::drawText() can abort there.
    QPainter painter(&image);
    painter.setRenderHint(QPainter::Antialiasing, false);
    painter.setPen(QPen(QColor(0, 0, 0), 2));
    QTransform xform1;
    xform1.translate(-0.5 * image.width(), -0.5 * image.height());
    QTransform xform2;
    xform2.rotate(4.5);
    QTransform xform3;
    xform3.translate(0.5 * image.width(), 0.5 * image.height());
    painter.setWorldTransform(xform1 * xform2 * xform3);
    for (int y = -500; y <= 500; y += 14) {
      painter.drawLine(QLineF(-700, y, 700, y));
    }
  }

  SkewFinder skewFinder;
  const Skew skew(skewFinder.findSkew(BinaryImage(image)));
  BOOST_REQUIRE(std::fabs(skew.angle() - 4.5) < 0.15);
  BOOST_CHECK(skew.confidence() >= Skew::GOOD_CONFIDENCE);
}

BOOST_AUTO_TEST_CASE(test_negative_detection) {
  QImage image(1000, 800, QImage::Format_Mono);
  image.fill(1);

  const int numDots = image.width() * image.height() / 5;
  for (int i = 0; i < numDots; ++i) {
    const int x = rand() % image.width();
    const int y = rand() % image.height();
    image.setPixel(x, y, 0);
  }

  SkewFinder skewFinder;
  skewFinder.setCoarseReduction(0);
  skewFinder.setFineReduction(0);
  const Skew skew(skewFinder.findSkew(BinaryImage(image)));
  BOOST_CHECK(skew.confidence() < Skew::GOOD_CONFIDENCE);
}

BOOST_AUTO_TEST_SUITE_END()
}  // namespace tests
}  // namespace imageproc