// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
// Original code is licensed as follows:
/*
 * Copyright 2008 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "xfa/fxbarcode/datamatrix/BC_DataMatrixDetector.h"

#include <algorithm>
#include <memory>

#include "xfa/fxbarcode/BC_ResultPoint.h"
#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
#include "xfa/fxbarcode/common/BC_WhiteRectangleDetector.h"
#include "xfa/fxbarcode/qrcode/BC_QRDetectorResult.h"
#include "xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.h"
#include "xfa/fxbarcode/qrcode/BC_QRGridSampler.h"
#include "xfa/fxbarcode/utils.h"

const int32_t CBC_DataMatrixDetector::INTEGERS[5] = {0, 1, 2, 3, 4};
CBC_DataMatrixDetector::CBC_DataMatrixDetector(CBC_CommonBitMatrix* image)
    : m_image(image), m_rectangleDetector(nullptr) {}
void CBC_DataMatrixDetector::Init(int32_t& e) {
  m_rectangleDetector = new CBC_WhiteRectangleDetector(m_image);
  m_rectangleDetector->Init(e);
  BC_EXCEPTION_CHECK_ReturnVoid(e);
}
CBC_DataMatrixDetector::~CBC_DataMatrixDetector() {
  delete m_rectangleDetector;
}

CBC_QRDetectorResult* CBC_DataMatrixDetector::Detect(int32_t& e) {
  CFX_ArrayTemplate<CBC_ResultPoint*>* cornerPoints =
      m_rectangleDetector->Detect(e);
  BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  CBC_ResultPoint* pointA = (*cornerPoints)[0];
  CBC_ResultPoint* pointB = (*cornerPoints)[1];
  CBC_ResultPoint* pointC = (*cornerPoints)[2];
  CBC_ResultPoint* pointD = (*cornerPoints)[3];
  delete cornerPoints;

  CFX_ArrayTemplate<CBC_ResultPointsAndTransitions*> transitions;
  transitions.Add(TransitionsBetween(pointA, pointB));
  transitions.Add(TransitionsBetween(pointA, pointC));
  transitions.Add(TransitionsBetween(pointB, pointD));
  transitions.Add(TransitionsBetween(pointC, pointD));
  std::sort(transitions.GetData(),
            transitions.GetData() + transitions.GetSize(),
            [](const CBC_ResultPointsAndTransitions* a,
               const CBC_ResultPointsAndTransitions* b) {
              return a->GetTransitions() < b->GetTransitions();
            });
  delete transitions[2];
  delete transitions[3];

  CBC_ResultPointsAndTransitions* lSideOne = transitions[0];
  CBC_ResultPointsAndTransitions* lSideTwo = transitions[1];
  CFX_MapPtrTemplate<CBC_ResultPoint*, int32_t> pointCount;
  Increment(pointCount, lSideOne->GetFrom());
  Increment(pointCount, lSideOne->GetTo());
  Increment(pointCount, lSideTwo->GetFrom());
  Increment(pointCount, lSideTwo->GetTo());
  delete transitions[1];
  delete transitions[0];
  transitions.RemoveAll();
  CBC_ResultPoint* maybeTopLeft = nullptr;
  CBC_ResultPoint* bottomLeft = nullptr;
  CBC_ResultPoint* maybeBottomRight = nullptr;
  FX_POSITION itBegin = pointCount.GetStartPosition();
  while (itBegin) {
    CBC_ResultPoint* key = 0;
    int32_t value = 0;
    pointCount.GetNextAssoc(itBegin, key, value);
    if (value == 2) {
      bottomLeft = key;
    } else {
      if (maybeBottomRight) {
        maybeTopLeft = key;
      } else {
        maybeBottomRight = key;
      }
    }
  }
  if (!maybeTopLeft || !bottomLeft || !maybeBottomRight) {
    delete pointA;
    delete pointB;
    delete pointC;
    delete pointD;
    e = BCExceptionNotFound;
    return nullptr;
  }
  CFX_ArrayTemplate<CBC_ResultPoint*> corners;
  corners.SetSize(3);
  corners[0] = maybeTopLeft;
  corners[1] = bottomLeft;
  corners[2] = maybeBottomRight;
  OrderBestPatterns(&corners);
  CBC_ResultPoint* bottomRight = corners[0];
  bottomLeft = corners[1];
  CBC_ResultPoint* topLeft = corners[2];
  CBC_ResultPoint* topRight = nullptr;
  int32_t value;
  if (!pointCount.Lookup(pointA, value)) {
    topRight = pointA;
  } else if (!pointCount.Lookup(pointB, value)) {
    topRight = pointB;
  } else if (!pointCount.Lookup(pointC, value)) {
    topRight = pointC;
  } else {
    topRight = pointD;
  }
  int32_t dimensionTop = std::unique_ptr<CBC_ResultPointsAndTransitions>(
                             TransitionsBetween(topLeft, topRight))
                             ->GetTransitions();
  int32_t dimensionRight = std::unique_ptr<CBC_ResultPointsAndTransitions>(
                               TransitionsBetween(bottomRight, topRight))
                               ->GetTransitions();
  if ((dimensionTop & 0x01) == 1) {
    dimensionTop++;
  }
  dimensionTop += 2;
  if ((dimensionRight & 0x01) == 1) {
    dimensionRight++;
  }
  dimensionRight += 2;
  std::unique_ptr<CBC_CommonBitMatrix> bits;
  std::unique_ptr<CBC_ResultPoint> correctedTopRight;
  if (4 * dimensionTop >= 7 * dimensionRight ||
      4 * dimensionRight >= 7 * dimensionTop) {
    correctedTopRight.reset(
        CorrectTopRightRectangular(bottomLeft, bottomRight, topLeft, topRight,
                                   dimensionTop, dimensionRight));
    if (!correctedTopRight.get()) {
      correctedTopRight.reset(topRight);
    } else {
      delete topRight;
      topRight = nullptr;
    }
    dimensionTop = std::unique_ptr<CBC_ResultPointsAndTransitions>(
                       TransitionsBetween(topLeft, correctedTopRight.get()))
                       ->GetTransitions();
    dimensionRight =
        std::unique_ptr<CBC_ResultPointsAndTransitions>(
            TransitionsBetween(bottomRight, correctedTopRight.get()))
            ->GetTransitions();
    if ((dimensionTop & 0x01) == 1) {
      dimensionTop++;
    }
    if ((dimensionRight & 0x01) == 1) {
      dimensionRight++;
    }
    bits.reset(SampleGrid(m_image, topLeft, bottomLeft, bottomRight,
                          correctedTopRight.get(), dimensionTop, dimensionRight,
                          e));
    BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  } else {
    int32_t dimension = std::min(dimensionRight, dimensionTop);
    correctedTopRight.reset(
        CorrectTopRight(bottomLeft, bottomRight, topLeft, topRight, dimension));
    if (!correctedTopRight.get()) {
      correctedTopRight.reset(topRight);
    } else {
      delete topRight;
      topRight = nullptr;
    }
    int32_t dimensionCorrected =
        std::max(std::unique_ptr<CBC_ResultPointsAndTransitions>(
                     TransitionsBetween(topLeft, correctedTopRight.get()))
                     ->GetTransitions(),
                 std::unique_ptr<CBC_ResultPointsAndTransitions>(
                     TransitionsBetween(bottomRight, correctedTopRight.get()))
                     ->GetTransitions());
    dimensionCorrected++;
    if ((dimensionCorrected & 0x01) == 1) {
      dimensionCorrected++;
    }
    bits.reset(SampleGrid(m_image, topLeft, bottomLeft, bottomRight,
                          correctedTopRight.get(), dimensionCorrected,
                          dimensionCorrected, e));
    BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  }
  CFX_ArrayTemplate<CBC_ResultPoint*>* result =
      new CFX_ArrayTemplate<CBC_ResultPoint*>();
  result->SetSize(4);
  result->Add(topLeft);
  result->Add(bottomLeft);
  result->Add(bottomRight);
  result->Add(correctedTopRight.release());
  return new CBC_QRDetectorResult(bits.release(), result);
}
CBC_ResultPoint* CBC_DataMatrixDetector::CorrectTopRightRectangular(
    CBC_ResultPoint* bottomLeft,
    CBC_ResultPoint* bottomRight,
    CBC_ResultPoint* topLeft,
    CBC_ResultPoint* topRight,
    int32_t dimensionTop,
    int32_t dimensionRight) {
  FX_FLOAT corr = Distance(bottomLeft, bottomRight) / (FX_FLOAT)dimensionTop;
  int32_t norm = Distance(topLeft, topRight);
  FX_FLOAT cos = (topRight->GetX() - topLeft->GetX()) / norm;
  FX_FLOAT sin = (topRight->GetY() - topLeft->GetY()) / norm;
  std::unique_ptr<CBC_ResultPoint> c1(new CBC_ResultPoint(
      topRight->GetX() + corr * cos, topRight->GetY() + corr * sin));
  corr = Distance(bottomLeft, topLeft) / (FX_FLOAT)dimensionRight;
  norm = Distance(bottomRight, topRight);
  cos = (topRight->GetX() - bottomRight->GetX()) / norm;
  sin = (topRight->GetY() - bottomRight->GetY()) / norm;
  std::unique_ptr<CBC_ResultPoint> c2(new CBC_ResultPoint(
      topRight->GetX() + corr * cos, topRight->GetY() + corr * sin));
  if (!IsValid(c1.get())) {
    if (IsValid(c2.get())) {
      return c2.release();
    }
    return nullptr;
  } else if (!IsValid(c2.get())) {
    return c1.release();
  }
  int32_t l1 = FXSYS_abs(dimensionTop -
                         std::unique_ptr<CBC_ResultPointsAndTransitions>(
                             TransitionsBetween(topLeft, c1.get()))
                             ->GetTransitions()) +
               FXSYS_abs(dimensionRight -
                         std::unique_ptr<CBC_ResultPointsAndTransitions>(
                             TransitionsBetween(bottomRight, c1.get()))
                             ->GetTransitions());
  int32_t l2 = FXSYS_abs(dimensionTop -
                         std::unique_ptr<CBC_ResultPointsAndTransitions>(
                             TransitionsBetween(topLeft, c2.get()))
                             ->GetTransitions()) +
               FXSYS_abs(dimensionRight -
                         std::unique_ptr<CBC_ResultPointsAndTransitions>(
                             TransitionsBetween(bottomRight, c2.get()))
                             ->GetTransitions());
  if (l1 <= l2) {
    return c1.release();
  }
  return c2.release();
}
CBC_ResultPoint* CBC_DataMatrixDetector::CorrectTopRight(
    CBC_ResultPoint* bottomLeft,
    CBC_ResultPoint* bottomRight,
    CBC_ResultPoint* topLeft,
    CBC_ResultPoint* topRight,
    int32_t dimension) {
  FX_FLOAT corr = Distance(bottomLeft, bottomRight) / (FX_FLOAT)dimension;
  int32_t norm = Distance(topLeft, topRight);
  FX_FLOAT cos = (topRight->GetX() - topLeft->GetX()) / norm;
  FX_FLOAT sin = (topRight->GetY() - topLeft->GetY()) / norm;
  std::unique_ptr<CBC_ResultPoint> c1(new CBC_ResultPoint(
      topRight->GetX() + corr * cos, topRight->GetY() + corr * sin));
  corr = Distance(bottomLeft, bottomRight) / (FX_FLOAT)dimension;
  norm = Distance(bottomRight, topRight);
  cos = (topRight->GetX() - bottomRight->GetX()) / norm;
  sin = (topRight->GetY() - bottomRight->GetY()) / norm;
  std::unique_ptr<CBC_ResultPoint> c2(new CBC_ResultPoint(
      topRight->GetX() + corr * cos, topRight->GetY() + corr * sin));
  if (!IsValid(c1.get())) {
    if (IsValid(c2.get())) {
      return c2.release();
    }
    return nullptr;
  } else if (!IsValid(c2.get())) {
    return c1.release();
  }
  int32_t l1 = FXSYS_abs(std::unique_ptr<CBC_ResultPointsAndTransitions>(
                             TransitionsBetween(topLeft, c1.get()))
                             ->GetTransitions() -
                         std::unique_ptr<CBC_ResultPointsAndTransitions>(
                             TransitionsBetween(bottomRight, c1.get()))
                             ->GetTransitions());
  int32_t l2 = FXSYS_abs(std::unique_ptr<CBC_ResultPointsAndTransitions>(
                             TransitionsBetween(topLeft, c2.get()))
                             ->GetTransitions() -
                         std::unique_ptr<CBC_ResultPointsAndTransitions>(
                             TransitionsBetween(bottomRight, c2.get()))
                             ->GetTransitions());
  return l1 <= l2 ? c1.release() : c2.release();
}
FX_BOOL CBC_DataMatrixDetector::IsValid(CBC_ResultPoint* p) {
  return p->GetX() >= 0 && p->GetX() < m_image->GetWidth() && p->GetY() > 0 &&
         p->GetY() < m_image->GetHeight();
}
int32_t CBC_DataMatrixDetector::Round(FX_FLOAT d) {
  return (int32_t)(d + 0.5f);
}
int32_t CBC_DataMatrixDetector::Distance(CBC_ResultPoint* a,
                                         CBC_ResultPoint* b) {
  return Round(
      (FX_FLOAT)sqrt((a->GetX() - b->GetX()) * (a->GetX() - b->GetX()) +
                     (a->GetY() - b->GetY()) * (a->GetY() - b->GetY())));
}
void CBC_DataMatrixDetector::Increment(
    CFX_MapPtrTemplate<CBC_ResultPoint*, int32_t>& table,
    CBC_ResultPoint* key) {
  int32_t value;
  if (table.Lookup(key, value)) {
    table.SetAt(key, INTEGERS[value + 1]);
  } else {
    table.SetAt(key, INTEGERS[1]);
  }
}
CBC_CommonBitMatrix* CBC_DataMatrixDetector::SampleGrid(
    CBC_CommonBitMatrix* image,
    CBC_ResultPoint* topLeft,
    CBC_ResultPoint* bottomLeft,
    CBC_ResultPoint* bottomRight,
    CBC_ResultPoint* topRight,
    int32_t dimensionX,
    int32_t dimensionY,
    int32_t& e) {
  CBC_QRGridSampler& sampler = CBC_QRGridSampler::GetInstance();
  CBC_CommonBitMatrix* cbm = sampler.SampleGrid(
      image, dimensionX, dimensionY, 0.5f, 0.5f, dimensionX - 0.5f, 0.5f,
      dimensionX - 0.5f, dimensionY - 0.5f, 0.5f, dimensionY - 0.5f,
      topLeft->GetX(), topLeft->GetY(), topRight->GetX(), topRight->GetY(),
      bottomRight->GetX(), bottomRight->GetY(), bottomLeft->GetX(),
      bottomLeft->GetY(), e);
  BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  return cbm;
}
CBC_ResultPointsAndTransitions* CBC_DataMatrixDetector::TransitionsBetween(
    CBC_ResultPoint* from,
    CBC_ResultPoint* to) {
  int32_t fromX = (int32_t)from->GetX();
  int32_t fromY = (int32_t)from->GetY();
  int32_t toX = (int32_t)to->GetX();
  int32_t toY = (int32_t)to->GetY();
  FX_BOOL steep = FXSYS_abs(toY - fromY) > FXSYS_abs(toX - fromX);
  if (steep) {
    int32_t temp = fromX;
    fromX = fromY;
    fromY = temp;
    temp = toX;
    toX = toY;
    toY = temp;
  }
  int32_t dx = FXSYS_abs(toX - fromX);
  int32_t dy = FXSYS_abs(toY - fromY);
  int32_t error = -dx >> 1;
  int32_t ystep = fromY < toY ? 1 : -1;
  int32_t xstep = fromX < toX ? 1 : -1;
  int32_t transitions = 0;
  FX_BOOL inBlack = m_image->Get(steep ? fromY : fromX, steep ? fromX : fromY);
  for (int32_t x = fromX, y = fromY; x != toX; x += xstep) {
    FX_BOOL isBlack = m_image->Get(steep ? y : x, steep ? x : y);
    if (isBlack != inBlack) {
      transitions++;
      inBlack = isBlack;
    }
    error += dy;
    if (error > 0) {
      if (y == toY) {
        break;
      }
      y += ystep;
      error -= dx;
    }
  }
  return new CBC_ResultPointsAndTransitions(from, to, transitions);
}
void CBC_DataMatrixDetector::OrderBestPatterns(
    CFX_ArrayTemplate<CBC_ResultPoint*>* patterns) {
  FX_FLOAT abDistance = (FX_FLOAT)Distance((*patterns)[0], (*patterns)[1]);
  FX_FLOAT bcDistance = (FX_FLOAT)Distance((*patterns)[1], (*patterns)[2]);
  FX_FLOAT acDistance = (FX_FLOAT)Distance((*patterns)[0], (*patterns)[2]);
  CBC_ResultPoint *topLeft, *topRight, *bottomLeft;
  if (bcDistance >= abDistance && bcDistance >= acDistance) {
    topLeft = (*patterns)[0];
    topRight = (*patterns)[1];
    bottomLeft = (*patterns)[2];
  } else if (acDistance >= bcDistance && acDistance >= abDistance) {
    topLeft = (*patterns)[1];
    topRight = (*patterns)[0];
    bottomLeft = (*patterns)[2];
  } else {
    topLeft = (*patterns)[2];
    topRight = (*patterns)[0];
    bottomLeft = (*patterns)[1];
  }
  if ((bottomLeft->GetY() - topLeft->GetY()) *
          (topRight->GetX() - topLeft->GetX()) <
      (bottomLeft->GetX() - topLeft->GetX()) *
          (topRight->GetY() - topLeft->GetY())) {
    CBC_ResultPoint* temp = topRight;
    topRight = bottomLeft;
    bottomLeft = temp;
  }
  (*patterns)[0] = bottomLeft;
  (*patterns)[1] = topLeft;
  (*patterns)[2] = topRight;
}
