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

#include "core/fxcrt/notreached.h"
#include "fxbarcode/datamatrix/BC_DataMatrixSymbolInfo144.h"
#include "fxbarcode/datamatrix/BC_Encoder.h"

namespace {

constexpr size_t kSymbolsCount = 30;
constexpr size_t kSymbolDataSize = kSymbolsCount - 1;

std::array<CBC_SymbolInfo*, kSymbolsCount> g_symbols = {};

constexpr std::array<CBC_SymbolInfo::Data, kSymbolDataSize> kSymbolData = {
    {{3, 5, 3, 5, 8, 8, 1},           {5, 7, 5, 7, 10, 10, 1},
     {5, 7, 5, 7, 16, 6, 1},          {8, 10, 8, 10, 12, 12, 1},
     {10, 11, 10, 11, 14, 6, 2},      {12, 12, 12, 12, 14, 14, 1},
     {16, 14, 16, 14, 24, 10, 1},     {18, 14, 18, 14, 16, 16, 1},
     {22, 18, 22, 18, 18, 18, 1},     {22, 18, 22, 18, 16, 10, 2},
     {30, 20, 30, 20, 20, 20, 1},     {32, 24, 32, 24, 16, 14, 2},
     {36, 24, 36, 24, 22, 22, 1},     {44, 28, 44, 28, 24, 24, 1},
     {49, 28, 49, 28, 22, 14, 2},     {62, 36, 62, 36, 14, 14, 4},
     {86, 42, 86, 42, 16, 16, 4},     {114, 48, 114, 48, 18, 18, 4},
     {144, 56, 144, 56, 20, 20, 4},   {174, 68, 174, 68, 22, 22, 4},
     {204, 84, 102, 42, 24, 24, 4},   {280, 112, 140, 56, 14, 14, 16},
     {368, 144, 92, 36, 16, 16, 16},  {456, 192, 114, 48, 18, 18, 16},
     {576, 224, 144, 56, 20, 20, 16}, {696, 272, 174, 68, 22, 22, 16},
     {816, 336, 136, 56, 24, 24, 16}, {1050, 408, 175, 68, 18, 18, 36},
     {1304, 496, 163, 62, 20, 20, 36}}};

}  // namespace

// static
void CBC_SymbolInfo::Initialize() {
  for (size_t i = 0; i < kSymbolDataSize; ++i) {
    g_symbols[i] = new CBC_SymbolInfo(&kSymbolData[i]);
  }
  g_symbols[kSymbolDataSize] = new CBC_DataMatrixSymbolInfo144();
}

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

CBC_SymbolInfo::CBC_SymbolInfo(const Data* data) : data_(data) {}

CBC_SymbolInfo::~CBC_SymbolInfo() = default;

const CBC_SymbolInfo* CBC_SymbolInfo::Lookup(size_t data_codewords,
                                             bool allow_rectangular) {
  for (size_t i = 0; i < kSymbolsCount; ++i) {
    CBC_SymbolInfo* symbol = g_symbols[i];
    if (symbol->is_rectangular() && !allow_rectangular) {
      continue;
    }

    if (data_codewords <= symbol->data_capacity()) {
      return symbol;
    }
  }
  return nullptr;
}

int32_t CBC_SymbolInfo::GetHorizontalDataRegions() const {
  switch (data_->data_regions) {
    case 1:
      return 1;
    case 2:
      return 2;
    case 4:
      return 2;
    case 16:
      return 4;
    case 36:
      return 6;
    default:
      NOTREACHED();
  }
}

int32_t CBC_SymbolInfo::GetVerticalDataRegions() const {
  switch (data_->data_regions) {
    case 1:
      return 1;
    case 2:
      return 1;
    case 4:
      return 2;
    case 16:
      return 4;
    case 36:
      return 6;
    default:
      NOTREACHED();
  }
}

int32_t CBC_SymbolInfo::GetSymbolDataWidth() const {
  return GetHorizontalDataRegions() * data_->matrix_width;
}

int32_t CBC_SymbolInfo::GetSymbolDataHeight() const {
  return GetVerticalDataRegions() * data_->matrix_height;
}

int32_t CBC_SymbolInfo::GetSymbolWidth() const {
  return GetSymbolDataWidth() + (GetHorizontalDataRegions() * 2);
}

int32_t CBC_SymbolInfo::GetSymbolHeight() const {
  return GetSymbolDataHeight() + (GetVerticalDataRegions() * 2);
}

size_t CBC_SymbolInfo::GetInterleavedBlockCount() const {
  return data_->data_capacity / data_->rs_block_data;
}

size_t CBC_SymbolInfo::GetDataLengthForInterleavedBlock() const {
  return data_->rs_block_data;
}

size_t CBC_SymbolInfo::GetErrorLengthForInterleavedBlock() const {
  return data_->rs_block_error;
}
