// 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_EdifactEncoder.h"

#include "fxbarcode/BC_Dimension.h"
#include "fxbarcode/common/BC_CommonBitMatrix.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 "fxbarcode/datamatrix/BC_SymbolShapeHint.h"

CBC_EdifactEncoder::CBC_EdifactEncoder() {}
CBC_EdifactEncoder::~CBC_EdifactEncoder() {}
int32_t CBC_EdifactEncoder::getEncodingMode() {
  return EDIFACT_ENCODATION;
}
void CBC_EdifactEncoder::Encode(CBC_EncoderContext& context, int32_t& e) {
  CFX_WideString buffer;
  while (context.hasMoreCharacters()) {
    wchar_t c = context.getCurrentChar();
    encodeChar(c, buffer, e);
    if (e != BCExceptionNO) {
      return;
    }
    context.m_pos++;
    int32_t count = buffer.GetLength();
    if (count >= 4) {
      context.writeCodewords(encodeToCodewords(buffer, 0, e));
      if (e != BCExceptionNO) {
        return;
      }
      buffer.Delete(0, 4);
      int32_t newMode = CBC_HighLevelEncoder::lookAheadTest(
          context.m_msg, context.m_pos, getEncodingMode());
      if (newMode != getEncodingMode()) {
        context.signalEncoderChange(ASCII_ENCODATION);
        break;
      }
    }
  }
  buffer += (wchar_t)31;
  handleEOD(context, buffer, e);
}
void CBC_EdifactEncoder::handleEOD(CBC_EncoderContext& context,
                                   CFX_WideString buffer,
                                   int32_t& e) {
  int32_t count = buffer.GetLength();
  if (count == 0) {
    return;
  }
  if (count == 1) {
    context.updateSymbolInfo(e);
    if (e != BCExceptionNO) {
      return;
    }
    int32_t available =
        context.m_symbolInfo->m_dataCapacity - context.getCodewordCount();
    int32_t remaining = context.getRemainingCharacters();
    if (remaining == 0 && available <= 2) {
      return;
    }
  }
  if (count > 4) {
    e = BCExceptionIllegalStateCountMustNotExceed4;
    return;
  }
  int32_t restChars = count - 1;
  CFX_WideString encoded = encodeToCodewords(buffer, 0, e);
  if (e != BCExceptionNO) {
    return;
  }
  bool endOfSymbolReached = !context.hasMoreCharacters();
  bool restInAscii = endOfSymbolReached && restChars <= 2;
  if (restChars <= 2) {
    context.updateSymbolInfo(context.getCodewordCount() + restChars, e);
    if (e != BCExceptionNO) {
      return;
    }
    int32_t available =
        context.m_symbolInfo->m_dataCapacity - context.getCodewordCount();
    if (available >= 3) {
      restInAscii = false;
      context.updateSymbolInfo(context.getCodewordCount() + encoded.GetLength(),
                               e);
      if (e != BCExceptionNO) {
        return;
      }
    }
  }
  if (restInAscii) {
    context.resetSymbolInfo();
    context.m_pos -= restChars;
  } else {
    context.writeCodewords(encoded);
  }
  context.signalEncoderChange(ASCII_ENCODATION);
}

void CBC_EdifactEncoder::encodeChar(wchar_t c, CFX_WideString& sb, int32_t& e) {
  if (c >= ' ' && c <= '?') {
    sb += c;
  } else if (c >= '@' && c <= '^') {
    sb += (wchar_t)(c - 64);
  } else {
    e = BCExceptionIllegalArgument;
  }
}

CFX_WideString CBC_EdifactEncoder::encodeToCodewords(CFX_WideString sb,
                                                     int32_t startPos,
                                                     int32_t& e) {
  int32_t len = sb.GetLength() - startPos;
  if (len == 0) {
    e = BCExceptionNoContents;
    return CFX_WideString();
  }
  wchar_t c1 = sb.GetAt(startPos);
  wchar_t c2 = len >= 2 ? sb.GetAt(startPos + 1) : 0;
  wchar_t c3 = len >= 3 ? sb.GetAt(startPos + 2) : 0;
  wchar_t c4 = len >= 4 ? sb.GetAt(startPos + 3) : 0;
  int32_t v = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4;
  wchar_t cw1 = (wchar_t)((v >> 16) & 255);
  wchar_t cw2 = (wchar_t)((v >> 8) & 255);
  wchar_t cw3 = (wchar_t)(v & 255);
  CFX_WideString res;
  res += cw1;
  if (len >= 2) {
    res += cw2;
  }
  if (len >= 3) {
    res += cw3;
  }
  return res;
}
