// 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 2006 Jeremias Maerki
 *
 * 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/datamatrix/BC_SymbolInfo.h"

#include "fxbarcode/common/BC_CommonBitMatrix.h"
#include "fxbarcode/datamatrix/BC_DataMatrixSymbolInfo144.h"
#include "fxbarcode/datamatrix/BC_Encoder.h"
#include "fxbarcode/utils.h"

namespace {

const size_t kSymbolsCount = 30;

CBC_SymbolInfo* g_symbols[kSymbolsCount] = {
    nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
    nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
    nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
    nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};

}  // namespace

void CBC_SymbolInfo::Initialize() {
  g_symbols[0] = new CBC_SymbolInfo(3, 5, 8, 8, 1);
  g_symbols[1] = new CBC_SymbolInfo(5, 7, 10, 10, 1);
  g_symbols[2] = new CBC_SymbolInfo(5, 7, 16, 6, 1);
  g_symbols[3] = new CBC_SymbolInfo(8, 10, 12, 12, 1);
  g_symbols[4] = new CBC_SymbolInfo(10, 11, 14, 6, 2);
  g_symbols[5] = new CBC_SymbolInfo(12, 12, 14, 14, 1);
  g_symbols[6] = new CBC_SymbolInfo(16, 14, 24, 10, 1);
  g_symbols[7] = new CBC_SymbolInfo(18, 14, 16, 16, 1);
  g_symbols[8] = new CBC_SymbolInfo(22, 18, 18, 18, 1);
  g_symbols[9] = new CBC_SymbolInfo(22, 18, 16, 10, 2);
  g_symbols[10] = new CBC_SymbolInfo(30, 20, 20, 20, 1);
  g_symbols[11] = new CBC_SymbolInfo(32, 24, 16, 14, 2);
  g_symbols[12] = new CBC_SymbolInfo(36, 24, 22, 22, 1);
  g_symbols[13] = new CBC_SymbolInfo(44, 28, 24, 24, 1);
  g_symbols[14] = new CBC_SymbolInfo(49, 28, 22, 14, 2);
  g_symbols[15] = new CBC_SymbolInfo(62, 36, 14, 14, 4);
  g_symbols[16] = new CBC_SymbolInfo(86, 42, 16, 16, 4);
  g_symbols[17] = new CBC_SymbolInfo(114, 48, 18, 18, 4);
  g_symbols[18] = new CBC_SymbolInfo(144, 56, 20, 20, 4);
  g_symbols[19] = new CBC_SymbolInfo(174, 68, 22, 22, 4);
  g_symbols[20] = new CBC_SymbolInfo(204, 84, 24, 24, 4, 102, 42);
  g_symbols[21] = new CBC_SymbolInfo(280, 112, 14, 14, 16, 140, 56);
  g_symbols[22] = new CBC_SymbolInfo(368, 144, 16, 16, 16, 92, 36);
  g_symbols[23] = new CBC_SymbolInfo(456, 192, 18, 18, 16, 114, 48);
  g_symbols[24] = new CBC_SymbolInfo(576, 224, 20, 20, 16, 144, 56);
  g_symbols[25] = new CBC_SymbolInfo(696, 272, 22, 22, 16, 174, 68);
  g_symbols[26] = new CBC_SymbolInfo(816, 336, 24, 24, 16, 136, 56);
  g_symbols[27] = new CBC_SymbolInfo(1050, 408, 18, 18, 36, 175, 68);
  g_symbols[28] = new CBC_SymbolInfo(1304, 496, 20, 20, 36, 163, 62);
  g_symbols[29] = new CBC_DataMatrixSymbolInfo144();
}

void CBC_SymbolInfo::Finalize() {
  for (size_t i = 0; i < kSymbolsCount; i++) {
    delete g_symbols[i];
    g_symbols[i] = nullptr;
  }
}

CBC_SymbolInfo::CBC_SymbolInfo(int32_t dataCapacity,
                               int32_t errorCodewords,
                               int32_t matrixWidth,
                               int32_t matrixHeight,
                               int32_t dataRegions)
    : CBC_SymbolInfo(dataCapacity,
                     errorCodewords,
                     matrixWidth,
                     matrixHeight,
                     dataRegions,
                     dataCapacity,
                     errorCodewords) {}

CBC_SymbolInfo::CBC_SymbolInfo(int32_t dataCapacity,
                               int32_t errorCodewords,
                               int32_t matrixWidth,
                               int32_t matrixHeight,
                               int32_t dataRegions,
                               int32_t rsBlockData,
                               int32_t rsBlockError)
    : m_rectangular(matrixWidth != matrixHeight),
      m_dataCapacity(dataCapacity),
      m_errorCodewords(errorCodewords),
      m_matrixWidth(matrixWidth),
      m_matrixHeight(matrixHeight),
      m_dataRegions(dataRegions),
      m_rsBlockData(rsBlockData),
      m_rsBlockError(rsBlockError) {}

CBC_SymbolInfo::~CBC_SymbolInfo() {}

CBC_SymbolInfo* CBC_SymbolInfo::lookup(int32_t dataCodewords,
                                       bool allowRectangular,
                                       int32_t& e) {
  for (size_t i = 0; i < kSymbolsCount; i++) {
    CBC_SymbolInfo* symbol = g_symbols[i];
    if (symbol->m_rectangular && !allowRectangular)
      continue;

    if (dataCodewords <= symbol->dataCapacity())
      return symbol;
  }
  e = BCExceptionIllegalDataCodewords;
  return nullptr;
}

int32_t CBC_SymbolInfo::getHorizontalDataRegions() const {
  switch (m_dataRegions) {
    case 1:
      return 1;
    case 2:
      return 2;
    case 4:
      return 2;
    case 16:
      return 4;
    case 36:
      return 6;
    default:
      NOTREACHED();
      return 0;
  }
}

int32_t CBC_SymbolInfo::getVerticalDataRegions() const {
  switch (m_dataRegions) {
    case 1:
      return 1;
    case 2:
      return 1;
    case 4:
      return 2;
    case 16:
      return 4;
    case 36:
      return 6;
    default:
      NOTREACHED();
      return 0;
  }
}

int32_t CBC_SymbolInfo::getSymbolDataWidth() const {
  return getHorizontalDataRegions() * m_matrixWidth;
}

int32_t CBC_SymbolInfo::getSymbolDataHeight() const {
  return getVerticalDataRegions() * m_matrixHeight;
}

int32_t CBC_SymbolInfo::getSymbolWidth() const {
  return getSymbolDataWidth() + (getHorizontalDataRegions() * 2);
}

int32_t CBC_SymbolInfo::getSymbolHeight() const {
  return getSymbolDataHeight() + (getVerticalDataRegions() * 2);
}

int32_t CBC_SymbolInfo::getCodewordCount() const {
  return m_dataCapacity + m_errorCodewords;
}

int32_t CBC_SymbolInfo::getInterleavedBlockCount() const {
  return m_dataCapacity / m_rsBlockData;
}

int32_t CBC_SymbolInfo::getDataLengthForInterleavedBlock(int32_t index) const {
  return m_rsBlockData;
}

int32_t CBC_SymbolInfo::getErrorLengthForInterleavedBlock(int32_t index) const {
  return m_rsBlockError;
}
