// 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

#ifndef XFA_SRC_FXBARCODE_QRCODE_BC_QRCODERENCODER_H_
#define XFA_SRC_FXBARCODE_QRCODE_BC_QRCODERENCODER_H_

#include "core/include/fxcrt/fx_basic.h"
#include "core/include/fxcrt/fx_string.h"

class CBC_QRCoder;
class CBC_QRCoderErrorCorrectionLevel;
class CBC_QRCoderMode;
class CBC_QRCoderBitVector;
class CBC_CommonByteArray;
class CBC_CommonByteMatrix;

class CBC_QRCoderEncoder {
 private:
  const static int32_t m_alphaNumbericTable[96];

 public:
  CBC_QRCoderEncoder();
  virtual ~CBC_QRCoderEncoder();

  static void Encode(const CFX_ByteString& content,
                     CBC_QRCoderErrorCorrectionLevel* ecLevel,
                     CBC_QRCoder* qrCode,
                     int32_t& e,
                     int32_t versionSpecify = 0);
  static void Encode(const CFX_WideString& content,
                     CBC_QRCoderErrorCorrectionLevel* ecLevel,
                     CBC_QRCoder* qrCode,
                     int32_t& e);
  static void EncodeWithSpecifyVersion(const CFX_ByteString& content,
                                       CBC_QRCoderErrorCorrectionLevel* ecLevel,
                                       CBC_QRCoder* qrCode,
                                       int32_t versionSpecify,
                                       int32_t& e);
  static void EncodeWithAutoVersion(const CFX_ByteString& content,
                                    CBC_QRCoderErrorCorrectionLevel* ecLevel,
                                    CBC_QRCoder* qrCode,
                                    int32_t& e);
  static CBC_QRCoderMode* ChooseMode(const CFX_ByteString& content,
                                     CFX_ByteString encoding);
  static int32_t GetAlphaNumericCode(int32_t code);
  static void AppendECI(CBC_QRCoderBitVector* bits);
  static void AppendBytes(const CFX_ByteString& content,
                          CBC_QRCoderMode* mode,
                          CBC_QRCoderBitVector* bits,
                          CFX_ByteString encoding,
                          int32_t& e);
  static void AppendNumericBytes(const CFX_ByteString& content,
                                 CBC_QRCoderBitVector* bits,
                                 int32_t& e);
  static void AppendAlphaNumericBytes(const CFX_ByteString& content,
                                      CBC_QRCoderBitVector* bits,
                                      int32_t& e);
  static void Append8BitBytes(const CFX_ByteString& content,
                              CBC_QRCoderBitVector* bits,
                              CFX_ByteString encoding,
                              int32_t& e);
  static void Append8BitBytes(CFX_ByteArray& bytes,
                              CBC_QRCoderBitVector* bits,
                              int32_t& e);
  static void AppendKanjiBytes(const CFX_ByteString& content,
                               CBC_QRCoderBitVector* bits,
                               int32_t& e);
  static void AppendGBKBytes(const CFX_ByteString& content,
                             CBC_QRCoderBitVector* bits,
                             int32_t& e);
  static void InitQRCode(int32_t numInputBytes,
                         int32_t versionNumber,
                         CBC_QRCoderErrorCorrectionLevel* ecLevel,
                         CBC_QRCoderMode* mode,
                         CBC_QRCoder* qrCode,
                         int32_t& e);
  static void InitQRCode(int32_t numInputBytes,
                         CBC_QRCoderErrorCorrectionLevel* ecLevel,
                         CBC_QRCoderMode* mode,
                         CBC_QRCoder* qrCode,
                         int32_t& e);
  static void AppendModeInfo(CBC_QRCoderMode* mode,
                             CBC_QRCoderBitVector* bits,
                             int32_t& e);
  static void AppendLengthInfo(int32_t numLetters,
                               int32_t version,
                               CBC_QRCoderMode* mode,
                               CBC_QRCoderBitVector* bits,
                               int32_t& e);

  static void InterleaveWithECBytes(CBC_QRCoderBitVector* bits,
                                    int32_t numTotalBytes,
                                    int32_t numDataBytes,
                                    int32_t numRSBlocks,
                                    CBC_QRCoderBitVector* result,
                                    int32_t& e);
  static void GetNumDataBytesAndNumECBytesForBlockID(
      int32_t numTotalBytes,
      int32_t numDataBytes,
      int32_t numRSBlocks,
      int32_t blockID,
      int32_t& numDataBytesInBlock,
      int32_t& numECBytesInBlocks);
  static CBC_CommonByteArray* GenerateECBytes(CBC_CommonByteArray* dataBytes,
                                              int32_t numEcBytesInBlock,
                                              int32_t& e);
  static int32_t ChooseMaskPattern(CBC_QRCoderBitVector* bits,
                                   CBC_QRCoderErrorCorrectionLevel* ecLevel,
                                   int32_t version,
                                   CBC_CommonByteMatrix* matrix,
                                   int32_t& e);
  static int32_t CalculateMaskPenalty(CBC_CommonByteMatrix* matrix);
  static void TerminateBits(int32_t numDataBytes,
                            CBC_QRCoderBitVector* bits,
                            int32_t& e);
  static int32_t GetSpanByVersion(CBC_QRCoderMode* modeFirst,
                                  CBC_QRCoderMode* modeSecond,
                                  int32_t versionNum,
                                  int32_t& e);
  static void MergeString(CFX_PtrArray& result, int32_t versionNum, int32_t& e);
  static void SplitString(const CFX_ByteString& content, CFX_PtrArray& result);
  static void AppendDataModeLenghInfo(CFX_PtrArray& splitResult,
                                      CBC_QRCoderBitVector& headerAndDataBits,
                                      CBC_QRCoderMode* tempMode,
                                      CBC_QRCoder* qrCode,
                                      CFX_ByteString& encoding,
                                      int32_t& e);
};

#endif  // XFA_SRC_FXBARCODE_QRCODE_BC_QRCODERENCODER_H_
