// Copyright 2016 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 "fpdfsdk/cfx_systemhandler.h"

#include <memory>

#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxge/cfx_fontmapper.h"
#include "core/fxge/cfx_fontmgr.h"
#include "core/fxge/cfx_gemodule.h"
#include "fpdfsdk/cpdfsdk_annot.h"
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "fpdfsdk/cpdfsdk_widget.h"
#include "fpdfsdk/formfiller/cffl_formfiller.h"

namespace {

int CharSet2CP(int charset) {
  if (charset == FX_CHARSET_ShiftJIS)
    return FX_CODEPAGE_ShiftJIS;
  if (charset == FX_CHARSET_ChineseSimplified)
    return FX_CODEPAGE_ChineseSimplified;
  if (charset == FX_CHARSET_Hangul)
    return FX_CODEPAGE_Hangul;
  if (charset == FX_CHARSET_ChineseTraditional)
    return FX_CODEPAGE_ChineseTraditional;
  return FX_CODEPAGE_DefANSI;
}

}  // namespace

CFX_SystemHandler::CFX_SystemHandler(CPDFSDK_FormFillEnvironment* pFormFillEnv)
    : m_pFormFillEnv(pFormFillEnv) {}

CFX_SystemHandler::~CFX_SystemHandler() {}

void CFX_SystemHandler::InvalidateRect(CPDFSDK_Widget* widget, FX_RECT rect) {
  CPDFSDK_PageView* pPageView = widget->GetPageView();
  UnderlyingPageType* pPage = widget->GetUnderlyingPage();
  if (!pPage || !pPageView)
    return;

  CFX_Matrix page2device;
  pPageView->GetCurrentMatrix(page2device);

  CFX_Matrix device2page = page2device.GetInverse();

  CFX_PointF left_top = device2page.Transform(
      CFX_PointF(static_cast<float>(rect.left), static_cast<float>(rect.top)));
  CFX_PointF right_bottom = device2page.Transform(CFX_PointF(
      static_cast<float>(rect.right), static_cast<float>(rect.bottom)));

  CFX_FloatRect rcPDF(left_top.x, right_bottom.y, right_bottom.x, left_top.y);
  rcPDF.Normalize();
  m_pFormFillEnv->Invalidate(pPage, rcPDF.ToFxRect());
}

void CFX_SystemHandler::OutputSelectedRect(CFFL_FormFiller* pFormFiller,
                                           CFX_FloatRect& rect) {
  if (!pFormFiller)
    return;

  CFX_PointF ptA = pFormFiller->PWLtoFFL(CFX_PointF(rect.left, rect.bottom));
  CFX_PointF ptB = pFormFiller->PWLtoFFL(CFX_PointF(rect.right, rect.top));

  CPDFSDK_Annot* pAnnot = pFormFiller->GetSDKAnnot();
  UnderlyingPageType* pPage = pAnnot->GetUnderlyingPage();
  ASSERT(pPage);

  m_pFormFillEnv->OutputSelectedRect(pPage,
                                     CFX_FloatRect(ptA.x, ptA.y, ptB.x, ptB.y));
}

bool CFX_SystemHandler::IsSelectionImplemented() const {
  if (!m_pFormFillEnv)
    return false;

  FPDF_FORMFILLINFO* pInfo = m_pFormFillEnv->GetFormFillInfo();
  return pInfo && pInfo->FFI_OutputSelectedRect;
}

void CFX_SystemHandler::SetCursor(int32_t nCursorType) {
  m_pFormFillEnv->SetCursor(nCursorType);
}

bool CFX_SystemHandler::FindNativeTrueTypeFont(CFX_ByteString sFontFaceName) {
  CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
  if (!pFontMgr)
    return false;

  CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
  if (!pFontMapper)
    return false;

  if (pFontMapper->m_InstalledTTFonts.empty())
    pFontMapper->LoadInstalledFonts();

  for (const auto& font : pFontMapper->m_InstalledTTFonts) {
    if (font.Compare(sFontFaceName.AsStringC()))
      return true;
  }
  for (const auto& fontPair : pFontMapper->m_LocalizedTTFonts) {
    if (fontPair.first.Compare(sFontFaceName.AsStringC()))
      return true;
  }
  return false;
}

CPDF_Font* CFX_SystemHandler::AddNativeTrueTypeFontToPDF(
    CPDF_Document* pDoc,
    CFX_ByteString sFontFaceName,
    uint8_t nCharset) {
  if (!pDoc)
    return nullptr;

  auto pFXFont = pdfium::MakeUnique<CFX_Font>();
  pFXFont->LoadSubst(sFontFaceName, true, 0, 0, 0, CharSet2CP(nCharset), false);
  return pDoc->AddFont(pFXFont.get(), nCharset, false);
}

int32_t CFX_SystemHandler::SetTimer(int32_t uElapse,
                                    TimerCallback lpTimerFunc) {
  return m_pFormFillEnv->SetTimer(uElapse, lpTimerFunc);
}

void CFX_SystemHandler::KillTimer(int32_t nID) {
  m_pFormFillEnv->KillTimer(nID);
}
