// 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 2007 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/qrcode/BC_QRFinderPatternFinder.h"

#include <memory>

#include "core/fxcrt/include/fx_basic.h"
#include "xfa/fxbarcode/BC_ResultPoint.h"
#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
#include "xfa/fxbarcode/qrcode/BC_FinderPatternInfo.h"
#include "xfa/fxbarcode/qrcode/BC_QRFinderPattern.h"
#include "xfa/fxbarcode/utils.h"

const int32_t CBC_QRFinderPatternFinder::CENTER_QUORUM = 2;
const int32_t CBC_QRFinderPatternFinder::MIN_SKIP = 3;
const int32_t CBC_QRFinderPatternFinder::MAX_MODULES = 57;
const int32_t CBC_QRFinderPatternFinder::INTEGER_MATH_SHIFT = 8;

CBC_QRFinderPatternFinder::CBC_QRFinderPatternFinder(
    CBC_CommonBitMatrix* image) {
  m_image = image;
  m_crossCheckStateCount.SetSize(5);
  m_hasSkipped = FALSE;
}

CBC_QRFinderPatternFinder::~CBC_QRFinderPatternFinder() {
  for (int32_t i = 0; i < m_possibleCenters.GetSize(); i++)
    delete m_possibleCenters[i];
}

class ClosestToAverageComparator {
 private:
  FX_FLOAT m_averageModuleSize;

 public:
  ClosestToAverageComparator(FX_FLOAT averageModuleSize)
      : m_averageModuleSize(averageModuleSize) {}
  int32_t operator()(FinderPattern* a, FinderPattern* b) {
    FX_FLOAT dA =
        (FX_FLOAT)fabs(a->GetEstimatedModuleSize() - m_averageModuleSize);
    FX_FLOAT dB =
        (FX_FLOAT)fabs(b->GetEstimatedModuleSize() - m_averageModuleSize);
    return dA < dB ? -1 : dA > dB ? 1 : 0;
  }
};
class CenterComparator {
 public:
  int32_t operator()(FinderPattern* a, FinderPattern* b) {
    return b->GetCount() - a->GetCount();
  }
};
CBC_CommonBitMatrix* CBC_QRFinderPatternFinder::GetImage() {
  return m_image;
}
CFX_Int32Array& CBC_QRFinderPatternFinder::GetCrossCheckStateCount() {
  m_crossCheckStateCount[0] = 0;
  m_crossCheckStateCount[1] = 0;
  m_crossCheckStateCount[2] = 0;
  m_crossCheckStateCount[3] = 0;
  m_crossCheckStateCount[4] = 0;
  return m_crossCheckStateCount;
}

CFX_ArrayTemplate<CBC_QRFinderPattern*>*
CBC_QRFinderPatternFinder::GetPossibleCenters() {
  return &m_possibleCenters;
}

CBC_QRFinderPatternInfo* CBC_QRFinderPatternFinder::Find(int32_t hint,
                                                         int32_t& e) {
  int32_t maxI = m_image->GetHeight();
  int32_t maxJ = m_image->GetWidth();
  int32_t iSkip = (3 * maxI) / (4 * MAX_MODULES);
  if (iSkip < MIN_SKIP || 0) {
    iSkip = MIN_SKIP;
  }
  FX_BOOL done = FALSE;
  CFX_Int32Array stateCount;
  stateCount.SetSize(5);
  for (int32_t i = iSkip - 1; i < maxI && !done; i += iSkip) {
    stateCount[0] = 0;
    stateCount[1] = 0;
    stateCount[2] = 0;
    stateCount[3] = 0;
    stateCount[4] = 0;
    int32_t currentState = 0;
    for (int32_t j = 0; j < maxJ; j++) {
      if (m_image->Get(j, i)) {
        if ((currentState & 1) == 1) {
          currentState++;
        }
        stateCount[currentState]++;
      } else {
        if ((currentState & 1) == 0) {
          if (currentState == 4) {
            if (FoundPatternCross(stateCount)) {
              FX_BOOL confirmed = HandlePossibleCenter(stateCount, i, j);
              if (confirmed) {
                iSkip = 2;
                if (m_hasSkipped) {
                  done = HaveMultiplyConfirmedCenters();
                } else {
                  int32_t rowSkip = FindRowSkip();
                  if (rowSkip > stateCount[2]) {
                    i += rowSkip - stateCount[2] - iSkip;
                    j = maxJ - 1;
                  }
                }
              } else {
                do {
                  j++;
                } while (j < maxJ && !m_image->Get(j, i));
                j--;
              }
              currentState = 0;
              stateCount[0] = 0;
              stateCount[1] = 0;
              stateCount[2] = 0;
              stateCount[3] = 0;
              stateCount[4] = 0;
            } else {
              stateCount[0] = stateCount[2];
              stateCount[1] = stateCount[3];
              stateCount[2] = stateCount[4];
              stateCount[3] = 1;
              stateCount[4] = 0;
              currentState = 3;
            }
          } else {
            stateCount[++currentState]++;
          }
        } else {
          stateCount[currentState]++;
        }
      }
    }
    if (FoundPatternCross(stateCount)) {
      FX_BOOL confirmed = HandlePossibleCenter(stateCount, i, maxJ);
      if (confirmed) {
        iSkip = stateCount[0];
        if (m_hasSkipped) {
          done = HaveMultiplyConfirmedCenters();
        }
      }
    }
  }
  std::unique_ptr<CFX_ArrayTemplate<CBC_QRFinderPattern*>> patternInfo(
      SelectBestpatterns(e));
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  OrderBestPatterns(patternInfo.get());
  return new CBC_QRFinderPatternInfo(patternInfo.get());
}
void CBC_QRFinderPatternFinder::OrderBestPatterns(
    CFX_ArrayTemplate<CBC_QRFinderPattern*>* patterns) {
  FX_FLOAT abDistance = Distance((*patterns)[0], (*patterns)[1]);
  FX_FLOAT bcDistance = Distance((*patterns)[1], (*patterns)[2]);
  FX_FLOAT acDistance = Distance((*patterns)[0], (*patterns)[2]);
  CBC_QRFinderPattern* topLeft;
  CBC_QRFinderPattern* topRight;
  CBC_QRFinderPattern* 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_QRFinderPattern* temp = topRight;
    topRight = bottomLeft;
    bottomLeft = temp;
  }
  (*patterns)[0] = bottomLeft;
  (*patterns)[1] = topLeft;
  (*patterns)[2] = topRight;
}
FX_FLOAT CBC_QRFinderPatternFinder::Distance(CBC_ResultPoint* point1,
                                             CBC_ResultPoint* point2) {
  FX_FLOAT dx = point1->GetX() - point2->GetX();
  FX_FLOAT dy = point1->GetY() - point2->GetY();
  return (FX_FLOAT)FXSYS_sqrt(dx * dx + dy * dy);
}
FX_FLOAT CBC_QRFinderPatternFinder::CenterFromEnd(
    const CFX_Int32Array& stateCount,
    int32_t end) {
  return (FX_FLOAT)(end - stateCount[4] - stateCount[3]) - stateCount[2] / 2.0f;
}
FX_BOOL CBC_QRFinderPatternFinder::FoundPatternCross(
    const CFX_Int32Array& stateCount) {
  int32_t totalModuleSize = 0;
  for (int32_t i = 0; i < 5; i++) {
    int32_t count = stateCount[i];
    if (count == 0) {
      return FALSE;
    }
    totalModuleSize += count;
  }
  if (totalModuleSize < 7) {
    return FALSE;
  }
  int32_t moduleSize = (totalModuleSize << INTEGER_MATH_SHIFT) / 7;
  int32_t maxVariance = moduleSize / 2;
  return FXSYS_abs(moduleSize - (stateCount[0] << INTEGER_MATH_SHIFT)) <
             maxVariance &&
         FXSYS_abs(moduleSize - (stateCount[1] << INTEGER_MATH_SHIFT)) <
             maxVariance &&
         FXSYS_abs(3 * moduleSize - (stateCount[2] << INTEGER_MATH_SHIFT)) <
             3 * maxVariance &&
         FXSYS_abs(moduleSize - (stateCount[3] << INTEGER_MATH_SHIFT)) <
             maxVariance &&
         FXSYS_abs(moduleSize - (stateCount[4] << INTEGER_MATH_SHIFT)) <
             maxVariance;
}
FX_FLOAT CBC_QRFinderPatternFinder::CrossCheckVertical(
    int32_t startI,
    int32_t centerJ,
    int32_t maxCount,
    int32_t originalStateCountTotal) {
  CBC_CommonBitMatrix* image = m_image;
  int32_t maxI = image->GetHeight();
  CFX_Int32Array& stateCount = GetCrossCheckStateCount();
  int32_t i = startI;
  while (i >= 0 && image->Get(centerJ, i)) {
    stateCount[2]++;
    i--;
  }
  if (i < 0) {
    return FXSYS_nan();
  }
  while (i >= 0 && !image->Get(centerJ, i) && stateCount[1] <= maxCount) {
    stateCount[1]++;
    i--;
  }
  if (i < 0 || stateCount[1] > maxCount) {
    return FXSYS_nan();
  }
  while (i >= 0 && image->Get(centerJ, i) && stateCount[0] <= maxCount) {
    stateCount[0]++;
    i--;
  }
  if (stateCount[0] > maxCount) {
    return FXSYS_nan();
  }
  i = startI + 1;
  while (i < maxI && image->Get(centerJ, i)) {
    stateCount[2]++;
    i++;
  }
  if (i == maxI) {
    return FXSYS_nan();
  }
  while (i < maxI && !image->Get(centerJ, i) && stateCount[3] < maxCount) {
    stateCount[3]++;
    i++;
  }
  if (i == maxI || stateCount[3] >= maxCount) {
    return FXSYS_nan();
  }
  while (i < maxI && image->Get(centerJ, i) && stateCount[4] < maxCount) {
    stateCount[4]++;
    i++;
  }
  if (stateCount[4] >= maxCount) {
    return FXSYS_nan();
  }
  int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] +
                            stateCount[3] + stateCount[4];
  if (5 * FXSYS_abs(stateCountTotal - originalStateCountTotal) >=
      originalStateCountTotal) {
    return FXSYS_nan();
  }
  return FoundPatternCross(stateCount) ? CenterFromEnd(stateCount, i)
                                       : FXSYS_nan();
}
FX_FLOAT CBC_QRFinderPatternFinder::CrossCheckHorizontal(
    int32_t startJ,
    int32_t centerI,
    int32_t maxCount,
    int32_t originalStateCountTotal) {
  CBC_CommonBitMatrix* image = m_image;
  int32_t maxJ = image->GetWidth();
  CFX_Int32Array& stateCount = GetCrossCheckStateCount();
  int32_t j = startJ;
  while (j >= 0 && image->Get(j, centerI)) {
    stateCount[2]++;
    j--;
  }
  if (j < 0) {
    return FXSYS_nan();
  }
  while (j >= 0 && !image->Get(j, centerI) && stateCount[1] <= maxCount) {
    stateCount[1]++;
    j--;
  }
  if (j < 0 || stateCount[1] > maxCount) {
    return FXSYS_nan();
  }
  while (j >= 0 && image->Get(j, centerI) && stateCount[0] <= maxCount) {
    stateCount[0]++;
    j--;
  }
  if (stateCount[0] > maxCount) {
    return FXSYS_nan();
  }
  j = startJ + 1;
  while (j < maxJ && image->Get(j, centerI)) {
    stateCount[2]++;
    j++;
  }
  if (j == maxJ) {
    return FXSYS_nan();
  }
  while (j < maxJ && !image->Get(j, centerI) && stateCount[3] < maxCount) {
    stateCount[3]++;
    j++;
  }
  if (j == maxJ || stateCount[3] >= maxCount) {
    return FXSYS_nan();
  }
  while (j < maxJ && image->Get(j, centerI) && stateCount[4] < maxCount) {
    stateCount[4]++;
    j++;
  }
  if (stateCount[4] >= maxCount) {
    return FXSYS_nan();
  }
  int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] +
                            stateCount[3] + stateCount[4];
  if (5 * FXSYS_abs(stateCountTotal - originalStateCountTotal) >=
      originalStateCountTotal) {
    return FXSYS_nan();
  }
  return FoundPatternCross(stateCount) ? CenterFromEnd(stateCount, j)
                                       : FXSYS_nan();
}
FX_BOOL CBC_QRFinderPatternFinder::HandlePossibleCenter(
    const CFX_Int32Array& stateCount,
    int32_t i,
    int32_t j) {
  int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] +
                            stateCount[3] + stateCount[4];
  FX_FLOAT centerJ = CenterFromEnd(stateCount, j);
  FX_FLOAT centerI =
      CrossCheckVertical(i, (int32_t)centerJ, stateCount[2], stateCountTotal);
  if (!FXSYS_isnan(centerI)) {
    centerJ = CrossCheckHorizontal((int32_t)centerJ, (int32_t)centerI,
                                   stateCount[2], stateCountTotal);
    if (!FXSYS_isnan(centerJ)) {
      FX_FLOAT estimatedModuleSize = (FX_FLOAT)stateCountTotal / 7.0f;
      FX_BOOL found = FALSE;
      int32_t max = m_possibleCenters.GetSize();
      for (int32_t index = 0; index < max; index++) {
        CBC_QRFinderPattern* center = m_possibleCenters[index];
        if (center->AboutEquals(estimatedModuleSize, centerI, centerJ)) {
          center->IncrementCount();
          found = TRUE;
          break;
        }
      }
      if (!found) {
        m_possibleCenters.Add(
            new CBC_QRFinderPattern(centerJ, centerI, estimatedModuleSize));
      }
      return TRUE;
    }
  }
  return FALSE;
}
int32_t CBC_QRFinderPatternFinder::FindRowSkip() {
  int32_t max = m_possibleCenters.GetSize();
  if (max <= 1) {
    return 0;
  }
  FinderPattern* firstConfirmedCenter = NULL;
  for (int32_t i = 0; i < max; i++) {
    CBC_QRFinderPattern* center = m_possibleCenters[i];
    if (center->GetCount() >= CENTER_QUORUM) {
      if (firstConfirmedCenter == NULL) {
        firstConfirmedCenter = center;
      } else {
        m_hasSkipped = TRUE;
        return (int32_t)((fabs(firstConfirmedCenter->GetX() - center->GetX()) -
                          fabs(firstConfirmedCenter->GetY() - center->GetY())) /
                         2);
      }
    }
  }
  return 0;
}
FX_BOOL CBC_QRFinderPatternFinder::HaveMultiplyConfirmedCenters() {
  int32_t confirmedCount = 0;
  FX_FLOAT totalModuleSize = 0.0f;
  int32_t max = m_possibleCenters.GetSize();
  int32_t i;
  for (i = 0; i < max; i++) {
    CBC_QRFinderPattern* pattern = m_possibleCenters[i];
    if (pattern->GetCount() >= CENTER_QUORUM) {
      confirmedCount++;
      totalModuleSize += pattern->GetEstimatedModuleSize();
    }
  }
  if (confirmedCount < 3) {
    return FALSE;
  }
  FX_FLOAT average = totalModuleSize / (FX_FLOAT)max;
  FX_FLOAT totalDeviation = 0.0f;
  for (i = 0; i < max; i++) {
    CBC_QRFinderPattern* pattern = m_possibleCenters[i];
    totalDeviation += fabs(pattern->GetEstimatedModuleSize() - average);
  }
  return totalDeviation <= 0.05f * totalModuleSize;
}

CFX_ArrayTemplate<CBC_QRFinderPattern*>*
CBC_QRFinderPatternFinder::SelectBestpatterns(int32_t& e) {
  int32_t startSize = m_possibleCenters.GetSize();
  if (m_possibleCenters.GetSize() < 3) {
    e = BCExceptionRead;
    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  }
  FX_FLOAT average = 0.0f;
  if (startSize > 3) {
    FX_FLOAT totalModuleSize = 0.0f;
    for (int32_t i = 0; i < startSize; i++)
      totalModuleSize += m_possibleCenters[i]->GetEstimatedModuleSize();

    average = totalModuleSize / (FX_FLOAT)startSize;
    for (int32_t j = 0;
         j < m_possibleCenters.GetSize() && m_possibleCenters.GetSize() > 3;
         j++) {
      CBC_QRFinderPattern* pattern = m_possibleCenters[j];
      if (fabs(pattern->GetEstimatedModuleSize() - average) > 0.2f * average) {
        delete pattern;
        m_possibleCenters.RemoveAt(j);
        j--;
      }
    }
  }
  if (m_possibleCenters.GetSize() > 3) {
    std::sort(m_possibleCenters.GetData(),
              m_possibleCenters.GetData() + m_possibleCenters.GetSize(),
              [](const CBC_QRFinderPattern* a, CBC_QRFinderPattern* b) {
                return a->GetCount() > b->GetCount();  // e.g. Descending.
              });
  }
  CFX_ArrayTemplate<CBC_QRFinderPattern*>* vec =
      new CFX_ArrayTemplate<CBC_QRFinderPattern*>();
  vec->SetSize(3);
  (*vec)[0] = m_possibleCenters[0]->Clone();
  (*vec)[1] = m_possibleCenters[1]->Clone();
  (*vec)[2] = m_possibleCenters[2]->Clone();
  return vec;
}
