// 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 "xfa/src/fxbarcode/BC_Dimension.h"
#include "xfa/src/fxbarcode/barcode.h"
#include "xfa/src/fxbarcode/common/BC_CommonBitMatrix.h"
#include "xfa/src/fxbarcode/datamatrix/BC_EdifactEncoder.h"
#include "xfa/src/fxbarcode/datamatrix/BC_Encoder.h"
#include "xfa/src/fxbarcode/datamatrix/BC_EncoderContext.h"
#include "xfa/src/fxbarcode/datamatrix/BC_HighLevelEncoder.h"
#include "xfa/src/fxbarcode/datamatrix/BC_SymbolInfo.h"
#include "xfa/src/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()) {
    FX_WCHAR 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 += (FX_WCHAR)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;
  }
  FX_BOOL endOfSymbolReached = !context.hasMoreCharacters();
  FX_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(FX_WCHAR c,
                                    CFX_WideString& sb,
                                    int32_t& e) {
  if (c >= ' ' && c <= '?') {
    sb += c;
  } else if (c >= '@' && c <= '^') {
    sb += (FX_WCHAR)(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 (FX_WCHAR*)"";
  }
  FX_WCHAR c1 = sb.GetAt(startPos);
  FX_WCHAR c2 = len >= 2 ? sb.GetAt(startPos + 1) : 0;
  FX_WCHAR c3 = len >= 3 ? sb.GetAt(startPos + 2) : 0;
  FX_WCHAR c4 = len >= 4 ? sb.GetAt(startPos + 3) : 0;
  int32_t v = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4;
  FX_WCHAR cw1 = (FX_WCHAR)((v >> 16) & 255);
  FX_WCHAR cw2 = (FX_WCHAR)((v >> 8) & 255);
  FX_WCHAR cw3 = (FX_WCHAR)(v & 255);
  CFX_WideString res;
  res += cw1;
  if (len >= 2) {
    res += cw2;
  }
  if (len >= 3) {
    res += cw3;
  }
  return res;
}
