// 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 "xfa/fxfa/cxfa_fftext.h"

#include "xfa/fgas/graphics/cfgas_gegraphics.h"
#include "xfa/fgas/layout/cfgas_linkuserdata.h"
#include "xfa/fwl/fwl_widgethit.h"
#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffpageview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_textlayout.h"
#include "xfa/fxfa/parser/cxfa_margin.h"

CXFA_FFText::CXFA_FFText(CXFA_Node* pNode) : CXFA_FFWidget(pNode) {}

CXFA_FFText::~CXFA_FFText() = default;

void CXFA_FFText::RenderWidget(CFGAS_GEGraphics* pGS,
                               const CFX_Matrix& matrix,
                               HighlightOption highlight) {
  if (!HasVisibleStatus())
    return;

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

  CXFA_FFWidget::RenderWidget(pGS, mtRotate, highlight);

  CXFA_TextLayout* pTextLayout = m_pNode->GetTextLayout();
  if (!pTextLayout)
    return;

  CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
  CFX_RectF rtText = GetRectWithoutRotate();
  CXFA_Margin* margin = m_pNode->GetMarginIfExists();
  if (margin) {
    CXFA_ContentLayoutItem* pItem = GetLayoutItem();
    if (!pItem->GetPrev() && !pItem->GetNext()) {
      XFA_RectWithoutMargin(&rtText, margin);
    } else {
      float fTopInset = 0;
      float fBottomInset = 0;
      if (!pItem->GetPrev())
        fTopInset = margin->GetTopInset();
      else if (!pItem->GetNext())
        fBottomInset = margin->GetBottomInset();

      rtText.Deflate(margin->GetLeftInset(), fTopInset, margin->GetRightInset(),
                     fBottomInset);
    }
  }

  CFX_Matrix mt(1, 0, 0, 1, rtText.left, rtText.top);
  CFX_RectF rtClip = mtRotate.TransformRect(rtText);
  mt.Concat(mtRotate);
  pTextLayout->DrawString(pRenderDevice, mt, rtClip,
                          GetLayoutItem()->GetIndex());
}

bool CXFA_FFText::IsLoaded() {
  CXFA_TextLayout* pTextLayout = m_pNode->GetTextLayout();
  return pTextLayout && !pTextLayout->HasBlock();
}

void CXFA_FFText::PerformLayout() {
  CXFA_FFWidget::PerformLayout();
  CXFA_TextLayout* pTextLayout = m_pNode->GetTextLayout();
  if (!pTextLayout || !pTextLayout->HasBlock()) {
    return;
  }
  pTextLayout->ClearBlocks();
  CXFA_ContentLayoutItem* pItem = GetLayoutItem();
  if (!pItem->GetPrev() && !pItem->GetNext()) {
    return;
  }
  pItem = pItem->GetFirst();
  while (pItem) {
    CFX_RectF rtText = pItem->GetAbsoluteRect();
    CXFA_Margin* margin = m_pNode->GetMarginIfExists();
    if (margin) {
      if (!pItem->GetPrev())
        rtText.height -= margin->GetTopInset();
      else if (!pItem->GetNext())
        rtText.height -= margin->GetBottomInset();
    }
    pTextLayout->ItemBlocks(rtText, pItem->GetIndex());
    pItem = pItem->GetNext();
  }
  pTextLayout->ResetHasBlock();
}

bool CXFA_FFText::AcceptsFocusOnButtonDown(
    Mask<XFA_FWL_KeyFlag> dwFlags,
    const CFX_PointF& point,
    CFWL_MessageMouse::MouseCommand command) {
  return command == CFWL_MessageMouse::MouseCommand::kLeftButtonDown &&
         GetRectWithoutRotate().Contains(point) &&
         !GetLinkURLAtPoint(point).IsEmpty();
}

bool CXFA_FFText::OnLButtonDown(Mask<XFA_FWL_KeyFlag> dwFlags,
                                const CFX_PointF& point) {
  SetButtonDown(true);
  return true;
}

bool CXFA_FFText::OnMouseMove(Mask<XFA_FWL_KeyFlag> dwFlags,
                              const CFX_PointF& point) {
  return GetRectWithoutRotate().Contains(point) &&
         !GetLinkURLAtPoint(point).IsEmpty();
}

bool CXFA_FFText::OnLButtonUp(Mask<XFA_FWL_KeyFlag> dwFlags,
                              const CFX_PointF& point) {
  if (!IsButtonDown())
    return false;

  SetButtonDown(false);
  WideString wsURLContent = GetLinkURLAtPoint(point);
  if (wsURLContent.IsEmpty())
    return false;

  GetDoc()->GotoURL(wsURLContent);
  return true;
}

FWL_WidgetHit CXFA_FFText::HitTest(const CFX_PointF& point) {
  if (GetRectWithoutRotate().Contains(point) &&
      !GetLinkURLAtPoint(point).IsEmpty()) {
    return FWL_WidgetHit::HyperLink;
  }
  return FWL_WidgetHit::Unknown;
}

WideString CXFA_FFText::GetLinkURLAtPoint(const CFX_PointF& point) {
  CXFA_TextLayout* pTextLayout = m_pNode->GetTextLayout();
  if (!pTextLayout)
    return WideString();

  CFX_RectF rect = GetRectWithoutRotate();
  return pTextLayout->GetLinkURLAtPoint(point - rect.TopLeft());
}
