// 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_ffcheckbutton.h"

#include "third_party/base/check.h"
#include "v8/include/cppgc/visitor.h"
#include "xfa/fwl/cfwl_checkbox.h"
#include "xfa/fwl/cfwl_messagemouse.h"
#include "xfa/fwl/cfwl_notedriver.h"
#include "xfa/fwl/cfwl_widgetmgr.h"
#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
#include "xfa/fxfa/cxfa_ffexclgroup.h"
#include "xfa/fxfa/cxfa_fffield.h"
#include "xfa/fxfa/cxfa_ffpageview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/parser/cxfa_border.h"
#include "xfa/fxfa/parser/cxfa_caption.h"
#include "xfa/fxfa/parser/cxfa_checkbutton.h"
#include "xfa/fxfa/parser/cxfa_para.h"

CXFA_FFCheckButton::CXFA_FFCheckButton(CXFA_Node* pNode,
                                       CXFA_CheckButton* button)
    : CXFA_FFField(pNode), button_(button) {}

CXFA_FFCheckButton::~CXFA_FFCheckButton() = default;

void CXFA_FFCheckButton::Trace(cppgc::Visitor* visitor) const {
  CXFA_FFField::Trace(visitor);
  visitor->Trace(m_pOldDelegate);
  visitor->Trace(button_);
}

bool CXFA_FFCheckButton::LoadWidget() {
  DCHECK(!IsLoaded());

  CFWL_CheckBox* pCheckBox = cppgc::MakeGarbageCollected<CFWL_CheckBox>(
      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp());
  SetNormalWidget(pCheckBox);
  pCheckBox->SetAdapterIface(this);

  CFWL_NoteDriver* pNoteDriver = pCheckBox->GetFWLApp()->GetNoteDriver();
  pNoteDriver->RegisterEventTarget(pCheckBox, pCheckBox);
  m_pOldDelegate = pCheckBox->GetDelegate();
  pCheckBox->SetDelegate(this);
  if (m_pNode->IsRadioButton())
    pCheckBox->ModifyStylesEx(FWL_STYLEEXT_CKB_RadioButton, 0xFFFFFFFF);

  {
    CFWL_Widget::ScopedUpdateLock update_lock(pCheckBox);
    UpdateWidgetProperty();
    SetFWLCheckState(m_pNode->GetCheckState());
  }

  return CXFA_FFField::LoadWidget();
}

void CXFA_FFCheckButton::UpdateWidgetProperty() {
  auto* pCheckBox = static_cast<CFWL_CheckBox*>(GetNormalWidget());
  if (!pCheckBox)
    return;

  pCheckBox->SetBoxSize(m_pNode->GetCheckButtonSize());
  uint32_t dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCross;
  switch (button_->GetMark()) {
    case XFA_AttributeValue::Check:
      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCheck;
      break;
    case XFA_AttributeValue::Circle:
      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle;
      break;
    case XFA_AttributeValue::Cross:
      break;
    case XFA_AttributeValue::Diamond:
      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeDiamond;
      break;
    case XFA_AttributeValue::Square:
      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeSquare;
      break;
    case XFA_AttributeValue::Star:
      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeStar;
      break;
    default: {
      if (button_->IsRound())
        dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle;
    } break;
  }
  if (button_->IsAllowNeutral())
    dwStyleEx |= FWL_STYLEEXT_CKB_3State;

  pCheckBox->ModifyStylesEx(
      dwStyleEx, FWL_STYLEEXT_CKB_SignShapeMask | FWL_STYLEEXT_CKB_3State);
}

bool CXFA_FFCheckButton::PerformLayout() {
  CXFA_FFWidget::PerformLayout();

  float fCheckSize = m_pNode->GetCheckButtonSize();
  CXFA_Margin* margin = m_pNode->GetMarginIfExists();
  CFX_RectF rtWidget = GetRectWithoutRotate();
  XFA_RectWithoutMargin(&rtWidget, margin);

  XFA_AttributeValue iCapPlacement = XFA_AttributeValue::Unknown;
  float fCapReserve = 0;
  CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
  if (caption && caption->IsVisible()) {
    m_CaptionRect = rtWidget;
    iCapPlacement = caption->GetPlacementType();
    fCapReserve = caption->GetReserve();
    if (fCapReserve <= 0) {
      if (iCapPlacement == XFA_AttributeValue::Top ||
          iCapPlacement == XFA_AttributeValue::Bottom) {
        fCapReserve = rtWidget.height - fCheckSize;
      } else {
        fCapReserve = rtWidget.width - fCheckSize;
      }
    }
  }

  XFA_AttributeValue iHorzAlign = XFA_AttributeValue::Left;
  XFA_AttributeValue iVertAlign = XFA_AttributeValue::Top;
  CXFA_Para* para = m_pNode->GetParaIfExists();
  if (para) {
    iHorzAlign = para->GetHorizontalAlign();
    iVertAlign = para->GetVerticalAlign();
  }

  m_UIRect = rtWidget;
  CXFA_Margin* captionMargin = caption ? caption->GetMarginIfExists() : nullptr;
  switch (iCapPlacement) {
    case XFA_AttributeValue::Left: {
      m_CaptionRect.width = fCapReserve;
      CapLeftRightPlacement(captionMargin);
      m_UIRect.width -= fCapReserve;
      m_UIRect.left += fCapReserve;
      break;
    }
    case XFA_AttributeValue::Top: {
      m_CaptionRect.height = fCapReserve;
      XFA_RectWithoutMargin(&m_CaptionRect, captionMargin);
      m_UIRect.height -= fCapReserve;
      m_UIRect.top += fCapReserve;
      break;
    }
    case XFA_AttributeValue::Right: {
      m_CaptionRect.left = m_CaptionRect.right() - fCapReserve;
      m_CaptionRect.width = fCapReserve;
      CapLeftRightPlacement(captionMargin);
      m_UIRect.width -= fCapReserve;
      break;
    }
    case XFA_AttributeValue::Bottom: {
      m_CaptionRect.top = m_CaptionRect.bottom() - fCapReserve;
      m_CaptionRect.height = fCapReserve;
      XFA_RectWithoutMargin(&m_CaptionRect, captionMargin);
      m_UIRect.height -= fCapReserve;
      break;
    }
    case XFA_AttributeValue::Inline:
      break;
    default:
      iHorzAlign = XFA_AttributeValue::Right;
      break;
  }

  if (iHorzAlign == XFA_AttributeValue::Center)
    m_UIRect.left += (m_UIRect.width - fCheckSize) / 2;
  else if (iHorzAlign == XFA_AttributeValue::Right)
    m_UIRect.left = m_UIRect.right() - fCheckSize;

  if (iVertAlign == XFA_AttributeValue::Middle)
    m_UIRect.top += (m_UIRect.height - fCheckSize) / 2;
  else if (iVertAlign == XFA_AttributeValue::Bottom)
    m_UIRect.top = m_UIRect.bottom() - fCheckSize;

  m_UIRect.width = fCheckSize;
  m_UIRect.height = fCheckSize;
  AddUIMargin(iCapPlacement);
  m_CheckBoxRect = m_UIRect;
  CXFA_Border* borderUI = m_pNode->GetUIBorder();
  if (borderUI) {
    CXFA_Margin* borderMargin = borderUI->GetMarginIfExists();
    XFA_RectWithoutMargin(&m_UIRect, borderMargin);
  }

  m_UIRect.Normalize();
  LayoutCaption();
  SetFWLRect();
  if (GetNormalWidget())
    GetNormalWidget()->Update();

  return true;
}

void CXFA_FFCheckButton::CapLeftRightPlacement(
    const CXFA_Margin* captionMargin) {
  XFA_RectWithoutMargin(&m_CaptionRect, captionMargin);
  if (m_CaptionRect.height < 0)
    m_CaptionRect.top += m_CaptionRect.height;
  if (m_CaptionRect.width < 0) {
    m_CaptionRect.left += m_CaptionRect.width;
    m_CaptionRect.width = -m_CaptionRect.width;
  }
}

void CXFA_FFCheckButton::AddUIMargin(XFA_AttributeValue iCapPlacement) {
  CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
  m_UIRect.top -= rtUIMargin.top / 2 - rtUIMargin.height / 2;

  float fLeftAddRight = rtUIMargin.left + rtUIMargin.width;
  float fTopAddBottom = rtUIMargin.top + rtUIMargin.height;
  if (m_UIRect.width < fLeftAddRight) {
    if (iCapPlacement == XFA_AttributeValue::Right ||
        iCapPlacement == XFA_AttributeValue::Left) {
      m_UIRect.left -= fLeftAddRight - m_UIRect.width;
    } else {
      m_UIRect.left -= 2 * (fLeftAddRight - m_UIRect.width);
    }
    m_UIRect.width += 2 * (fLeftAddRight - m_UIRect.width);
  }
  if (m_UIRect.height < fTopAddBottom) {
    if (iCapPlacement == XFA_AttributeValue::Right)
      m_UIRect.left -= fTopAddBottom - m_UIRect.height;

    m_UIRect.top -= fTopAddBottom - m_UIRect.height;
    m_UIRect.height += 2 * (fTopAddBottom - m_UIRect.height);
  }
}

void CXFA_FFCheckButton::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);
  DrawBorderWithFlag(pGS, m_pNode->GetUIBorder(), m_UIRect, mtRotate,
                     button_->IsRound());
  RenderCaption(pGS, &mtRotate);
  DrawHighlight(pGS, &mtRotate, highlight,
                button_->IsRound() ? kRoundShape : kSquareShape);
  CFX_Matrix mt(1, 0, 0, 1, m_CheckBoxRect.left, m_CheckBoxRect.top);
  mt.Concat(mtRotate);
  GetApp()->GetFWLWidgetMgr()->OnDrawWidget(GetNormalWidget(), pGS, mt);
}

bool CXFA_FFCheckButton::OnLButtonUp(uint32_t dwFlags,
                                     const CFX_PointF& point) {
  if (!GetNormalWidget() || !IsButtonDown())
    return false;

  SetButtonDown(false);
  CFWL_MessageMouse msg(GetNormalWidget(), FWL_MouseCommand::LeftButtonUp,
                        dwFlags, FWLToClient(point));
  SendMessageToFWLWidget(&msg);
  return true;
}

XFA_CHECKSTATE CXFA_FFCheckButton::FWLState2XFAState() {
  uint32_t dwState = GetNormalWidget()->GetStates();
  if (dwState & FWL_STATE_CKB_Checked)
    return XFA_CHECKSTATE_On;
  if (dwState & FWL_STATE_CKB_Neutral)
    return XFA_CHECKSTATE_Neutral;
  return XFA_CHECKSTATE_Off;
}

bool CXFA_FFCheckButton::CommitData() {
  XFA_CHECKSTATE eCheckState = FWLState2XFAState();
  m_pNode->SetCheckState(eCheckState, true);
  return true;
}

bool CXFA_FFCheckButton::IsDataChanged() {
  XFA_CHECKSTATE eCheckState = FWLState2XFAState();
  return m_pNode->GetCheckState() != eCheckState;
}

void CXFA_FFCheckButton::SetFWLCheckState(XFA_CHECKSTATE eCheckState) {
  if (eCheckState == XFA_CHECKSTATE_Neutral)
    GetNormalWidget()->SetStates(FWL_STATE_CKB_Neutral);
  else if (eCheckState == XFA_CHECKSTATE_On)
    GetNormalWidget()->SetStates(FWL_STATE_CKB_Checked);
  else
    GetNormalWidget()->RemoveStates(FWL_STATE_CKB_Checked);
}

bool CXFA_FFCheckButton::UpdateFWLData() {
  if (!GetNormalWidget())
    return false;

  SetFWLCheckState(m_pNode->GetCheckState());
  GetNormalWidget()->Update();
  return true;
}

void CXFA_FFCheckButton::OnProcessMessage(CFWL_Message* pMessage) {
  m_pOldDelegate->OnProcessMessage(pMessage);
}

void CXFA_FFCheckButton::OnProcessEvent(CFWL_Event* pEvent) {
  CXFA_FFField::OnProcessEvent(pEvent);
  switch (pEvent->GetType()) {
    case CFWL_Event::Type::CheckStateChanged: {
      CXFA_EventParam eParam;
      eParam.m_eType = XFA_EVENT_Change;
      eParam.m_wsPrevText = m_pNode->GetValue(XFA_VALUEPICTURE_Raw);

      CXFA_Node* exclNode = m_pNode->GetExclGroupIfExists();
      if (ProcessCommittedData()) {
        eParam.m_pTarget = exclNode;
        if (exclNode) {
          m_pDocView->AddValidateNode(exclNode);
          m_pDocView->AddCalculateNode(exclNode);
          exclNode->ProcessEvent(GetDocView(), XFA_AttributeValue::Change,
                                 &eParam);
        }
        eParam.m_pTarget = m_pNode.Get();
        m_pNode->ProcessEvent(GetDocView(), XFA_AttributeValue::Change,
                              &eParam);
      } else {
        SetFWLCheckState(m_pNode->GetCheckState());
      }
      if (exclNode) {
        eParam.m_pTarget = exclNode;
        exclNode->ProcessEvent(GetDocView(), XFA_AttributeValue::Click,
                               &eParam);
      }
      eParam.m_pTarget = m_pNode.Get();
      m_pNode->ProcessEvent(GetDocView(), XFA_AttributeValue::Click, &eParam);
      break;
    }
    default:
      break;
  }
  m_pOldDelegate->OnProcessEvent(pEvent);
}

void CXFA_FFCheckButton::OnDrawWidget(CFGAS_GEGraphics* pGraphics,
                                      const CFX_Matrix& matrix) {
  m_pOldDelegate->OnDrawWidget(pGraphics, matrix);
}

FormFieldType CXFA_FFCheckButton::GetFormFieldType() {
  return FormFieldType::kXFA_CheckBox;
}
