// 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 "../barcode.h"
#include "../BC_Writer.h"
#include "../BC_TwoDimWriter.h"
#include "../BC_Dimension.h"
#include "../BC_BinaryBitmap.h"
#include "../BC_UtilCodingConvert.h"
#include "../common/BC_CommonBitMatrix.h"
#include "../common/BC_CommonByteMatrix.h"
#include "BC_Encoder.h"
#include "BC_DefaultPlacement.h"
#include "BC_SymbolShapeHint.h"
#include "BC_SymbolInfo.h"
#include "BC_DataMatrixSymbolInfo144.h"
#include "BC_ErrorCorrection.h"
#include "BC_EncoderContext.h"
#include "BC_C40Encoder.h"
#include "BC_TextEncoder.h"
#include "BC_X12Encoder.h"
#include "BC_EdifactEncoder.h"
#include "BC_Base256Encoder.h"
#include "BC_ASCIIEncoder.h"
#include "BC_HighLevelEncoder.h"
#include "BC_DataMatrixWriter.h"
CBC_DataMatrixWriter::CBC_DataMatrixWriter() {}
CBC_DataMatrixWriter::~CBC_DataMatrixWriter() {}
FX_BOOL CBC_DataMatrixWriter::SetErrorCorrectionLevel(int32_t level) {
  m_iCorrectLevel = level;
  return TRUE;
}
uint8_t* CBC_DataMatrixWriter::Encode(const CFX_WideString& contents,
                                      int32_t& outWidth,
                                      int32_t& outHeight,
                                      int32_t& e) {
  if (outWidth < 0 || outHeight < 0) {
    e = BCExceptionHeightAndWidthMustBeAtLeast1;
    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  }
  CBC_SymbolShapeHint::SymbolShapeHint shape =
      CBC_SymbolShapeHint::FORCE_SQUARE;
  CBC_Dimension* minSize = NULL;
  CBC_Dimension* maxSize = NULL;
  CFX_WideString ecLevel;
  CFX_WideString encoded = CBC_HighLevelEncoder::encodeHighLevel(
      contents, ecLevel, shape, minSize, maxSize, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  CBC_SymbolInfo* symbolInfo = CBC_SymbolInfo::lookup(
      encoded.GetLength(), shape, minSize, maxSize, TRUE, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  CFX_WideString codewords =
      CBC_ErrorCorrection::encodeECC200(encoded, symbolInfo, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  CBC_DefaultPlacement* placement =
      new CBC_DefaultPlacement(codewords, symbolInfo->getSymbolDataWidth(e),
                               symbolInfo->getSymbolDataHeight(e));
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  placement->place();
  CBC_CommonByteMatrix* bytematrix = encodeLowLevel(placement, symbolInfo, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  outWidth = bytematrix->GetWidth();
  outHeight = bytematrix->GetHeight();
  uint8_t* result = FX_Alloc(uint8_t, outWidth * outHeight);
  FXSYS_memcpy(result, bytematrix->GetArray(), outWidth * outHeight);
  delete bytematrix;
  delete placement;
  return result;
}
uint8_t* CBC_DataMatrixWriter::Encode(const CFX_ByteString& contents,
                                      BCFORMAT format,
                                      int32_t& outWidth,
                                      int32_t& outHeight,
                                      int32_t& e) {
  return NULL;
}
uint8_t* CBC_DataMatrixWriter::Encode(const CFX_ByteString& contents,
                                      BCFORMAT format,
                                      int32_t& outWidth,
                                      int32_t& outHeight,
                                      int32_t hints,
                                      int32_t& e) {
  return NULL;
}
CBC_CommonByteMatrix* CBC_DataMatrixWriter::encodeLowLevel(
    CBC_DefaultPlacement* placement,
    CBC_SymbolInfo* symbolInfo,
    int32_t& e) {
  int32_t symbolWidth = symbolInfo->getSymbolDataWidth(e);
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  int32_t symbolHeight = symbolInfo->getSymbolDataHeight(e);
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  CBC_CommonByteMatrix* matrix = new CBC_CommonByteMatrix(
      symbolInfo->getSymbolWidth(e), symbolInfo->getSymbolHeight(e));
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  matrix->Init();
  int32_t matrixY = 0;
  for (int32_t y = 0; y < symbolHeight; y++) {
    int32_t matrixX;
    if ((y % symbolInfo->m_matrixHeight) == 0) {
      matrixX = 0;
      for (int32_t x = 0; x < symbolInfo->getSymbolWidth(e); x++) {
        matrix->Set(matrixX, matrixY, (x % 2) == 0);
        matrixX++;
      }
      matrixY++;
    }
    matrixX = 0;
    for (int32_t x = 0; x < symbolWidth; x++) {
      if ((x % symbolInfo->m_matrixWidth) == 0) {
        matrix->Set(matrixX, matrixY, TRUE);
        matrixX++;
      }
      matrix->Set(matrixX, matrixY, placement->getBit(x, y));
      matrixX++;
      if ((x % symbolInfo->m_matrixWidth) == symbolInfo->m_matrixWidth - 1) {
        matrix->Set(matrixX, matrixY, (y % 2) == 0);
        matrixX++;
      }
    }
    matrixY++;
    if ((y % symbolInfo->m_matrixHeight) == symbolInfo->m_matrixHeight - 1) {
      matrixX = 0;
      for (int32_t x = 0; x < symbolInfo->getSymbolWidth(e); x++) {
        matrix->Set(matrixX, matrixY, TRUE);
        matrixX++;
      }
      matrixY++;
    }
  }
  return matrix;
}
