// 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 2010 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/BC_Reader.h"
#include "xfa/fxbarcode/BC_Writer.h"
#include "xfa/fxbarcode/oned/BC_OneDReader.h"
#include "xfa/fxbarcode/oned/BC_OneDimWriter.h"
#include "xfa/fxbarcode/oned/BC_OnedCode128Reader.h"
#include "xfa/fxbarcode/oned/BC_OnedCode128Writer.h"

CBC_OnedCode128Writer::CBC_OnedCode128Writer() {
  m_codeFormat = BC_CODE128_B;
}
CBC_OnedCode128Writer::CBC_OnedCode128Writer(BC_TYPE type) {
  m_codeFormat = type;
}
CBC_OnedCode128Writer::~CBC_OnedCode128Writer() {}
BC_TYPE CBC_OnedCode128Writer::GetType() {
  return m_codeFormat;
}
FX_BOOL CBC_OnedCode128Writer::CheckContentValidity(
    const CFX_WideStringC& contents) {
  FX_BOOL ret = TRUE;
  int32_t position = 0;
  int32_t patternIndex = -1;
  if (m_codeFormat == BC_CODE128_B || m_codeFormat == BC_CODE128_C) {
    while (position < contents.GetLength()) {
      patternIndex = (int32_t)contents.GetAt(position);
      if (patternIndex >= 32 && patternIndex <= 126 && patternIndex != 34) {
        position++;
        continue;
      } else {
        ret = FALSE;
        break;
      }
      position++;
    }
  } else {
    ret = FALSE;
  }
  return ret;
}
CFX_WideString CBC_OnedCode128Writer::FilterContents(
    const CFX_WideStringC& contents) {
  CFX_WideString filterChineseChar;
  FX_WCHAR ch;
  for (int32_t i = 0; i < contents.GetLength(); i++) {
    ch = contents.GetAt(i);
    if (ch > 175) {
      i++;
      continue;
    }
    filterChineseChar += ch;
  }
  CFX_WideString filtercontents;
  if (m_codeFormat == BC_CODE128_B) {
    for (int32_t i = 0; i < filterChineseChar.GetLength(); i++) {
      ch = filterChineseChar.GetAt(i);
      if (ch >= 32 && ch <= 126) {
        filtercontents += ch;
      } else {
        continue;
      }
    }
  } else if (m_codeFormat == BC_CODE128_C) {
    for (int32_t i = 0; i < filterChineseChar.GetLength(); i++) {
      ch = filterChineseChar.GetAt(i);
      if (ch >= 32 && ch <= 106) {
        filtercontents += ch;
      } else {
        continue;
      }
    }
  } else {
    filtercontents = contents;
  }
  return filtercontents;
}
FX_BOOL CBC_OnedCode128Writer::SetTextLocation(BC_TEXT_LOC location) {
  if (location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) {
    return FALSE;
  }
  m_locTextLoc = location;
  return TRUE;
}
uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents,
                                       BCFORMAT format,
                                       int32_t& outWidth,
                                       int32_t& outHeight,
                                       int32_t hints,
                                       int32_t& e) {
  if (format != BCFORMAT_CODE_128) {
    e = BCExceptionOnlyEncodeCODE_128;
    return NULL;
  }
  uint8_t* ret =
      CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  return ret;
}
uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents,
                                       BCFORMAT format,
                                       int32_t& outWidth,
                                       int32_t& outHeight,
                                       int32_t& e) {
  uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  return ret;
}
FX_BOOL CBC_OnedCode128Writer::IsDigits(const CFX_ByteString& contents,
                                        int32_t start,
                                        int32_t length) {
  int32_t end = start + length;
  for (int32_t i = start; i < end; i++) {
    if (contents[i] < '0' || contents[i] > '9') {
      return FALSE;
    }
  }
  return TRUE;
}
uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents,
                                       int32_t& outLength,
                                       int32_t& e) {
  if (contents.GetLength() < 1 || contents.GetLength() > 80) {
    e = BCExceptionContentsLengthShouldBetween1and80;
    return NULL;
  }
  CFX_PtrArray patterns;
  int32_t checkSum = 0;
  if (m_codeFormat == BC_CODE128_B) {
    checkSum = Encode128B(contents, patterns);
  } else if (m_codeFormat == BC_CODE128_C) {
    checkSum = Encode128C(contents, patterns);
  } else {
    e = BCExceptionFormatException;
    return NULL;
  }
  checkSum %= 103;
  patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[checkSum]);
  patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_STOP]);
  m_iContentLen = contents.GetLength() + 3;
  int32_t codeWidth = 0;
  for (int32_t k = 0; k < patterns.GetSize(); k++) {
    int32_t* pattern = (int32_t*)patterns[k];
    for (int32_t j = 0; j < 7; j++) {
      codeWidth += pattern[j];
    }
  }
  outLength = codeWidth;
  uint8_t* result = FX_Alloc(uint8_t, outLength);
  int32_t pos = 0;
  for (int32_t j = 0; j < patterns.GetSize(); j++) {
    int32_t* pattern = (int32_t*)patterns[j];
    pos += AppendPattern(result, pos, pattern, 7, 1, e);
    if (e != BCExceptionNO) {
      FX_Free(result);
      return NULL;
    }
  }
  return result;
}
int32_t CBC_OnedCode128Writer::Encode128B(const CFX_ByteString& contents,
                                          CFX_PtrArray& patterns) {
  int32_t checkSum = 0;
  int32_t checkWeight = 1;
  int32_t position = 0;
  patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_START_B]);
  checkSum += CODE_START_B * checkWeight;
  while (position < contents.GetLength()) {
    int32_t patternIndex = 0;
    patternIndex = contents[position] - ' ';
    position += 1;
    patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[patternIndex]);
    checkSum += patternIndex * checkWeight;
    if (position != 0) {
      checkWeight++;
    }
  }
  return checkSum;
}
int32_t CBC_OnedCode128Writer::Encode128C(const CFX_ByteString& contents,
                                          CFX_PtrArray& patterns) {
  int32_t checkSum = 0;
  int32_t checkWeight = 1;
  int32_t position = 0;
  patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_START_C]);
  checkSum += CODE_START_C * checkWeight;
  while (position < contents.GetLength()) {
    int32_t patternIndex = 0;
    FX_CHAR ch = contents.GetAt(position);
    if (ch < '0' || ch > '9') {
      patternIndex = (int32_t)ch;
      position++;
    } else {
      patternIndex = FXSYS_atoi(contents.Mid(position, 2));
      if (contents.GetAt(position + 1) < '0' ||
          contents.GetAt(position + 1) > '9') {
        position += 1;
      } else {
        position += 2;
      }
    }
    patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[patternIndex]);
    checkSum += patternIndex * checkWeight;
    if (position != 0) {
      checkWeight++;
    }
  }
  return checkSum;
}
