// 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/oned/BC_OneDimReader.h"

#include <memory>

#include "xfa/fxbarcode/BC_Reader.h"
#include "xfa/fxbarcode/common/BC_CommonBitArray.h"
#include "xfa/fxbarcode/oned/BC_OneDReader.h"
#include "xfa/fxbarcode/utils.h"

const int32_t CBC_OneDimReader::START_END_PATTERN[3] = {1, 1, 1};
const int32_t CBC_OneDimReader::MIDDLE_PATTERN[5] = {1, 1, 1, 1, 1};
const int32_t CBC_OneDimReader::L_PATTERNS[10][4] = {
    {3, 2, 1, 1}, {2, 2, 2, 1}, {2, 1, 2, 2}, {1, 4, 1, 1}, {1, 1, 3, 2},
    {1, 2, 3, 1}, {1, 1, 1, 4}, {1, 3, 1, 2}, {1, 2, 1, 3}, {3, 1, 1, 2}};
const int32_t CBC_OneDimReader::L_AND_G_PATTERNS[20][4] = {
    {3, 2, 1, 1}, {2, 2, 2, 1}, {2, 1, 2, 2}, {1, 4, 1, 1}, {1, 1, 3, 2},
    {1, 2, 3, 1}, {1, 1, 1, 4}, {1, 3, 1, 2}, {1, 2, 1, 3}, {3, 1, 1, 2},
    {1, 1, 2, 3}, {1, 2, 2, 2}, {2, 2, 1, 2}, {1, 1, 4, 1}, {2, 3, 1, 1},
    {1, 3, 2, 1}, {4, 1, 1, 1}, {2, 1, 3, 1}, {3, 1, 2, 1}, {2, 1, 1, 3}};

CBC_OneDimReader::CBC_OneDimReader() {}
CBC_OneDimReader::~CBC_OneDimReader() {}
CFX_Int32Array* CBC_OneDimReader::FindStartGuardPattern(CBC_CommonBitArray* row,
                                                        int32_t& e) {
  FX_BOOL foundStart = FALSE;
  CFX_Int32Array* startRange = nullptr;
  CFX_Int32Array startEndPattern;
  startEndPattern.SetSize(3);
  startEndPattern[0] = START_END_PATTERN[0];
  startEndPattern[1] = START_END_PATTERN[1];
  startEndPattern[2] = START_END_PATTERN[2];
  int32_t nextStart = 0;
  while (!foundStart) {
    delete startRange;
    startRange = FindGuardPattern(row, nextStart, FALSE, &startEndPattern, e);
    BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
    int32_t start = (*startRange)[0];
    nextStart = (*startRange)[1];
    if (start <= 1) {
      break;
    }
    int32_t quietStart = start - (nextStart - start);
    if (quietStart >= 0) {
      FX_BOOL booT = row->IsRange(quietStart, start, FALSE, e);
      BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
      foundStart = booT;
    }
  }
  return startRange;
}
CFX_ByteString CBC_OneDimReader::DecodeRow(int32_t rowNumber,
                                           CBC_CommonBitArray* row,
                                           int32_t hints,
                                           int32_t& e) {
  std::unique_ptr<CFX_Int32Array> result(FindStartGuardPattern(row, e));
  BC_EXCEPTION_CHECK_ReturnValue(e, "");
  CFX_ByteString temp = DecodeRow(rowNumber, row, result.get(), hints, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, "");
  return temp;
}
CFX_ByteString CBC_OneDimReader::DecodeRow(int32_t rowNumber,
                                           CBC_CommonBitArray* row,
                                           CFX_Int32Array* startGuardRange,
                                           int32_t hints,
                                           int32_t& e) {
  CFX_ByteString result;
  DecodeMiddle(row, startGuardRange, result, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, "");
  FX_BOOL b = CheckChecksum(result, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, "");
  if (!b) {
    e = BCExceptionChecksumException;
    return "";
  }
  return result;
}
FX_BOOL CBC_OneDimReader::CheckChecksum(CFX_ByteString& s, int32_t& e) {
  FX_BOOL temp = CheckStandardUPCEANChecksum(s, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
  return temp;
}
FX_BOOL CBC_OneDimReader::CheckStandardUPCEANChecksum(CFX_ByteString& s,
                                                      int32_t& e) {
  int32_t length = s.GetLength();
  if (length == 0) {
    return FALSE;
  }
  int32_t sum = 0;
  for (int32_t i = length - 2; i >= 0; i -= 2) {
    int32_t digit = (int32_t)s[i] - (int32_t)'0';
    if (digit < 0 || digit > 9) {
      e = BCExceptionFormatException;
      return FALSE;
    }
    sum += digit;
  }
  sum *= 3;
  for (int32_t j = length - 1; j >= 0; j -= 2) {
    int32_t digit = (int32_t)s[j] - (int32_t)'0';
    if (digit < 0 || digit > 9) {
      e = BCExceptionFormatException;
      return FALSE;
    }
    sum += digit;
  }
  return sum % 10 == 0;
}
CFX_Int32Array* CBC_OneDimReader::DecodeEnd(CBC_CommonBitArray* row,
                                            int32_t endStart,
                                            int32_t& e) {
  CFX_Int32Array startEndPattern;
  startEndPattern.Add(START_END_PATTERN[0]);
  startEndPattern.Add(START_END_PATTERN[1]);
  startEndPattern.Add(START_END_PATTERN[2]);
  CFX_Int32Array* FindGuard =
      FindGuardPattern(row, endStart, FALSE, &startEndPattern, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  return FindGuard;
}
CFX_Int32Array* CBC_OneDimReader::FindGuardPattern(CBC_CommonBitArray* row,
                                                   int32_t rowOffset,
                                                   FX_BOOL whiteFirst,
                                                   CFX_Int32Array* pattern,
                                                   int32_t& e) {
  int32_t patternLength = pattern->GetSize();
  CFX_Int32Array counters;
  counters.SetSize(patternLength);
  int32_t width = row->GetSize();
  FX_BOOL isWhite = FALSE;
  while (rowOffset < width) {
    isWhite = !row->Get(rowOffset);
    if (whiteFirst == isWhite) {
      break;
    }
    rowOffset++;
  }
  int32_t counterPosition = 0;
  int32_t patternStart = rowOffset;
  for (int32_t x = rowOffset; x < width; x++) {
    FX_BOOL pixel = row->Get(x);
    if (pixel ^ isWhite) {
      counters[counterPosition]++;
    } else {
      if (counterPosition == patternLength - 1) {
        if (PatternMatchVariance(&counters, &(*pattern)[0],
                                 MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {
          CFX_Int32Array* result = new CFX_Int32Array();
          result->SetSize(2);
          (*result)[0] = patternStart;
          (*result)[1] = x;
          return result;
        }
        patternStart += counters[0] + counters[1];
        for (int32_t y = 2; y < patternLength; y++) {
          counters[y - 2] = counters[y];
        }
        counters[patternLength - 2] = 0;
        counters[patternLength - 1] = 0;
        counterPosition--;
      } else {
        counterPosition++;
      }
      counters[counterPosition] = 1;
      isWhite = !isWhite;
    }
  }
  e = BCExceptionNotFound;
  BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  return nullptr;
}
int32_t CBC_OneDimReader::DecodeDigit(CBC_CommonBitArray* row,
                                      CFX_Int32Array* counters,
                                      int32_t rowOffset,
                                      const int32_t* patterns,
                                      int32_t patternLength,
                                      int32_t& e) {
  RecordPattern(row, rowOffset, counters, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, 0);
  int32_t bestVariance = MAX_AVG_VARIANCE;
  int32_t bestMatch = -1;
  int32_t max = patternLength;
  for (int32_t i = 0; i < max; i++) {
    int32_t variance = PatternMatchVariance(counters, &patterns[i * 4],
                                            MAX_INDIVIDUAL_VARIANCE);
    if (variance < bestVariance) {
      bestVariance = variance;
      bestMatch = i;
    }
  }
  if (bestMatch >= 0) {
    return bestMatch;
  }
  e = BCExceptionNotFound;
  return 0;
}
