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

#include "xfa/fwl/core/cfwl_checkbox.h"
#include "xfa/fwl/core/cfwl_message.h"
#include "xfa/fwl/core/cfwl_widgetmgr.h"
#include "xfa/fwl/core/fwl_noteimp.h"
#include "xfa/fxfa/app/xfa_ffexclgroup.h"
#include "xfa/fxfa/app/xfa_fffield.h"
#include "xfa/fxfa/xfa_ffapp.h"
#include "xfa/fxfa/xfa_ffdoc.h"
#include "xfa/fxfa/xfa_ffdocview.h"
#include "xfa/fxfa/xfa_ffpageview.h"
#include "xfa/fxfa/xfa_ffwidget.h"

CXFA_FFCheckButton::CXFA_FFCheckButton(CXFA_FFPageView* pPageView,
                                       CXFA_WidgetAcc* pDataAcc)
    : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(nullptr) {
  m_rtCheckBox.Set(0, 0, 0, 0);
}

CXFA_FFCheckButton::~CXFA_FFCheckButton() {}

bool CXFA_FFCheckButton::LoadWidget() {
  CFWL_CheckBox* pCheckBox = new CFWL_CheckBox(GetFWLApp());
  pCheckBox->Initialize();
  m_pNormalWidget = pCheckBox;
  m_pNormalWidget->SetLayoutItem(this);

  IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
  CFWL_NoteDriver* pNoteDriver = pWidget->GetOwnerApp()->GetNoteDriver();
  pNoteDriver->RegisterEventTarget(pWidget, pWidget);

  m_pOldDelegate = m_pNormalWidget->GetDelegate();
  m_pNormalWidget->SetDelegate(this);

  if (m_pDataAcc->IsRadioButton())
    pCheckBox->ModifyStylesEx(FWL_STYLEEXT_CKB_RadioButton, 0xFFFFFFFF);

  m_pNormalWidget->LockUpdate();
  UpdateWidgetProperty();
  SetFWLCheckState(m_pDataAcc->GetCheckState());
  m_pNormalWidget->UnlockUpdate();
  return CXFA_FFField::LoadWidget();
}
void CXFA_FFCheckButton::UpdateWidgetProperty() {
  CFWL_CheckBox* pCheckBox = (CFWL_CheckBox*)m_pNormalWidget;
  if (!m_pNormalWidget) {
    return;
  }
  FX_FLOAT fSize = m_pDataAcc->GetCheckButtonSize();
  pCheckBox->SetBoxSize(fSize);
  uint32_t dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCross;
  int32_t iCheckMark = m_pDataAcc->GetCheckButtonMark();
  switch (iCheckMark) {
    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: {
      int32_t iShape = m_pDataAcc->GetCheckButtonShape();
      if (iShape == XFA_ATTRIBUTEENUM_Round) {
        dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle;
      }
    } break;
  }
  if (m_pDataAcc->IsAllowNeutral()) {
    dwStyleEx |= FWL_STYLEEXT_CKB_3State;
  }
  pCheckBox->ModifyStylesEx(
      dwStyleEx, FWL_STYLEEXT_CKB_SignShapeMask | FWL_STYLEEXT_CKB_3State);
}
bool CXFA_FFCheckButton::PerformLayout() {
  CXFA_FFWidget::PerformLayout();
  FX_FLOAT fCheckSize = m_pDataAcc->GetCheckButtonSize();
  CXFA_Margin mgWidget = m_pDataAcc->GetMargin();
  CFX_RectF rtWidget;
  GetRectWithoutRotate(rtWidget);
  if (mgWidget) {
    XFA_RectWidthoutMargin(rtWidget, mgWidget);
  }
  int32_t iCapPlacement = -1;
  FX_FLOAT fCapReserve = 0;
  CXFA_Caption caption = m_pDataAcc->GetCaption();
  if (caption && caption.GetPresence()) {
    m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width,
                    rtWidget.height);
    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;
      }
    }
  }
  int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left;
  int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top;
  if (CXFA_Para para = m_pDataAcc->GetPara()) {
    iHorzAlign = para.GetHorizontalAlign();
    iVertAlign = para.GetVerticalAlign();
  }
  m_rtUI = rtWidget;
  CXFA_Margin mgCap = caption.GetMargin();
  switch (iCapPlacement) {
    case XFA_ATTRIBUTEENUM_Left: {
      m_rtCaption.width = fCapReserve;
      CapLeftRightPlacement(mgCap);
      m_rtUI.width -= fCapReserve;
      m_rtUI.left += fCapReserve;
    } break;
    case XFA_ATTRIBUTEENUM_Top: {
      m_rtCaption.height = fCapReserve;
      XFA_RectWidthoutMargin(m_rtCaption, mgCap);
      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(mgCap);
      m_rtUI.width -= fCapReserve;
    } break;
    case XFA_ATTRIBUTEENUM_Bottom: {
      m_rtCaption.top = m_rtCaption.bottom() - fCapReserve;
      m_rtCaption.height = fCapReserve;
      XFA_RectWidthoutMargin(m_rtCaption, mgCap);
      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_pDataAcc->GetUIBorder();
  if (borderUI) {
    CXFA_Margin margin = borderUI.GetMargin();
    if (margin) {
      XFA_RectWidthoutMargin(m_rtUI, margin);
    }
  }
  m_rtUI.Normalize();
  LayoutCaption();
  SetFWLRect();
  if (m_pNormalWidget) {
    m_pNormalWidget->Update();
  }
  return true;
}
void CXFA_FFCheckButton::CapLeftRightPlacement(CXFA_Margin mgCap) {
  XFA_RectWidthoutMargin(m_rtCaption, mgCap);
  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(int32_t iCapPlacement) {
  CFX_RectF rtUIMargin;
  m_pDataAcc->GetUIMargin(rtUIMargin);
  m_rtUI.top -= rtUIMargin.top / 2 - rtUIMargin.height / 2;
  FX_FLOAT fLeftAddRight = rtUIMargin.left + rtUIMargin.width;
  FX_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(CFX_Graphics* pGS,
                                      CFX_Matrix* pMatrix,
                                      uint32_t dwStatus) {
  if (!IsMatchVisibleStatus(dwStatus)) {
    return;
  }
  CFX_Matrix mtRotate;
  GetRotateMatrix(mtRotate);
  if (pMatrix) {
    mtRotate.Concat(*pMatrix);
  }
  CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
  CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
  DrawBorder(pGS, borderUI, m_rtUI, &mtRotate,
             m_pDataAcc->GetCheckButtonShape() == XFA_ATTRIBUTEENUM_Round
                 ? XFA_DRAWBOX_ForceRound
                 : 0);
  RenderCaption(pGS, &mtRotate);
  DrawHighlight(pGS, &mtRotate, dwStatus,
                m_pDataAcc->GetCheckButtonShape() == XFA_ATTRIBUTEENUM_Round);
  CFX_Matrix mt;
  mt.Set(1, 0, 0, 1, m_rtCheckBox.left, m_rtCheckBox.top);
  mt.Concat(mtRotate);
  GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget->GetWidget(),
                                                 pGS, &mt);
}
bool CXFA_FFCheckButton::OnLButtonUp(uint32_t dwFlags,
                                     FX_FLOAT fx,
                                     FX_FLOAT fy) {
  if (!m_pNormalWidget || !IsButtonDown())
    return false;

  SetButtonDown(false);
  CFWL_MsgMouse ms;
  ms.m_dwCmd = FWL_MouseCommand::LeftButtonUp;
  ms.m_dwFlags = dwFlags;
  ms.m_fx = fx;
  ms.m_fy = fy;
  FWLToClient(ms.m_fx, ms.m_fy);
  ms.m_pDstTarget = m_pNormalWidget->GetWidget();
  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_pDataAcc->SetCheckState(eCheckState, true);
  return true;
}

bool CXFA_FFCheckButton::IsDataChanged() {
  XFA_CHECKSTATE eCheckState = FWLState2XFAState();
  return m_pDataAcc->GetCheckState() != eCheckState;
}
void CXFA_FFCheckButton::SetFWLCheckState(XFA_CHECKSTATE eCheckState) {
  if (eCheckState == XFA_CHECKSTATE_Neutral) {
    m_pNormalWidget->SetStates(FWL_STATE_CKB_Neutral, true);
  } else {
    m_pNormalWidget->SetStates(FWL_STATE_CKB_Checked,
                               eCheckState == XFA_CHECKSTATE_On);
  }
}
bool CXFA_FFCheckButton::UpdateFWLData() {
  if (!m_pNormalWidget) {
    return false;
  }
  XFA_CHECKSTATE eState = m_pDataAcc->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->GetClassID()) {
    case CFWL_EventType::CheckStateChanged: {
      CXFA_EventParam eParam;
      eParam.m_eType = XFA_EVENT_Change;
      m_pDataAcc->GetValue(eParam.m_wsNewText, XFA_VALUEPICTURE_Raw);
      CXFA_WidgetAcc* pFFExclGroup = m_pDataAcc->GetExclGroup();
      if (ProcessCommittedData()) {
        eParam.m_pTarget = pFFExclGroup;
        if (pFFExclGroup) {
          m_pDocView->AddValidateWidget(pFFExclGroup);
          m_pDocView->AddCalculateWidgetAcc(pFFExclGroup);
          pFFExclGroup->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
        }
        eParam.m_pTarget = m_pDataAcc;
        m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
      } else {
        SetFWLCheckState(m_pDataAcc->GetCheckState());
      }
      if (pFFExclGroup) {
        eParam.m_pTarget = pFFExclGroup;
        pFFExclGroup->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
      }
      eParam.m_pTarget = m_pDataAcc;
      m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
      break;
    }
    default:
      break;
  }
  m_pOldDelegate->OnProcessEvent(pEvent);
}

void CXFA_FFCheckButton::OnDrawWidget(CFX_Graphics* pGraphics,
                                      const CFX_Matrix* pMatrix) {
  m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
}
