// 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/BC_Dimension.h"
#include "fxbarcode/common/BC_CommonBitMatrix.h"
#include "fxbarcode/datamatrix/BC_EdifactEncoder.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 {
    CBC_HighLevelEncoder::illegalCharacter(c, e);
  }
}
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;
}
