// 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 <utility>
#include "third_party/base/ptr_util.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_para.h"

CXFA_FFCheckButton::CXFA_FFCheckButton(CXFA_Node* pNode)
    : CXFA_FFField(pNode), m_pOldDelegate(nullptr) {}

CXFA_FFCheckButton::~CXFA_FFCheckButton() {}

bool CXFA_FFCheckButton::LoadWidget() {
  auto pNew = pdfium::MakeUnique<CFWL_CheckBox>(GetFWLApp());
  CFWL_CheckBox* pCheckBox = 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);
  if (m_pNode->GetWidgetAcc()->IsRadioButton())
    pCheckBox->ModifyStylesEx(FWL_STYLEEXT_CKB_RadioButton, 0xFFFFFFFF);

  m_pNormalWidget->LockUpdate();
  UpdateWidgetProperty();
  SetFWLCheckState(m_pNode->GetWidgetAcc()->GetCheckState());
  m_pNormalWidget->UnlockUpdate();
  return CXFA_FFField::LoadWidget();
}

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

  pCheckBox->SetBoxSize(m_pNode->GetWidgetAcc()->GetCheckButtonSize());
  uint32_t dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCross;
  switch (m_pNode->GetWidgetAcc()->GetCheckButtonMark()) {
    case XFA_AttributeEnum::Check:
      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCheck;
      break;
    case XFA_AttributeEnum::Circle:
      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle;
      break;
    case XFA_AttributeEnum::Cross:
      break;
    case XFA_AttributeEnum::Diamond:
      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeDiamond;
      break;
    case XFA_AttributeEnum::Square:
      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeSquare;
      break;
    case XFA_AttributeEnum::Star:
      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeStar;
      break;
    default: {
      if (m_pNode->GetWidgetAcc()->IsCheckButtonRound())
        dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle;
    } break;
  }
  if (m_pNode->GetWidgetAcc()->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->GetWidgetAcc()->GetCheckButtonSize();
  CXFA_Margin* margin = m_pNode->GetMargin();
  CFX_RectF rtWidget = GetRectWithoutRotate();
  if (margin)
    XFA_RectWidthoutMargin(rtWidget, margin);

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

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

  m_rtUI = rtWidget;
  CXFA_Margin* captionMargin = caption->GetMargin();
  switch (iCapPlacement) {
    case XFA_AttributeEnum::Left: {
      m_rtCaption.width = fCapReserve;
      CapLeftRightPlacement(captionMargin);
      m_rtUI.width -= fCapReserve;
      m_rtUI.left += fCapReserve;
      break;
    }
    case XFA_AttributeEnum::Top: {
      m_rtCaption.height = fCapReserve;
      XFA_RectWidthoutMargin(m_rtCaption, captionMargin);
      m_rtUI.height -= fCapReserve;
      m_rtUI.top += fCapReserve;
      break;
    }
    case XFA_AttributeEnum::Right: {
      m_rtCaption.left = m_rtCaption.right() - fCapReserve;
      m_rtCaption.width = fCapReserve;
      CapLeftRightPlacement(captionMargin);
      m_rtUI.width -= fCapReserve;
      break;
    }
    case XFA_AttributeEnum::Bottom: {
      m_rtCaption.top = m_rtCaption.bottom() - fCapReserve;
      m_rtCaption.height = fCapReserve;
      XFA_RectWidthoutMargin(m_rtCaption, captionMargin);
      m_rtUI.height -= fCapReserve;
      break;
    }
    case XFA_AttributeEnum::Inline:
      break;
    default:
      iHorzAlign = XFA_AttributeEnum::Right;
      break;
  }

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

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

  m_rtUI.width = fCheckSize;
  m_rtUI.height = fCheckSize;
  AddUIMargin(iCapPlacement);
  m_rtCheckBox = m_rtUI;
  CXFA_Border* borderUI = m_pNode->GetWidgetAcc()->GetUIBorder();
  if (borderUI) {
    CXFA_Margin* borderMargin = borderUI->GetMargin();
    if (borderMargin)
      XFA_RectWidthoutMargin(m_rtUI, borderMargin);
  }

  m_rtUI.Normalize();
  LayoutCaption();
  SetFWLRect();
  if (m_pNormalWidget)
    m_pNormalWidget->Update();

  return true;
}

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

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

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

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

void CXFA_FFCheckButton::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);
  DrawBorderWithFlags(
      pGS, m_pNode->GetWidgetAcc()->GetUIBorder(), m_rtUI, mtRotate,
      m_pNode->GetWidgetAcc()->IsCheckButtonRound() ? XFA_DRAWBOX_ForceRound
                                                    : 0);
  RenderCaption(pGS, &mtRotate);
  DrawHighlight(pGS, &mtRotate, dwStatus,
                m_pNode->GetWidgetAcc()->IsCheckButtonRound());
  CFX_Matrix mt(1, 0, 0, 1, m_rtCheckBox.left, m_rtCheckBox.top);
  mt.Concat(mtRotate);
  GetApp()->GetFWLWidgetMgr()->OnDrawWidget(m_pNormalWidget.get(), pGS, mt);
}

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

  SetButtonDown(false);
  CFWL_MessageMouse ms(nullptr, m_pNormalWidget.get());
  ms.m_dwCmd = FWL_MouseCommand::LeftButtonUp;
  ms.m_dwFlags = dwFlags;
  ms.m_pos = FWLToClient(point);
  TranslateFWLMessage(&ms);
  return true;
}

XFA_CHECKSTATE CXFA_FFCheckButton::FWLState2XFAState() {
  uint32_t dwState = m_pNormalWidget->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->GetWidgetAcc()->SetCheckState(eCheckState, true);
  return true;
}

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

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

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

  XFA_CHECKSTATE eState = m_pNode->GetWidgetAcc()->GetCheckState();
  SetFWLCheckState(eState);
  m_pNormalWidget->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_wsNewText =
          m_pNode->GetWidgetAcc()->GetValue(XFA_VALUEPICTURE_Raw);

      CXFA_Node* exclNode = m_pNode->GetExclGroup();
      if (ProcessCommittedData()) {
        eParam.m_pTarget = exclNode ? exclNode->GetWidgetAcc() : nullptr;
        if (exclNode) {
          m_pDocView->AddValidateWidget(exclNode->GetWidgetAcc());
          m_pDocView->AddCalculateWidgetAcc(exclNode->GetWidgetAcc());
          exclNode->ProcessEvent(GetDocView(), XFA_AttributeEnum::Change,
                                 &eParam);
        }
        eParam.m_pTarget = m_pNode->GetWidgetAcc();
        m_pNode->ProcessEvent(GetDocView(), XFA_AttributeEnum::Change, &eParam);
      } else {
        SetFWLCheckState(m_pNode->GetWidgetAcc()->GetCheckState());
      }
      if (exclNode) {
        eParam.m_pTarget = exclNode->GetWidgetAcc();
        exclNode->ProcessEvent(GetDocView(), XFA_AttributeEnum::Click, &eParam);
      }
      eParam.m_pTarget = m_pNode->GetWidgetAcc();
      m_pNode->ProcessEvent(GetDocView(), XFA_AttributeEnum::Click, &eParam);
      break;
    }
    default:
      break;
  }
  m_pOldDelegate->OnProcessEvent(pEvent);
}

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