// Copyright 2014 The PDFium Authors
// 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_C40Encoder.h"

#include <iterator>

#include "core/fxcrt/check.h"
#include "core/fxcrt/compiler_specific.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"

namespace {

WideString EncodeToC40Codewords(const WideString& sb) {
  wchar_t c1 = sb[0];
  wchar_t c2 = sb[1];
  wchar_t c3 = sb[2];
  int32_t v = (1600 * c1) + (40 * c2) + c3 + 1;
  wchar_t cw[2];
  cw[0] = static_cast<wchar_t>(v / 256);
  cw[1] = static_cast<wchar_t>(v % 256);
  return WideString(WideStringView(pdfium::span(cw)));
}

}  // namespace

CBC_C40Encoder::CBC_C40Encoder() = default;

CBC_C40Encoder::~CBC_C40Encoder() = default;

CBC_HighLevelEncoder::Encoding CBC_C40Encoder::GetEncodingMode() {
  return CBC_HighLevelEncoder::Encoding::C40;
}

bool CBC_C40Encoder::Encode(CBC_EncoderContext* context) {
  WideString buffer;
  while (context->hasMoreCharacters()) {
    wchar_t c = context->getCurrentChar();
    context->pos_++;
    int32_t lastCharSize = EncodeChar(c, &buffer);
    if (lastCharSize <= 0) {
      return false;
    }

    size_t unwritten = (buffer.GetLength() / 3) * 2;
    int32_t curCodewordCount = context->getCodewordCount() + unwritten;
    if (!context->UpdateSymbolInfo(curCodewordCount)) {
      return false;
    }

    int32_t available =
        context->symbol_info_->data_capacity() - curCodewordCount;
    if (!context->hasMoreCharacters()) {
      if ((buffer.GetLength() % 3) == 2) {
        if (available < 2 || available > 2) {
          lastCharSize = BacktrackOneCharacter(context, &buffer, lastCharSize);
          if (lastCharSize < 0) {
            return false;
          }
        }
      }
      while ((buffer.GetLength() % 3) == 1 &&
             ((lastCharSize <= 3 && available != 1) || lastCharSize > 3)) {
        lastCharSize = BacktrackOneCharacter(context, &buffer, lastCharSize);
        if (lastCharSize < 0) {
          return false;
        }
      }
      break;
    }
    size_t count = buffer.GetLength();
    if ((count % 3) == 0) {
      CBC_HighLevelEncoder::Encoding newMode =
          CBC_HighLevelEncoder::LookAheadTest(context->msg_, context->pos_,
                                              GetEncodingMode());
      if (newMode != GetEncodingMode()) {
        context->SignalEncoderChange(newMode);
        break;
      }
    }
  }
  return HandleEOD(context, &buffer);
}

void CBC_C40Encoder::WriteNextTriplet(CBC_EncoderContext* context,
                                      WideString* buffer) {
  context->writeCodewords(EncodeToC40Codewords(*buffer));
  buffer->Delete(0, 3);
}

bool CBC_C40Encoder::HandleEOD(CBC_EncoderContext* context,
                               WideString* buffer) {
  size_t unwritten = (buffer->GetLength() / 3) * 2;
  size_t rest = buffer->GetLength() % 3;
  int32_t curCodewordCount = context->getCodewordCount() + unwritten;
  if (!context->UpdateSymbolInfo(curCodewordCount)) {
    return false;
  }

  int32_t available = context->symbol_info_->data_capacity() - curCodewordCount;
  if (rest == 2) {
    *buffer += (wchar_t)'\0';
    while (buffer->GetLength() >= 3) {
      WriteNextTriplet(context, buffer);
    }
    if (context->hasMoreCharacters()) {
      context->writeCodeword(CBC_HighLevelEncoder::C40_UNLATCH);
    }
  } else if (available == 1 && rest == 1) {
    while (buffer->GetLength() >= 3) {
      WriteNextTriplet(context, buffer);
    }
    if (context->hasMoreCharacters()) {
      context->writeCodeword(CBC_HighLevelEncoder::C40_UNLATCH);
    }
    context->pos_--;
  } else if (rest == 0) {
    while (buffer->GetLength() >= 3) {
      WriteNextTriplet(context, buffer);
    }
    if (available > 0 || context->hasMoreCharacters()) {
      context->writeCodeword(CBC_HighLevelEncoder::C40_UNLATCH);
    }
  } else {
    return false;
  }
  context->SignalEncoderChange(CBC_HighLevelEncoder::Encoding::ASCII);
  return true;
}

int32_t CBC_C40Encoder::EncodeChar(wchar_t c, WideString* sb) {
  if (c == ' ') {
    *sb += (wchar_t)'\3';
    return 1;
  }
  if (FXSYS_IsDecimalDigit(c)) {
    *sb += (wchar_t)(c - 48 + 4);
    return 1;
  }
  if (FXSYS_IsUpperASCII(c)) {
    *sb += (wchar_t)(c - 65 + 14);
    return 1;
  }
  if (c <= 0x1f) {
    *sb += (wchar_t)'\0';
    *sb += c;
    return 2;
  }
  if ((c >= '!') && (c <= '/')) {
    *sb += (wchar_t)'\1';
    *sb += (wchar_t)(c - 33);
    return 2;
  }
  if ((c >= ':') && (c <= '@')) {
    *sb += (wchar_t)'\1';
    *sb += (wchar_t)(c - 58 + 15);
    return 2;
  }
  if ((c >= '[') && (c <= '_')) {
    *sb += (wchar_t)'\1';
    *sb += (wchar_t)(c - 91 + 22);
    return 2;
  }
  if ((c >= 60) && (c <= 0x7f)) {
    *sb += (wchar_t)'\2';
    *sb += (wchar_t)(c - 96);
    return 2;
  }
  if (c >= 80) {
    *sb += (wchar_t)'\1';
    *sb += (wchar_t)0x001e;
    int32_t encode_result = EncodeChar(c - 128, sb);
    return encode_result > 0 ? encode_result + 2 : 0;
  }
  return 0;
}

int32_t CBC_C40Encoder::BacktrackOneCharacter(CBC_EncoderContext* context,
                                              WideString* buffer,
                                              int32_t lastCharSize) {
  DCHECK(lastCharSize >= 0);

  if (context->pos_ < 1) {
    return -1;
  }

  size_t count = buffer->GetLength();
  if (count < static_cast<size_t>(lastCharSize)) {
    return -1;
  }

  buffer->Delete(count - lastCharSize, lastCharSize);
  context->pos_--;
  wchar_t c = context->getCurrentChar();
  WideString removed;
  int32_t len = EncodeChar(c, &removed);
  if (len <= 0) {
    return -1;
  }

  context->resetSymbolInfo();
  return len;
}
