// 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 2007 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 <stdint.h>

#include "xfa/fxbarcode/datamatrix/BC_DataMatrixVersion.h"
#include "xfa/fxbarcode/utils.h"

CFX_ArrayTemplate<CBC_DataMatrixVersion*>* CBC_DataMatrixVersion::VERSIONS =
    nullptr;

void CBC_DataMatrixVersion::Initialize() {
  VERSIONS = new CFX_ArrayTemplate<CBC_DataMatrixVersion*>();
}
void CBC_DataMatrixVersion::Finalize() {
  for (int32_t i = 0; i < VERSIONS->GetSize(); i++) {
    delete VERSIONS->GetAt(i);
  }
  VERSIONS->RemoveAll();
  delete VERSIONS;
}
CBC_DataMatrixVersion::CBC_DataMatrixVersion(int32_t versionNumber,
                                             int32_t symbolSizeRows,
                                             int32_t symbolSizeColumns,
                                             int32_t dataRegionSizeRows,
                                             int32_t dataRegionSizeColumns,
                                             ECBlocks* ecBlocks) {
  m_versionNumber = versionNumber;
  m_symbolSizeRows = symbolSizeRows;
  m_symbolSizeColumns = symbolSizeColumns;
  m_dataRegionSizeRows = dataRegionSizeRows;
  m_dataRegionSizeColumns = dataRegionSizeColumns;
  m_ecBlocks = ecBlocks;
  int32_t total = 0;
  int32_t ecCodewords = ecBlocks->GetECCodewords();
  const CFX_ArrayTemplate<ECB*>& ecbArray = ecBlocks->GetECBlocks();
  for (int32_t i = 0; i < ecbArray.GetSize(); i++) {
    total += ecbArray[i]->GetCount() *
             (ecbArray[i]->GetDataCodewords() + ecCodewords);
  }
  m_totalCodewords = total;
}
CBC_DataMatrixVersion::~CBC_DataMatrixVersion() {
  delete m_ecBlocks;
}
int32_t CBC_DataMatrixVersion::GetVersionNumber() {
  return m_versionNumber;
}
int32_t CBC_DataMatrixVersion::GetSymbolSizeRows() {
  return m_symbolSizeRows;
}
int32_t CBC_DataMatrixVersion::GetSymbolSizeColumns() {
  return m_symbolSizeColumns;
}
int32_t CBC_DataMatrixVersion::GetDataRegionSizeRows() {
  return m_dataRegionSizeRows;
}
int32_t CBC_DataMatrixVersion::GetDataRegionSizeColumns() {
  return m_dataRegionSizeColumns;
}
int32_t CBC_DataMatrixVersion::GetTotalCodewords() {
  return m_totalCodewords;
}
ECBlocks* CBC_DataMatrixVersion::GetECBlocks() {
  return m_ecBlocks;
}
void CBC_DataMatrixVersion::ReleaseAll() {
  for (int32_t i = 0; i < VERSIONS->GetSize(); i++) {
    delete VERSIONS->GetAt(i);
  }
  VERSIONS->RemoveAll();
}
CBC_DataMatrixVersion* CBC_DataMatrixVersion::GetVersionForDimensions(
    int32_t numRows,
    int32_t numColumns,
    int32_t& e) {
  if ((numRows & 0x01) != 0 || (numColumns & 0x01) != 0) {
    e = BCExceptionNotFound;
    return nullptr;
  }
  if (VERSIONS->GetSize() == 0) {
    VERSIONS->Add(new CBC_DataMatrixVersion(1, 10, 10, 8, 8,
                                            new ECBlocks(5, new ECB(1, 3))));
    VERSIONS->Add(new CBC_DataMatrixVersion(2, 12, 12, 10, 10,
                                            new ECBlocks(7, new ECB(1, 5))));
    VERSIONS->Add(new CBC_DataMatrixVersion(3, 14, 14, 12, 12,
                                            new ECBlocks(10, new ECB(1, 8))));
    VERSIONS->Add(new CBC_DataMatrixVersion(4, 16, 16, 14, 14,
                                            new ECBlocks(12, new ECB(1, 12))));
    VERSIONS->Add(new CBC_DataMatrixVersion(5, 18, 18, 16, 16,
                                            new ECBlocks(14, new ECB(1, 18))));
    VERSIONS->Add(new CBC_DataMatrixVersion(6, 20, 20, 18, 18,
                                            new ECBlocks(18, new ECB(1, 22))));
    VERSIONS->Add(new CBC_DataMatrixVersion(7, 22, 22, 20, 20,
                                            new ECBlocks(20, new ECB(1, 30))));
    VERSIONS->Add(new CBC_DataMatrixVersion(8, 24, 24, 22, 22,
                                            new ECBlocks(24, new ECB(1, 36))));
    VERSIONS->Add(new CBC_DataMatrixVersion(9, 26, 26, 24, 24,
                                            new ECBlocks(28, new ECB(1, 44))));
    VERSIONS->Add(new CBC_DataMatrixVersion(10, 32, 32, 14, 14,
                                            new ECBlocks(36, new ECB(1, 62))));
    VERSIONS->Add(new CBC_DataMatrixVersion(11, 36, 36, 16, 16,
                                            new ECBlocks(42, new ECB(1, 86))));
    VERSIONS->Add(new CBC_DataMatrixVersion(12, 40, 40, 18, 18,
                                            new ECBlocks(48, new ECB(1, 114))));
    VERSIONS->Add(new CBC_DataMatrixVersion(13, 44, 44, 20, 20,
                                            new ECBlocks(56, new ECB(1, 144))));
    VERSIONS->Add(new CBC_DataMatrixVersion(14, 48, 48, 22, 22,
                                            new ECBlocks(68, new ECB(1, 174))));
    VERSIONS->Add(new CBC_DataMatrixVersion(15, 52, 52, 24, 24,
                                            new ECBlocks(42, new ECB(2, 102))));
    VERSIONS->Add(new CBC_DataMatrixVersion(16, 64, 64, 14, 14,
                                            new ECBlocks(56, new ECB(2, 140))));
    VERSIONS->Add(new CBC_DataMatrixVersion(17, 72, 72, 16, 16,
                                            new ECBlocks(36, new ECB(4, 92))));
    VERSIONS->Add(new CBC_DataMatrixVersion(18, 80, 80, 18, 18,
                                            new ECBlocks(48, new ECB(4, 114))));
    VERSIONS->Add(new CBC_DataMatrixVersion(19, 88, 88, 20, 20,
                                            new ECBlocks(56, new ECB(4, 144))));
    VERSIONS->Add(new CBC_DataMatrixVersion(20, 96, 96, 22, 22,
                                            new ECBlocks(68, new ECB(4, 174))));
    VERSIONS->Add(new CBC_DataMatrixVersion(21, 104, 104, 24, 24,
                                            new ECBlocks(56, new ECB(6, 136))));
    VERSIONS->Add(new CBC_DataMatrixVersion(22, 120, 120, 18, 18,
                                            new ECBlocks(68, new ECB(6, 175))));
    VERSIONS->Add(new CBC_DataMatrixVersion(23, 132, 132, 20, 20,
                                            new ECBlocks(62, new ECB(8, 163))));
    VERSIONS->Add(new CBC_DataMatrixVersion(
        24, 144, 144, 22, 22,
        new ECBlocks(62, new ECB(8, 156), new ECB(2, 155))));
    VERSIONS->Add(new CBC_DataMatrixVersion(25, 8, 18, 6, 16,
                                            new ECBlocks(7, new ECB(1, 5))));
    VERSIONS->Add(new CBC_DataMatrixVersion(26, 8, 32, 6, 14,
                                            new ECBlocks(11, new ECB(1, 10))));
    VERSIONS->Add(new CBC_DataMatrixVersion(27, 12, 26, 10, 24,
                                            new ECBlocks(14, new ECB(1, 16))));
    VERSIONS->Add(new CBC_DataMatrixVersion(28, 12, 36, 10, 16,
                                            new ECBlocks(18, new ECB(1, 22))));
    VERSIONS->Add(new CBC_DataMatrixVersion(29, 16, 36, 14, 16,
                                            new ECBlocks(24, new ECB(1, 32))));
    VERSIONS->Add(new CBC_DataMatrixVersion(30, 16, 48, 14, 22,
                                            new ECBlocks(28, new ECB(1, 49))));
  }
  int32_t numVersions = VERSIONS->GetSize();
  for (int32_t i = 0; i < numVersions; ++i) {
    if ((*VERSIONS)[i]->m_symbolSizeRows == numRows &&
        (*VERSIONS)[i]->m_symbolSizeColumns == numColumns) {
      return (*VERSIONS)[i];
    }
  }
  e = BCExceptionNotFound;
  return nullptr;
}
