// Copyright 2014 The PDFium Authors
// 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 2010 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 "fxbarcode/oned/BC_OnedCode128Writer.h"

#include <ctype.h>

#include <array>
#include <memory>

#include "core/fxcrt/check.h"
#include "fxbarcode/BC_Writer.h"
#include "fxbarcode/oned/BC_OneDimWriter.h"

namespace {

constexpr size_t kPatternSize = 7;

using CodePatternRow = std::array<uint8_t, kPatternSize>;
constexpr std::array<const CodePatternRow, 107> kCodePatternTable = {
    {{2, 1, 2, 2, 2, 2, 0}, {2, 2, 2, 1, 2, 2, 0}, {2, 2, 2, 2, 2, 1, 0},
     {1, 2, 1, 2, 2, 3, 0}, {1, 2, 1, 3, 2, 2, 0}, {1, 3, 1, 2, 2, 2, 0},
     {1, 2, 2, 2, 1, 3, 0}, {1, 2, 2, 3, 1, 2, 0}, {1, 3, 2, 2, 1, 2, 0},
     {2, 2, 1, 2, 1, 3, 0}, {2, 2, 1, 3, 1, 2, 0}, {2, 3, 1, 2, 1, 2, 0},
     {1, 1, 2, 2, 3, 2, 0}, {1, 2, 2, 1, 3, 2, 0}, {1, 2, 2, 2, 3, 1, 0},
     {1, 1, 3, 2, 2, 2, 0}, {1, 2, 3, 1, 2, 2, 0}, {1, 2, 3, 2, 2, 1, 0},
     {2, 2, 3, 2, 1, 1, 0}, {2, 2, 1, 1, 3, 2, 0}, {2, 2, 1, 2, 3, 1, 0},
     {2, 1, 3, 2, 1, 2, 0}, {2, 2, 3, 1, 1, 2, 0}, {3, 1, 2, 1, 3, 1, 0},
     {3, 1, 1, 2, 2, 2, 0}, {3, 2, 1, 1, 2, 2, 0}, {3, 2, 1, 2, 2, 1, 0},
     {3, 1, 2, 2, 1, 2, 0}, {3, 2, 2, 1, 1, 2, 0}, {3, 2, 2, 2, 1, 1, 0},
     {2, 1, 2, 1, 2, 3, 0}, {2, 1, 2, 3, 2, 1, 0}, {2, 3, 2, 1, 2, 1, 0},
     {1, 1, 1, 3, 2, 3, 0}, {1, 3, 1, 1, 2, 3, 0}, {1, 3, 1, 3, 2, 1, 0},
     {1, 1, 2, 3, 1, 3, 0}, {1, 3, 2, 1, 1, 3, 0}, {1, 3, 2, 3, 1, 1, 0},
     {2, 1, 1, 3, 1, 3, 0}, {2, 3, 1, 1, 1, 3, 0}, {2, 3, 1, 3, 1, 1, 0},
     {1, 1, 2, 1, 3, 3, 0}, {1, 1, 2, 3, 3, 1, 0}, {1, 3, 2, 1, 3, 1, 0},
     {1, 1, 3, 1, 2, 3, 0}, {1, 1, 3, 3, 2, 1, 0}, {1, 3, 3, 1, 2, 1, 0},
     {3, 1, 3, 1, 2, 1, 0}, {2, 1, 1, 3, 3, 1, 0}, {2, 3, 1, 1, 3, 1, 0},
     {2, 1, 3, 1, 1, 3, 0}, {2, 1, 3, 3, 1, 1, 0}, {2, 1, 3, 1, 3, 1, 0},
     {3, 1, 1, 1, 2, 3, 0}, {3, 1, 1, 3, 2, 1, 0}, {3, 3, 1, 1, 2, 1, 0},
     {3, 1, 2, 1, 1, 3, 0}, {3, 1, 2, 3, 1, 1, 0}, {3, 3, 2, 1, 1, 1, 0},
     {3, 1, 4, 1, 1, 1, 0}, {2, 2, 1, 4, 1, 1, 0}, {4, 3, 1, 1, 1, 1, 0},
     {1, 1, 1, 2, 2, 4, 0}, {1, 1, 1, 4, 2, 2, 0}, {1, 2, 1, 1, 2, 4, 0},
     {1, 2, 1, 4, 2, 1, 0}, {1, 4, 1, 1, 2, 2, 0}, {1, 4, 1, 2, 2, 1, 0},
     {1, 1, 2, 2, 1, 4, 0}, {1, 1, 2, 4, 1, 2, 0}, {1, 2, 2, 1, 1, 4, 0},
     {1, 2, 2, 4, 1, 1, 0}, {1, 4, 2, 1, 1, 2, 0}, {1, 4, 2, 2, 1, 1, 0},
     {2, 4, 1, 2, 1, 1, 0}, {2, 2, 1, 1, 1, 4, 0}, {4, 1, 3, 1, 1, 1, 0},
     {2, 4, 1, 1, 1, 2, 0}, {1, 3, 4, 1, 1, 1, 0}, {1, 1, 1, 2, 4, 2, 0},
     {1, 2, 1, 1, 4, 2, 0}, {1, 2, 1, 2, 4, 1, 0}, {1, 1, 4, 2, 1, 2, 0},
     {1, 2, 4, 1, 1, 2, 0}, {1, 2, 4, 2, 1, 1, 0}, {4, 1, 1, 2, 1, 2, 0},
     {4, 2, 1, 1, 1, 2, 0}, {4, 2, 1, 2, 1, 1, 0}, {2, 1, 2, 1, 4, 1, 0},
     {2, 1, 4, 1, 2, 1, 0}, {4, 1, 2, 1, 2, 1, 0}, {1, 1, 1, 1, 4, 3, 0},
     {1, 1, 1, 3, 4, 1, 0}, {1, 3, 1, 1, 4, 1, 0}, {1, 1, 4, 1, 1, 3, 0},
     {1, 1, 4, 3, 1, 1, 0}, {4, 1, 1, 1, 1, 3, 0}, {4, 1, 1, 3, 1, 1, 0},
     {1, 1, 3, 1, 4, 1, 0}, {1, 1, 4, 1, 3, 1, 0}, {3, 1, 1, 1, 4, 1, 0},
     {4, 1, 1, 1, 3, 1, 0}, {2, 1, 1, 4, 1, 2, 0}, {2, 1, 1, 2, 1, 4, 0},
     {2, 1, 1, 2, 3, 2, 0}, {2, 3, 3, 1, 1, 1, 2}}};

const int32_t CODE_START_B = 104;
const int32_t CODE_START_C = 105;
const int32_t CODE_STOP = 106;

bool IsInOnedCode128Alphabet(wchar_t ch) {
  int32_t index = static_cast<int32_t>(ch);
  return index >= 32 && index <= 126 && index != 34;
}

}  // namespace

CBC_OnedCode128Writer::CBC_OnedCode128Writer(BC_TYPE type)
    : m_codeFormat(type) {
  DCHECK(m_codeFormat == BC_TYPE::kCode128B ||
         m_codeFormat == BC_TYPE::kCode128C);
}

CBC_OnedCode128Writer::~CBC_OnedCode128Writer() = default;

bool CBC_OnedCode128Writer::CheckContentValidity(WideStringView contents) {
  return HasValidContentSize(contents) &&
         std::all_of(contents.begin(), contents.end(), IsInOnedCode128Alphabet);
}

WideString CBC_OnedCode128Writer::FilterContents(WideStringView contents) {
  const wchar_t limit = m_codeFormat == BC_TYPE::kCode128B ? 126 : 106;

  WideString filtered;
  filtered.Reserve(contents.GetLength());
  for (size_t i = 0; i < contents.GetLength(); i++) {
    wchar_t ch = contents[i];
    if (ch > 175) {
      i++;
      continue;
    }
    if (ch >= 32 && ch <= limit)
      filtered += ch;
  }
  return filtered;
}

void CBC_OnedCode128Writer::SetTextLocation(BC_TEXT_LOC location) {
  m_locTextLoc = location;
}

DataVector<uint8_t> CBC_OnedCode128Writer::Encode(const ByteString& contents) {
  if (contents.GetLength() < 1 || contents.GetLength() > 80)
    return DataVector<uint8_t>();

  std::vector<int32_t> patterns;
  int32_t checkSum = 0;
  if (m_codeFormat == BC_TYPE::kCode128B)
    checkSum = Encode128B(contents, &patterns);
  else
    checkSum = Encode128C(contents, &patterns);

  checkSum %= 103;
  patterns.push_back(checkSum);
  patterns.push_back(CODE_STOP);
  m_iContentLen = contents.GetLength() + 3;
  int32_t codeWidth = 0;
  for (const auto& patternIndex : patterns) {
    for (size_t i = 0; i < kPatternSize; ++i)
      codeWidth += kCodePatternTable[patternIndex][i];
  }
  DataVector<uint8_t> result(codeWidth);
  auto result_span = pdfium::make_span(result);
  for (const int32_t pattern_index : patterns) {
    result_span =
        AppendPattern(result_span, kCodePatternTable[pattern_index], true);
  }
  return result;
}

// static
int32_t CBC_OnedCode128Writer::Encode128B(const ByteString& contents,
                                          std::vector<int32_t>* patterns) {
  int32_t checkWeight = 1;
  patterns->push_back(CODE_START_B);
  int32_t checkSum = CODE_START_B * checkWeight;
  for (size_t position = 0; position < contents.GetLength(); position++) {
    int32_t patternIndex = contents[position] - ' ';
    patterns->push_back(patternIndex);
    checkSum += patternIndex * checkWeight++;
  }
  return checkSum;
}

// static
int32_t CBC_OnedCode128Writer::Encode128C(const ByteString& contents,
                                          std::vector<int32_t>* patterns) {
  int32_t checkWeight = 1;
  patterns->push_back(CODE_START_C);
  int32_t checkSum = CODE_START_C * checkWeight;
  size_t position = 0;
  while (position < contents.GetLength()) {
    int32_t patternIndex;
    char ch = contents[position];
    if (isdigit(ch)) {
      patternIndex = FXSYS_atoi(
          contents.Substr(position, contents.IsValidIndex(position + 1) ? 2 : 1)
              .c_str());
      ++position;
      if (position < contents.GetLength() && isdigit(contents[position]))
        ++position;
    } else {
      patternIndex = static_cast<int32_t>(ch);
      ++position;
    }
    patterns->push_back(patternIndex);
    checkSum += patternIndex * checkWeight++;
  }
  return checkSum;
}
