// 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 2008 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 "xfa/fxbarcode/datamatrix/BC_DataMatrixDataBlock.h"

#include <memory>

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

CBC_DataMatrixDataBlock::~CBC_DataMatrixDataBlock() {}
CBC_DataMatrixDataBlock::CBC_DataMatrixDataBlock(int32_t numDataCodewords,
                                                 CFX_ByteArray* codewords) {
  m_codewords.Copy(*codewords);
  m_numDataCodewords = numDataCodewords;
}
CFX_ArrayTemplate<CBC_DataMatrixDataBlock*>*
CBC_DataMatrixDataBlock::GetDataBlocks(CFX_ByteArray* rawCodewords,
                                       CBC_DataMatrixVersion* version,
                                       int32_t& e) {
  ECBlocks* ecBlocks = version->GetECBlocks();
  int32_t totalBlocks = 0;
  const CFX_ArrayTemplate<ECB*>& ecBlockArray = ecBlocks->GetECBlocks();
  int32_t i;
  for (i = 0; i < ecBlockArray.GetSize(); i++) {
    totalBlocks += ecBlockArray[i]->GetCount();
  }
  std::unique_ptr<CFX_ArrayTemplate<CBC_DataMatrixDataBlock*>> result(
      new CFX_ArrayTemplate<CBC_DataMatrixDataBlock*>());
  result->SetSize(totalBlocks);
  int32_t numResultBlocks = 0;
  int32_t j;
  for (j = 0; j < ecBlockArray.GetSize(); j++) {
    for (i = 0; i < ((ECB*)ecBlockArray[j])->GetCount(); i++) {
      int32_t numDataCodewords = ((ECB*)ecBlockArray[j])->GetDataCodewords();
      int32_t numBlockCodewords = ecBlocks->GetECCodewords() + numDataCodewords;
      CFX_ByteArray codewords;
      codewords.SetSize(numBlockCodewords);
      (*result)[numResultBlocks++] =
          new CBC_DataMatrixDataBlock(numDataCodewords, &codewords);
      codewords.SetSize(0);
    }
  }
  int32_t longerBlocksTotalCodewords = (*result)[0]->GetCodewords()->GetSize();
  int32_t longerBlocksNumDataCodewords =
      longerBlocksTotalCodewords - ecBlocks->GetECCodewords();
  int32_t shorterBlocksNumDataCodewords = longerBlocksNumDataCodewords - 1;
  int32_t rawCodewordsOffset = 0;
  for (i = 0; i < shorterBlocksNumDataCodewords; i++) {
    int32_t j;
    for (j = 0; j < numResultBlocks; j++) {
      if (rawCodewordsOffset < rawCodewords->GetSize()) {
        (*result)[j]->GetCodewords()->operator[](i) =
            (*rawCodewords)[rawCodewordsOffset++];
      }
    }
  }
  const bool specialVersion = version->GetVersionNumber() == 24;
  int32_t numLongerBlocks = specialVersion ? 8 : numResultBlocks;
  for (j = 0; j < numLongerBlocks; j++) {
    if (rawCodewordsOffset < rawCodewords->GetSize()) {
      (*result)[j]->GetCodewords()->operator[](longerBlocksNumDataCodewords -
                                               1) =
          (*rawCodewords)[rawCodewordsOffset++];
    }
  }
  int32_t max = (*result)[0]->GetCodewords()->GetSize();
  for (i = longerBlocksNumDataCodewords; i < max; i++) {
    int32_t j;
    for (j = 0; j < numResultBlocks; j++) {
      int32_t iOffset = specialVersion && j > 7 ? i - 1 : i;
      if (rawCodewordsOffset < rawCodewords->GetSize()) {
        (*result)[j]->GetCodewords()->operator[](iOffset) =
            (*rawCodewords)[rawCodewordsOffset++];
      }
    }
  }
  if (rawCodewordsOffset != rawCodewords->GetSize()) {
    e = BCExceptionIllegalArgument;
    return NULL;
  }
  return result.release();
}
int32_t CBC_DataMatrixDataBlock::GetNumDataCodewords() {
  return m_numDataCodewords;
}
CFX_ByteArray* CBC_DataMatrixDataBlock::GetCodewords() {
  return &m_codewords;
}
