// Copyright 2014 The PDFium Authors
// 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 "fxbarcode/cfx_barcode.h"

#include <memory>

#include "core/fxcrt/notreached.h"
#include "core/fxcrt/ptr_util.h"
#include "fxbarcode/cbc_codabar.h"
#include "fxbarcode/cbc_code128.h"
#include "fxbarcode/cbc_code39.h"
#include "fxbarcode/cbc_codebase.h"
#include "fxbarcode/cbc_datamatrix.h"
#include "fxbarcode/cbc_ean13.h"
#include "fxbarcode/cbc_ean8.h"
#include "fxbarcode/cbc_pdf417i.h"
#include "fxbarcode/cbc_qrcode.h"
#include "fxbarcode/cbc_upca.h"

namespace {

std::unique_ptr<CBC_CodeBase> CreateBarCodeEngineObject(BC_TYPE type) {
  switch (type) {
    case BC_TYPE::kCode39:
      return std::make_unique<CBC_Code39>();
    case BC_TYPE::kCodabar:
      return std::make_unique<CBC_Codabar>();
    case BC_TYPE::kCode128:
      return std::make_unique<CBC_Code128>(BC_TYPE::kCode128B);
    case BC_TYPE::kCode128B:
      return std::make_unique<CBC_Code128>(BC_TYPE::kCode128B);
    case BC_TYPE::kCode128C:
      return std::make_unique<CBC_Code128>(BC_TYPE::kCode128C);
    case BC_TYPE::kEAN8:
      return std::make_unique<CBC_EAN8>();
    case BC_TYPE::kUPCA:
      return std::make_unique<CBC_UPCA>();
    case BC_TYPE::kEAN13:
      return std::make_unique<CBC_EAN13>();
    case BC_TYPE::kQRCode:
      return std::make_unique<CBC_QRCode>();
    case BC_TYPE::kPDF417:
      return std::make_unique<CBC_PDF417I>();
    case BC_TYPE::kDataMatrix:
      return std::make_unique<CBC_DataMatrix>();
    case BC_TYPE::kUnknown:
      NOTREACHED();
  }
  NOTREACHED();
}

}  // namespace

CFX_Barcode::CFX_Barcode(BC_TYPE type)
    : bc_engine_(CreateBarCodeEngineObject(type)) {}

CFX_Barcode::~CFX_Barcode() = default;

BC_TYPE CFX_Barcode::GetType() {
  return bc_engine_->GetType();
}

bool CFX_Barcode::SetModuleHeight(int32_t moduleHeight) {
  return bc_engine_->SetModuleHeight(moduleHeight);
}

bool CFX_Barcode::SetModuleWidth(int32_t moduleWidth) {
  return bc_engine_->SetModuleWidth(moduleWidth);
}

void CFX_Barcode::SetHeight(int32_t height) {
  bc_engine_->SetHeight(height);
}

void CFX_Barcode::SetWidth(int32_t width) {
  bc_engine_->SetWidth(width);
}

bool CFX_Barcode::SetPrintChecksum(bool checksum) {
  switch (GetType()) {
    case BC_TYPE::kCode39:
    case BC_TYPE::kCodabar:
    case BC_TYPE::kCode128:
    case BC_TYPE::kCode128B:
    case BC_TYPE::kCode128C:
    case BC_TYPE::kEAN8:
    case BC_TYPE::kEAN13:
    case BC_TYPE::kUPCA:
      static_cast<CBC_OneCode*>(bc_engine_.get())->SetPrintChecksum(checksum);
      return true;
    default:
      return false;
  }
}

bool CFX_Barcode::SetDataLength(int32_t length) {
  switch (GetType()) {
    case BC_TYPE::kCode39:
    case BC_TYPE::kCodabar:
    case BC_TYPE::kCode128:
    case BC_TYPE::kCode128B:
    case BC_TYPE::kCode128C:
    case BC_TYPE::kEAN8:
    case BC_TYPE::kEAN13:
    case BC_TYPE::kUPCA:
      static_cast<CBC_OneCode*>(bc_engine_.get())->SetDataLength(length);
      return true;
    default:
      return false;
  }
}

bool CFX_Barcode::SetCalChecksum(bool state) {
  switch (GetType()) {
    case BC_TYPE::kCode39:
    case BC_TYPE::kCodabar:
    case BC_TYPE::kCode128:
    case BC_TYPE::kCode128B:
    case BC_TYPE::kCode128C:
    case BC_TYPE::kEAN8:
    case BC_TYPE::kEAN13:
    case BC_TYPE::kUPCA:
      static_cast<CBC_OneCode*>(bc_engine_.get())->SetCalChecksum(state);
      return true;
    default:
      return false;
  }
}

bool CFX_Barcode::SetFont(CFX_Font* font) {
  switch (GetType()) {
    case BC_TYPE::kCode39:
    case BC_TYPE::kCodabar:
    case BC_TYPE::kCode128:
    case BC_TYPE::kCode128B:
    case BC_TYPE::kCode128C:
    case BC_TYPE::kEAN8:
    case BC_TYPE::kEAN13:
    case BC_TYPE::kUPCA:
      return static_cast<CBC_OneCode*>(bc_engine_.get())->SetFont(font);
    default:
      return false;
  }
}

bool CFX_Barcode::SetFontSize(float size) {
  switch (GetType()) {
    case BC_TYPE::kCode39:
    case BC_TYPE::kCodabar:
    case BC_TYPE::kCode128:
    case BC_TYPE::kCode128B:
    case BC_TYPE::kCode128C:
    case BC_TYPE::kEAN8:
    case BC_TYPE::kEAN13:
    case BC_TYPE::kUPCA:
      static_cast<CBC_OneCode*>(bc_engine_.get())->SetFontSize(size);
      return true;
    default:
      return false;
  }
}

bool CFX_Barcode::SetFontColor(FX_ARGB color) {
  switch (GetType()) {
    case BC_TYPE::kCode39:
    case BC_TYPE::kCodabar:
    case BC_TYPE::kCode128:
    case BC_TYPE::kCode128B:
    case BC_TYPE::kCode128C:
    case BC_TYPE::kEAN8:
    case BC_TYPE::kEAN13:
    case BC_TYPE::kUPCA:
      static_cast<CBC_OneCode*>(bc_engine_.get())->SetFontColor(color);
      return true;
    default:
      return false;
  }
}

void CFX_Barcode::SetTextLocation(BC_TEXT_LOC location) {
  bc_engine_->SetTextLocation(location);
}

bool CFX_Barcode::SetWideNarrowRatio(int8_t ratio) {
  return bc_engine_->SetWideNarrowRatio(ratio);
}

bool CFX_Barcode::SetStartChar(char start) {
  return bc_engine_->SetStartChar(start);
}

bool CFX_Barcode::SetEndChar(char end) {
  return bc_engine_->SetEndChar(end);
}

bool CFX_Barcode::SetErrorCorrectionLevel(int32_t level) {
  return bc_engine_->SetErrorCorrectionLevel(level);
}

bool CFX_Barcode::Encode(WideStringView contents) {
  return bc_engine_->Encode(contents);
}

bool CFX_Barcode::RenderDevice(CFX_RenderDevice* device,
                               const CFX_Matrix& matrix) {
  return bc_engine_->RenderDevice(device, matrix);
}
