// 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 <array>
#include <memory>

#include "core/fxcrt/check.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_string.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)
    : code_format_(type) {
  DCHECK(code_format_ == BC_TYPE::kCode128B ||
         code_format_ == 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 = code_format_ == 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) {
  loc_text_loc_ = 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 (code_format_ == BC_TYPE::kCode128B) {
    checkSum = Encode128B(contents, &patterns);
  } else {
    checkSum = Encode128C(contents, &patterns);
  }

  checkSum %= 103;
  patterns.push_back(checkSum);
  patterns.push_back(CODE_STOP);
  content_len_ = 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::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;
  const ByteStringView view = contents.AsStringView();
  while (position < view.GetLength()) {
    int32_t patternIndex;
    char ch = view.CharAt(position);
    if (FXSYS_IsDecimalDigit(ch)) {
      patternIndex = StringToInt(
          view.Substr(position, view.IsValidIndex(position + 1) ? 2 : 1));
      ++position;
      if (position < view.GetLength() &&
          FXSYS_IsDecimalDigit(view.CharAt(position))) {
        ++position;
      }
    } else {
      patternIndex = static_cast<int32_t>(ch);
      ++position;
    }
    patterns->push_back(patternIndex);
    checkSum += patternIndex * checkWeight++;
  }
  return checkSum;
}
