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

#include "xfa/fxfa/cxfa_ffbarcode.h"

#include <utility>

#include "core/fxcrt/fx_extension.h"
#include "third_party/base/ptr_util.h"
#include "xfa/fwl/cfwl_app.h"
#include "xfa/fwl/cfwl_barcode.h"
#include "xfa/fwl/cfwl_notedriver.h"
#include "xfa/fxfa/cxfa_fffield.h"
#include "xfa/fxfa/cxfa_ffpageview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"

namespace {

const BarCodeInfo g_BarCodeData[] = {
    {0x7fb4a18, L"ean13", BarcodeType::ean13, BC_EAN13},
    {0x8d13a3d, L"code11", BarcodeType::code11, BC_UNKNOWN},
    {0x8d149a8, L"code49", BarcodeType::code49, BC_UNKNOWN},
    {0x8d16347, L"code93", BarcodeType::code93, BC_UNKNOWN},
    {0x91a92e2, L"upsMaxicode", BarcodeType::upsMaxicode, BC_UNKNOWN},
    {0xa7d48dc, L"fim", BarcodeType::fim, BC_UNKNOWN},
    {0xb359fe9, L"msi", BarcodeType::msi, BC_UNKNOWN},
    {0x121f738c, L"code2Of5Matrix", BarcodeType::code2Of5Matrix, BC_UNKNOWN},
    {0x15358616, L"ucc128", BarcodeType::ucc128, BC_UNKNOWN},
    {0x1f4bfa05, L"rfid", BarcodeType::rfid, BC_UNKNOWN},
    {0x1fda71bc, L"rss14Stacked", BarcodeType::rss14Stacked, BC_UNKNOWN},
    {0x22065087, L"ean8add2", BarcodeType::ean8add2, BC_UNKNOWN},
    {0x2206508a, L"ean8add5", BarcodeType::ean8add5, BC_UNKNOWN},
    {0x2278366c, L"codabar", BarcodeType::codabar, BC_CODABAR},
    {0x2a039a8d, L"telepen", BarcodeType::telepen, BC_UNKNOWN},
    {0x323ed337, L"upcApwcd", BarcodeType::upcApwcd, BC_UNKNOWN},
    {0x347a1846, L"postUSIMB", BarcodeType::postUSIMB, BC_UNKNOWN},
    {0x391bb836, L"code128", BarcodeType::code128, BC_CODE128},
    {0x398eddaf, L"dataMatrix", BarcodeType::dataMatrix, BC_DATAMATRIX},
    {0x3cff60a8, L"upcEadd2", BarcodeType::upcEadd2, BC_UNKNOWN},
    {0x3cff60ab, L"upcEadd5", BarcodeType::upcEadd5, BC_UNKNOWN},
    {0x402cb188, L"code2Of5Standard", BarcodeType::code2Of5Standard,
     BC_UNKNOWN},
    {0x411764f7, L"aztec", BarcodeType::aztec, BC_UNKNOWN},
    {0x44d4e84c, L"ean8", BarcodeType::ean8, BC_EAN8},
    {0x48468902, L"ucc128sscc", BarcodeType::ucc128sscc, BC_UNKNOWN},
    {0x4880aea4, L"upcAadd2", BarcodeType::upcAadd2, BC_UNKNOWN},
    {0x4880aea7, L"upcAadd5", BarcodeType::upcAadd5, BC_UNKNOWN},
    {0x54f18256, L"code2Of5Industrial", BarcodeType::code2Of5Industrial,
     BC_UNKNOWN},
    {0x58e15f25, L"rss14Limited", BarcodeType::rss14Limited, BC_UNKNOWN},
    {0x5c08d1b9, L"postAUSReplyPaid", BarcodeType::postAUSReplyPaid,
     BC_UNKNOWN},
    {0x5fa700bd, L"rss14", BarcodeType::rss14, BC_UNKNOWN},
    {0x631a7e35, L"logmars", BarcodeType::logmars, BC_UNKNOWN},
    {0x6a236236, L"pdf417", BarcodeType::pdf417, BC_PDF417},
    {0x6d098ece, L"upcean2", BarcodeType::upcean2, BC_UNKNOWN},
    {0x6d098ed1, L"upcean5", BarcodeType::upcean5, BC_UNKNOWN},
    {0x76b04eed, L"code3Of9extended", BarcodeType::code3Of9extended,
     BC_UNKNOWN},
    {0x7c7db84a, L"maxicode", BarcodeType::maxicode, BC_UNKNOWN},
    {0x8266f7f7, L"ucc128random", BarcodeType::ucc128random, BC_UNKNOWN},
    {0x83eca147, L"postUSDPBC", BarcodeType::postUSDPBC, BC_UNKNOWN},
    {0x8dd71de0, L"postAUSStandard", BarcodeType::postAUSStandard, BC_UNKNOWN},
    {0x98adad85, L"plessey", BarcodeType::plessey, BC_UNKNOWN},
    {0x9f84cce6, L"ean13pwcd", BarcodeType::ean13pwcd, BC_UNKNOWN},
    {0xb514fbe9, L"upcA", BarcodeType::upcA, BC_UPCA},
    {0xb514fbed, L"upcE", BarcodeType::upcE, BC_UNKNOWN},
    {0xb5c6a853, L"ean13add2", BarcodeType::ean13add2, BC_UNKNOWN},
    {0xb5c6a856, L"ean13add5", BarcodeType::ean13add5, BC_UNKNOWN},
    {0xb81fc512, L"postUKRM4SCC", BarcodeType::postUKRM4SCC, BC_UNKNOWN},
    {0xbad34b22, L"code128SSCC", BarcodeType::code128SSCC, BC_UNKNOWN},
    {0xbfbe0cf6, L"postUS5Zip", BarcodeType::postUS5Zip, BC_UNKNOWN},
    {0xc56618e8, L"pdf417macro", BarcodeType::pdf417macro, BC_UNKNOWN},
    {0xca730f8a, L"code2Of5Interleaved", BarcodeType::code2Of5Interleaved,
     BC_UNKNOWN},
    {0xd0097ac6, L"rss14Expanded", BarcodeType::rss14Expanded, BC_UNKNOWN},
    {0xd25a0240, L"postAUSCust2", BarcodeType::postAUSCust2, BC_UNKNOWN},
    {0xd25a0241, L"postAUSCust3", BarcodeType::postAUSCust3, BC_UNKNOWN},
    {0xd53ed3e7, L"rss14Truncated", BarcodeType::rss14Truncated, BC_UNKNOWN},
    {0xe72bcd57, L"code128A", BarcodeType::code128A, BC_UNKNOWN},
    {0xe72bcd58, L"code128B", BarcodeType::code128B, BC_CODE128_B},
    {0xe72bcd59, L"code128C", BarcodeType::code128C, BC_CODE128_C},
    {0xee83c50f, L"rss14StackedOmni", BarcodeType::rss14StackedOmni,
     BC_UNKNOWN},
    {0xf2a18f7e, L"QRCode", BarcodeType::QRCode, BC_QR_CODE},
    {0xfaeaf37f, L"postUSStandard", BarcodeType::postUSStandard, BC_UNKNOWN},
    {0xfb48155c, L"code3Of9", BarcodeType::code3Of9, BC_CODE39},
};

}  // namespace.

// static
const BarCodeInfo* CXFA_FFBarcode::GetBarcodeTypeByName(
    const WideStringView& wsName) {
  if (wsName.IsEmpty())
    return nullptr;

  auto* it = std::lower_bound(
      std::begin(g_BarCodeData), std::end(g_BarCodeData),
      FX_HashCode_GetW(wsName, true),
      [](const BarCodeInfo& arg, uint32_t hash) { return arg.uHash < hash; });

  if (it != std::end(g_BarCodeData) && wsName == it->pName)
    return it;

  return nullptr;
}

CXFA_FFBarcode::CXFA_FFBarcode(CXFA_WidgetAcc* pDataAcc)
    : CXFA_FFTextEdit(pDataAcc) {}

CXFA_FFBarcode::~CXFA_FFBarcode() {}

bool CXFA_FFBarcode::LoadWidget() {
  auto pNew = pdfium::MakeUnique<CFWL_Barcode>(GetFWLApp());
  CFWL_Barcode* pFWLBarcode = pNew.get();
  m_pNormalWidget = std::move(pNew);
  m_pNormalWidget->SetLayoutItem(this);

  CFWL_NoteDriver* pNoteDriver =
      m_pNormalWidget->GetOwnerApp()->GetNoteDriver();
  pNoteDriver->RegisterEventTarget(m_pNormalWidget.get(),
                                   m_pNormalWidget.get());
  m_pOldDelegate = m_pNormalWidget->GetDelegate();
  m_pNormalWidget->SetDelegate(this);
  m_pNormalWidget->LockUpdate();

  pFWLBarcode->SetText(m_pDataAcc->GetValue(XFA_VALUEPICTURE_Display));
  UpdateWidgetProperty();
  m_pNormalWidget->UnlockUpdate();
  return CXFA_FFField::LoadWidget();
}

void CXFA_FFBarcode::RenderWidget(CXFA_Graphics* pGS,
                                  const CFX_Matrix& matrix,
                                  uint32_t dwStatus) {
  if (!IsMatchVisibleStatus(dwStatus))
    return;

  CFX_Matrix mtRotate = GetRotateMatrix();
  mtRotate.Concat(matrix);

  CXFA_FFWidget::RenderWidget(pGS, mtRotate, dwStatus);
  DrawBorder(pGS, m_pDataAcc->GetUIBorderData(), m_rtUI, mtRotate);
  RenderCaption(pGS, &mtRotate);
  CFX_RectF rtWidget = m_pNormalWidget->GetWidgetRect();

  CFX_Matrix mt(1, 0, 0, 1, rtWidget.left, rtWidget.top);
  mt.Concat(mtRotate);
  m_pNormalWidget->DrawWidget(pGS, mt);
}

void CXFA_FFBarcode::UpdateWidgetProperty() {
  CXFA_FFTextEdit::UpdateWidgetProperty();

  auto* pBarCodeWidget = static_cast<CFWL_Barcode*>(m_pNormalWidget.get());
  WideString wsType = GetDataAcc()->GetBarcodeType();
  const BarCodeInfo* pBarcodeInfo = GetBarcodeTypeByName(wsType.AsStringView());
  if (!pBarcodeInfo)
    return;

  pBarCodeWidget->SetType(pBarcodeInfo->eBCType);

  CXFA_WidgetAcc* pAcc = GetDataAcc();
  pdfium::Optional<BC_CHAR_ENCODING> encoding =
      pAcc->GetBarcodeAttribute_CharEncoding();
  if (encoding)
    pBarCodeWidget->SetCharEncoding(*encoding);

  pdfium::Optional<bool> calcChecksum = pAcc->GetBarcodeAttribute_Checksum();
  if (calcChecksum)
    pBarCodeWidget->SetCalChecksum(*calcChecksum);

  pdfium::Optional<int32_t> dataLen = pAcc->GetBarcodeAttribute_DataLength();
  if (dataLen)
    pBarCodeWidget->SetDataLength(*dataLen);

  pdfium::Optional<char> startChar = pAcc->GetBarcodeAttribute_StartChar();
  if (startChar)
    pBarCodeWidget->SetStartChar(*startChar);

  pdfium::Optional<char> endChar = pAcc->GetBarcodeAttribute_EndChar();
  if (endChar)
    pBarCodeWidget->SetEndChar(*endChar);

  pdfium::Optional<int32_t> ecLevel = pAcc->GetBarcodeAttribute_ECLevel();
  if (ecLevel)
    pBarCodeWidget->SetErrorCorrectionLevel(*ecLevel);

  pdfium::Optional<int32_t> width = pAcc->GetBarcodeAttribute_ModuleWidth();
  if (width)
    pBarCodeWidget->SetModuleWidth(*width);

  pdfium::Optional<int32_t> height = pAcc->GetBarcodeAttribute_ModuleHeight();
  if (height)
    pBarCodeWidget->SetModuleHeight(*height);

  pdfium::Optional<bool> printCheck = pAcc->GetBarcodeAttribute_PrintChecksum();
  if (printCheck)
    pBarCodeWidget->SetPrintChecksum(*printCheck);

  pdfium::Optional<BC_TEXT_LOC> textLoc =
      pAcc->GetBarcodeAttribute_TextLocation();
  if (textLoc)
    pBarCodeWidget->SetTextLocation(*textLoc);

  pdfium::Optional<bool> truncate = pAcc->GetBarcodeAttribute_Truncate();
  if (truncate)
    pBarCodeWidget->SetTruncated(*truncate);

  pdfium::Optional<int8_t> ratio = pAcc->GetBarcodeAttribute_WideNarrowRatio();
  if (ratio)
    pBarCodeWidget->SetWideNarrowRatio(*ratio);

  if (pBarcodeInfo->eName == BarcodeType::code3Of9 ||
      pBarcodeInfo->eName == BarcodeType::ean8 ||
      pBarcodeInfo->eName == BarcodeType::ean13 ||
      pBarcodeInfo->eName == BarcodeType::upcA) {
    pBarCodeWidget->SetPrintChecksum(true);
  }
}

bool CXFA_FFBarcode::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
  auto* pBarCodeWidget = static_cast<CFWL_Barcode*>(m_pNormalWidget.get());
  if (!pBarCodeWidget || pBarCodeWidget->IsProtectedType())
    return false;
  if (!m_pDataAcc->IsOpenAccess())
    return false;
  return CXFA_FFTextEdit::OnLButtonDown(dwFlags, point);
}

bool CXFA_FFBarcode::OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
  auto* pBarCodeWidget = static_cast<CFWL_Barcode*>(m_pNormalWidget.get());
  if (!pBarCodeWidget || pBarCodeWidget->IsProtectedType())
    return false;
  return CXFA_FFTextEdit::OnRButtonDown(dwFlags, point);
}
