// 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 2009 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 <memory>

#include "xfa/fxbarcode/BC_BinaryBitmap.h"
#include "xfa/fxbarcode/BC_ResultPoint.h"
#include "xfa/fxbarcode/common/BC_CommonBitArray.h"
#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
#include "xfa/fxbarcode/pdf417/BC_PDF417Detector.h"
#include "xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.h"
#include "xfa/fxbarcode/utils.h"

#define INTEGER_MAX 2147483647

int32_t CBC_Detector::INDEXES_START_PATTERN[] = {0, 4, 1, 5};
int32_t CBC_Detector::INDEXES_STOP_PATTERN[] = {6, 2, 7, 3};
int32_t CBC_Detector::INTEGER_MATH_SHIFT = 8;
int32_t CBC_Detector::PATTERN_MATCH_RESULT_SCALE_FACTOR = 1
                                                          << INTEGER_MATH_SHIFT;
int32_t CBC_Detector::MAX_AVG_VARIANCE =
    (int32_t)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.42f);
int32_t CBC_Detector::MAX_INDIVIDUAL_VARIANCE =
    (int32_t)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.8f);
int32_t CBC_Detector::START_PATTERN[] = {8, 1, 1, 1, 1, 1, 1, 3};
int32_t CBC_Detector::STOP_PATTERN[] = {7, 1, 1, 3, 1, 1, 1, 2, 1};
int32_t CBC_Detector::MAX_PIXEL_DRIFT = 3;
int32_t CBC_Detector::MAX_PATTERN_DRIFT = 5;
int32_t CBC_Detector::SKIPPED_ROW_COUNT_MAX = 25;
int32_t CBC_Detector::ROW_STEP = 5;
int32_t CBC_Detector::BARCODE_MIN_HEIGHT = 10;

CBC_Detector::CBC_Detector() {}
CBC_Detector::~CBC_Detector() {}

CBC_PDF417DetectorResult* CBC_Detector::detect(CBC_BinaryBitmap* image,
                                               int32_t hints,
                                               FX_BOOL multiple,
                                               int32_t& e) {
  CBC_CommonBitMatrix* bitMatrix = image->GetBlackMatrix(e);
  BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  CBC_ResultPointArrayArray* barcodeCoordinates = detect(multiple, bitMatrix);
  if (barcodeCoordinates->GetSize() == 0) {
    rotate180(bitMatrix);
    barcodeCoordinates = detect(multiple, bitMatrix);
  }
  if (barcodeCoordinates->GetSize() == 0) {
    e = BCExceptionUnSupportedBarcode;
    BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  }
  return new CBC_PDF417DetectorResult(bitMatrix, barcodeCoordinates);
}
void CBC_Detector::rotate180(CBC_CommonBitMatrix* bitMatrix) {
  int32_t width = bitMatrix->GetWidth();
  int32_t height = bitMatrix->GetHeight();
  CBC_CommonBitArray* firstRowBitArray = new CBC_CommonBitArray(width);
  CBC_CommonBitArray* secondRowBitArray = new CBC_CommonBitArray(width);
  CBC_CommonBitArray* tmpBitArray = new CBC_CommonBitArray(width);
  for (int32_t y = 0; y<(height + 1)>> 1; y++) {
    CBC_CommonBitArray* temp =
        bitMatrix->GetRow(height - 1 - y, secondRowBitArray);
    CBC_CommonBitArray* tempfirstRow = firstRowBitArray;
    firstRowBitArray = bitMatrix->GetRow(y, tempfirstRow);
    delete tempfirstRow;
    CBC_CommonBitArray* row = mirror(temp, tmpBitArray);
    delete temp;
    bitMatrix->SetRow(y, row);
    delete row;
    CBC_CommonBitArray* rowfirstRow = mirror(firstRowBitArray, tmpBitArray);
    bitMatrix->SetRow(height - 1 - y, rowfirstRow);
    delete rowfirstRow;
  }
  delete tmpBitArray;
  delete firstRowBitArray;
  delete secondRowBitArray;
}
CBC_CommonBitArray* CBC_Detector::mirror(CBC_CommonBitArray* input,
                                         CBC_CommonBitArray* result) {
  CBC_CommonBitArray* array = new CBC_CommonBitArray(result->GetSize());
  array->Clear();
  int32_t size = input->GetSize();
  for (int32_t i = 0; i < size; i++) {
    if (input->Get(i)) {
      array->Set(size - 1 - i);
    }
  }
  return array;
}

CBC_ResultPointArrayArray* CBC_Detector::detect(
    FX_BOOL multiple,
    CBC_CommonBitMatrix* bitMatrix) {
  CBC_ResultPointArrayArray* barcodeCoordinates = new CBC_ResultPointArrayArray;
  int32_t row = 0;
  int32_t column = 0;
  FX_BOOL foundBarcodeInRow = FALSE;
  while (row < bitMatrix->GetHeight()) {
    CBC_ResultPointArray* vertices = findVertices(bitMatrix, row, column);
    if (!vertices->GetAt(0) && !vertices->GetAt(3)) {
      if (!foundBarcodeInRow) {
        delete vertices;
        break;
      }
      foundBarcodeInRow = FALSE;
      column = 0;
      for (int32_t i = 0; i < barcodeCoordinates->GetSize(); i++) {
        CBC_ResultPointArray* barcodeCoordinate = barcodeCoordinates->GetAt(i);
        if (barcodeCoordinate->GetAt(1)) {
          row = row > barcodeCoordinate->GetAt(1)->GetY();
        }
        if (barcodeCoordinate->GetAt(3)) {
          row = row > barcodeCoordinate->GetAt(3)->GetY();
        }
      }
      row += ROW_STEP;
      delete vertices;
      continue;
    }
    foundBarcodeInRow = TRUE;
    barcodeCoordinates->Add(vertices);
    if (!multiple) {
      break;
    }
    if (vertices->GetAt(2)) {
      column = (int32_t)vertices->GetAt(2)->GetX();
      row = (int32_t)vertices->GetAt(2)->GetY();
    } else {
      column = (int32_t)vertices->GetAt(4)->GetX();
      row = (int32_t)vertices->GetAt(4)->GetY();
    }
  }
  return barcodeCoordinates;
}

CBC_ResultPointArray* CBC_Detector::findVertices(CBC_CommonBitMatrix* matrix,
                                                 int32_t startRow,
                                                 int32_t startColumn) {
  int32_t height = matrix->GetHeight();
  int32_t width = matrix->GetWidth();
  CBC_ResultPointArray* result = new CBC_ResultPointArray;
  result->SetSize(8);
  std::unique_ptr<CBC_ResultPointArray> startptr(
      findRowsWithPattern(matrix, height, width, startRow, startColumn,
                          START_PATTERN, FX_ArraySize(START_PATTERN)));
  copyToResult(result, startptr.get(), INDEXES_START_PATTERN,
               FX_ArraySize(INDEXES_START_PATTERN));
  if (result->GetAt(4)) {
    startColumn = (int32_t)result->GetAt(4)->GetX();
    startRow = (int32_t)result->GetAt(4)->GetY();
  }
  std::unique_ptr<CBC_ResultPointArray> stopptr(
      findRowsWithPattern(matrix, height, width, startRow, startColumn,
                          STOP_PATTERN, FX_ArraySize(STOP_PATTERN)));
  copyToResult(result, stopptr.get(), INDEXES_STOP_PATTERN,
               FX_ArraySize(INDEXES_STOP_PATTERN));
  return result;
}

void CBC_Detector::copyToResult(CBC_ResultPointArray* result,
                                CBC_ResultPointArray* tmpResult,
                                int32_t* destinationIndexes,
                                int32_t destinationLength) {
  for (int32_t i = 0; i < destinationLength; i++) {
    result->SetAt(destinationIndexes[i], tmpResult->GetAt(i));
  }
}

CBC_ResultPointArray* CBC_Detector::findRowsWithPattern(
    CBC_CommonBitMatrix* matrix,
    int32_t height,
    int32_t width,
    int32_t startRow,
    int32_t startColumn,
    int32_t* pattern,
    int32_t patternLength) {
  CBC_ResultPointArray* result = new CBC_ResultPointArray;
  result->SetSize(4);
  FX_BOOL found = FALSE;
  CFX_Int32Array counters;
  counters.SetSize(patternLength);
  for (; startRow < height; startRow += ROW_STEP) {
    CFX_Int32Array* loc =
        findGuardPattern(matrix, startColumn, startRow, width, FALSE, pattern,
                         patternLength, counters);
    if (loc) {
      while (startRow > 0) {
        CFX_Int32Array* previousRowLoc =
            findGuardPattern(matrix, startColumn, --startRow, width, FALSE,
                             pattern, patternLength, counters);
        if (previousRowLoc) {
          delete loc;
          loc = previousRowLoc;
        } else {
          startRow++;
          break;
        }
      }
      result->SetAt(
          0, new CBC_ResultPoint((FX_FLOAT)loc->GetAt(0), (FX_FLOAT)startRow));
      result->SetAt(
          1, new CBC_ResultPoint((FX_FLOAT)loc->GetAt(1), (FX_FLOAT)startRow));
      found = TRUE;
      delete loc;
      break;
    }
  }
  int32_t stopRow = startRow + 1;
  if (found) {
    int32_t skippedRowCount = 0;
    CFX_Int32Array previousRowLoc;
    previousRowLoc.Add((int32_t)result->GetAt(0)->GetX());
    previousRowLoc.Add((int32_t)result->GetAt(1)->GetX());
    for (; stopRow < height; stopRow++) {
      CFX_Int32Array* loc =
          findGuardPattern(matrix, previousRowLoc[0], stopRow, width, FALSE,
                           pattern, patternLength, counters);
      if (loc && abs(previousRowLoc[0] - loc->GetAt(0)) < MAX_PATTERN_DRIFT &&
          abs(previousRowLoc[1] - loc->GetAt(1)) < MAX_PATTERN_DRIFT) {
        previousRowLoc.Copy(*loc);
        skippedRowCount = 0;
      } else {
        if (skippedRowCount > SKIPPED_ROW_COUNT_MAX) {
          delete loc;
          break;
        } else {
          skippedRowCount++;
        }
      }
      delete loc;
    }
    stopRow -= skippedRowCount + 1;
    result->SetAt(2, new CBC_ResultPoint((FX_FLOAT)previousRowLoc.GetAt(0),
                                         (FX_FLOAT)stopRow));
    result->SetAt(3, new CBC_ResultPoint((FX_FLOAT)previousRowLoc.GetAt(1),
                                         (FX_FLOAT)stopRow));
  }
  if (stopRow - startRow < BARCODE_MIN_HEIGHT) {
    for (int32_t i = 0; i < result->GetSize(); i++) {
      result->SetAt(i, nullptr);
    }
  }
  return result;
}
CFX_Int32Array* CBC_Detector::findGuardPattern(CBC_CommonBitMatrix* matrix,
                                               int32_t column,
                                               int32_t row,
                                               int32_t width,
                                               FX_BOOL whiteFirst,
                                               int32_t* pattern,
                                               int32_t patternLength,
                                               CFX_Int32Array& counters) {
  for (int32_t i = 0; i < counters.GetSize(); i++) {
    counters.SetAt(i, 0);
  }
  FX_BOOL isWhite = whiteFirst;
  int32_t patternStart = column;
  int32_t pixelDrift = 0;
  CFX_Int32Array* intarray = new CFX_Int32Array;
  while (matrix->Get(patternStart, row) && patternStart > 0 &&
         pixelDrift++ < MAX_PIXEL_DRIFT) {
    patternStart--;
  }
  int32_t x = patternStart;
  int32_t counterPosition = 0;
  for (; x < width; x++) {
    FX_BOOL pixel = matrix->Get(x, row);
    if (pixel ^ isWhite) {
      counters[counterPosition]++;
    } else {
      if (counterPosition == patternLength - 1) {
        if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) <
            MAX_AVG_VARIANCE) {
          intarray->Add(patternStart);
          intarray->Add(x);
          return intarray;
        }
        patternStart += counters[0] + counters[1];
        for (int32_t l = 2, k = 0; l < patternLength; l++, k++) {
          counters.SetAt(k, counters.GetAt(l));
        }
        counters.SetAt(patternLength - 2, 0);
        counters.SetAt(patternLength - 1, 0);
        counterPosition--;
      } else {
        counterPosition++;
      }
      counters[counterPosition] = 1;
      isWhite = !isWhite;
    }
  }
  if (counterPosition == patternLength - 1) {
    if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) <
        MAX_AVG_VARIANCE) {
      intarray->Add(patternStart);
      intarray->Add(x - 1);
      return intarray;
    }
  }
  delete intarray;
  return nullptr;
}
int32_t CBC_Detector::patternMatchVariance(CFX_Int32Array& counters,
                                           int32_t* pattern,
                                           int32_t maxIndividualVariance) {
  int32_t numCounters = counters.GetSize();
  int32_t total = 0;
  int32_t patternLength = 0;
  for (int32_t i = 0; i < numCounters; i++) {
    total += counters[i];
    patternLength += pattern[i];
  }
  if (total < patternLength) {
    return INTEGER_MAX;
  }
  int32_t unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength;
  maxIndividualVariance =
      (maxIndividualVariance * unitBarWidth) >> INTEGER_MATH_SHIFT;
  int32_t totalVariance = 0;
  for (int32_t x = 0; x < numCounters; x++) {
    int32_t counter = counters[x] << INTEGER_MATH_SHIFT;
    int32_t scaledPattern = pattern[x] * unitBarWidth;
    int32_t variance = counter > scaledPattern ? counter - scaledPattern
                                               : scaledPattern - counter;
    if (variance > maxIndividualVariance) {
      return INTEGER_MAX;
    }
    totalVariance += variance;
  }
  return totalVariance / total;
}
