// 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 2006-2007 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_ASCIIEncoder.h"

#include "core/fxcrt/fx_extension.h"
#include "fxbarcode/datamatrix/BC_Encoder.h"
#include "fxbarcode/datamatrix/BC_EncoderContext.h"
#include "fxbarcode/datamatrix/BC_HighLevelEncoder.h"
#include "fxbarcode/datamatrix/BC_SymbolInfo.h"
#include "third_party/base/optional.h"

namespace {

Optional<wchar_t> EncodeASCIIDigits(wchar_t digit1, wchar_t digit2) {
  if (!FXSYS_IsDecimalDigit(digit1) || !FXSYS_IsDecimalDigit(digit2)) {
    // This could potentially return 0 as a sentinel value. Then this function
    // can just return wchar_t instead of Optional<wchar_t>.
    return {};
  }
  return static_cast<wchar_t>((digit1 - 48) * 10 + (digit2 - 48) + 130);
}

int32_t DetermineConsecutiveDigitCount(WideString msg, int32_t startpos) {
  int32_t count = 0;
  int32_t len = pdfium::base::checked_cast<int32_t>(msg.GetLength());
  int32_t idx = startpos;
  if (idx < len) {
    wchar_t ch = msg[idx];
    while (FXSYS_IsDecimalDigit(ch) && idx < len) {
      count++;
      idx++;
      if (idx < len) {
        ch = msg[idx];
      }
    }
  }
  return count;
}

}  // namespace

CBC_ASCIIEncoder::CBC_ASCIIEncoder() = default;

CBC_ASCIIEncoder::~CBC_ASCIIEncoder() = default;

int32_t CBC_ASCIIEncoder::getEncodingMode() {
  return ASCII_ENCODATION;
}

bool CBC_ASCIIEncoder::Encode(CBC_EncoderContext* context) {
  int32_t n = DetermineConsecutiveDigitCount(context->m_msg, context->m_pos);
  if (n >= 2) {
    Optional<wchar_t> code = EncodeASCIIDigits(
        context->m_msg[context->m_pos], context->m_msg[context->m_pos + 1]);
    if (!code)
      return false;

    context->writeCodeword(*code);
    context->m_pos += 2;
    return true;
  }

  wchar_t c = context->getCurrentChar();
  int32_t newMode = CBC_HighLevelEncoder::LookAheadTest(
      context->m_msg, context->m_pos, getEncodingMode());
  if (newMode != getEncodingMode()) {
    switch (newMode) {
      case BASE256_ENCODATION:
        context->writeCodeword(CBC_HighLevelEncoder::LATCH_TO_BASE256);
        context->signalEncoderChange(BASE256_ENCODATION);
        return true;
      case C40_ENCODATION:
        context->writeCodeword(CBC_HighLevelEncoder::LATCH_TO_C40);
        context->signalEncoderChange(C40_ENCODATION);
        return true;
      case X12_ENCODATION:
        context->writeCodeword(CBC_HighLevelEncoder::LATCH_TO_ANSIX12);
        context->signalEncoderChange(X12_ENCODATION);
        return true;
      case TEXT_ENCODATION:
        context->writeCodeword(CBC_HighLevelEncoder::LATCH_TO_TEXT);
        context->signalEncoderChange(TEXT_ENCODATION);
        return true;
      case EDIFACT_ENCODATION:
        context->writeCodeword(CBC_HighLevelEncoder::LATCH_TO_EDIFACT);
        context->signalEncoderChange(EDIFACT_ENCODATION);
        return true;
      default:
        return false;
    }
  }

  if (CBC_HighLevelEncoder::IsExtendedASCII(c)) {
    context->writeCodeword(CBC_HighLevelEncoder::UPPER_SHIFT);
    context->writeCodeword(static_cast<wchar_t>(c - 128 + 1));
  } else {
    context->writeCodeword(static_cast<wchar_t>(c + 1));
  }
  context->m_pos++;
  return true;
}
