// 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/BC_ResultPoint.h"
#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
#include "xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.h"
#include "xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h"

CBC_QRAlignmentPatternFinder::CBC_QRAlignmentPatternFinder(
    CBC_CommonBitMatrix* image,
    int32_t startX,
    int32_t startY,
    int32_t width,
    int32_t height,
    FX_FLOAT moduleSize)
    : m_image(image),
      m_startX(startX),
      m_startY(startY),
      m_width(width),
      m_height(height),
      m_moduleSize(moduleSize) {
  m_crossCheckStateCount.SetSize(3);
}
CBC_QRAlignmentPatternFinder::~CBC_QRAlignmentPatternFinder() {
  for (int32_t i = 0; i < m_possibleCenters.GetSize(); i++) {
    delete (CBC_QRAlignmentPattern*)m_possibleCenters[i];
  }
  m_possibleCenters.RemoveAll();
}
CBC_QRAlignmentPattern* CBC_QRAlignmentPatternFinder::Find(int32_t& e) {
  int32_t startX = m_startX;
  int32_t height = m_height;
  int32_t maxJ = startX + m_width;
  int32_t middleI = m_startY + (height >> 1);
  CFX_Int32Array stateCount;
  stateCount.SetSize(3);
  for (int32_t iGen = 0; iGen < height; iGen++) {
    int32_t i =
        middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1));
    stateCount[0] = 0;
    stateCount[1] = 0;
    stateCount[2] = 0;
    int32_t j = startX;
    while (j < maxJ && !m_image->Get(j, i)) {
      j++;
    }
    int32_t currentState = 0;
    while (j < maxJ) {
      if (m_image->Get(j, i)) {
        if (currentState == 1) {
          stateCount[currentState]++;
        } else {
          if (currentState == 2) {
            if (FoundPatternCross(stateCount)) {
              CBC_QRAlignmentPattern* confirmed =
                  HandlePossibleCenter(stateCount, i, j);
              if (confirmed) {
                return confirmed;
              }
            }
            stateCount[0] = stateCount[2];
            stateCount[1] = 1;
            stateCount[2] = 0;
            currentState = 1;
          } else {
            stateCount[++currentState]++;
          }
        }
      } else {
        if (currentState == 1) {
          currentState++;
        }
        stateCount[currentState]++;
      }
      j++;
    }
    if (FoundPatternCross(stateCount)) {
      CBC_QRAlignmentPattern* confirmed =
          HandlePossibleCenter(stateCount, i, maxJ);
      if (confirmed) {
        return confirmed;
      }
    }
  }
  if (m_possibleCenters.GetSize() != 0) {
    return ((CBC_QRAlignmentPattern*)(m_possibleCenters[0]))->Clone();
  }
  e = BCExceptionRead;
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  return NULL;
}
FX_FLOAT CBC_QRAlignmentPatternFinder::CenterFromEnd(
    const CFX_Int32Array& stateCount,
    int32_t end) {
  return (FX_FLOAT)(end - stateCount[2]) - stateCount[1] / 2.0f;
}
FX_BOOL CBC_QRAlignmentPatternFinder::FoundPatternCross(
    const CFX_Int32Array& stateCount) {
  FX_FLOAT moduleSize = m_moduleSize;
  FX_FLOAT maxVariance = moduleSize / 2.0f;
  for (int32_t i = 0; i < 3; i++) {
    if (fabs(moduleSize - stateCount[i]) >= maxVariance) {
      return false;
    }
  }
  return TRUE;
}
FX_FLOAT CBC_QRAlignmentPatternFinder::CrossCheckVertical(
    int32_t startI,
    int32_t centerJ,
    int32_t maxCount,
    int32_t originalStateCountTotal) {
  int32_t maxI = m_image->GetHeight();
  CFX_Int32Array stateCount;
  stateCount.Copy(m_crossCheckStateCount);
  stateCount[0] = 0;
  stateCount[1] = 0;
  stateCount[2] = 0;
  int32_t i = startI;
  while (i >= 0 && m_image->Get(centerJ, i) && stateCount[1] <= maxCount) {
    stateCount[1]++;
    i--;
  }
  if (i < 0 || stateCount[1] > maxCount) {
    return FXSYS_nan();
  }
  while (i >= 0 && !m_image->Get(centerJ, i) && stateCount[0] <= maxCount) {
    stateCount[0]++;
    i--;
  }
  if (stateCount[0] > maxCount) {
    return FXSYS_nan();
  }
  i = startI + 1;
  while (i < maxI && m_image->Get(centerJ, i) && stateCount[1] <= maxCount) {
    stateCount[1]++;
    i++;
  }
  if (i == maxI || stateCount[1] > maxCount) {
    return FXSYS_nan();
  }
  while (i < maxI && !m_image->Get(centerJ, i) && stateCount[2] <= maxCount) {
    stateCount[2]++;
    i++;
  }
  if (stateCount[2] > maxCount) {
    return FXSYS_nan();
  }
  int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
  if (5 * abs(stateCountTotal - originalStateCountTotal) >=
      originalStateCountTotal) {
    return FXSYS_nan();
  }
  return FoundPatternCross(stateCount) ? CenterFromEnd(stateCount, i)
                                       : FXSYS_nan();
}
CBC_QRAlignmentPattern* CBC_QRAlignmentPatternFinder::HandlePossibleCenter(
    const CFX_Int32Array& stateCount,
    int32_t i,
    int32_t j) {
  int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
  FX_FLOAT centerJ = CenterFromEnd(stateCount, j);
  FX_FLOAT centerI = CrossCheckVertical(i, (int32_t)centerJ, 2 * stateCount[1],
                                        stateCountTotal);
  if (!FXSYS_isnan(centerI)) {
    FX_FLOAT estimatedModuleSize =
        (FX_FLOAT)(stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f;
    int32_t max = m_possibleCenters.GetSize();
    for (int32_t index = 0; index < max; index++) {
      CBC_QRAlignmentPattern* center =
          (CBC_QRAlignmentPattern*)(m_possibleCenters[index]);
      if (center->AboutEquals(estimatedModuleSize, centerI, centerJ)) {
        return new CBC_QRAlignmentPattern(centerJ, centerI,
                                          estimatedModuleSize);
      }
    }
    m_possibleCenters.Add(
        new CBC_QRAlignmentPattern(centerJ, centerI, estimatedModuleSize));
  }
  return NULL;
}
