// 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_message.h"
#include "xfa/fwl/core/fwl_noteimp.h"
#include "xfa/fwl/core/fwl_widgetmgrimp.h"
#include "xfa/fwl/lightwidget/cfwl_checkbox.h"
#include "xfa/fxfa/app/xfa_ffexclgroup.h"
#include "xfa/fxfa/app/xfa_fffield.h"
#include "xfa/fxfa/include/xfa_ffapp.h"
#include "xfa/fxfa/include/xfa_ffdoc.h"
#include "xfa/fxfa/include/xfa_ffdocview.h"
#include "xfa/fxfa/include/xfa_ffpageview.h"
#include "xfa/fxfa/include/xfa_ffwidget.h"

CXFA_FFCheckButton::CXFA_FFCheckButton(CXFA_FFPageView* pPageView,
                                       CXFA_WidgetAcc* pDataAcc)
    : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(NULL) {
  m_rtCheckBox.Set(0, 0, 0, 0);
}
CXFA_FFCheckButton::~CXFA_FFCheckButton() {}
FX_BOOL CXFA_FFCheckButton::LoadWidget() {
  CFWL_CheckBox* pCheckBox = CFWL_CheckBox::Create();
  pCheckBox->Initialize();
  m_pNormalWidget = pCheckBox;
  IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
  m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
  CFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
  pNoteDriver->RegisterEventTarget(pWidget, pWidget);
  m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
  if (m_pDataAcc->IsRadioButton()) {
    pCheckBox->ModifyStylesEx(FWL_STYLEEXT_CKB_RadioButton, 0xFFFFFFFF);
  }
  m_pNormalWidget = (CFWL_Widget*)pCheckBox;
  m_pNormalWidget->SetPrivateData(m_pNormalWidget->GetWidget(), this, NULL);
  m_pNormalWidget->LockUpdate();
  UpdateWidgetProperty();
  XFA_CHECKSTATE eState = m_pDataAcc->GetCheckState();
  SetFWLCheckState(eState);
  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);
}
FX_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,
                                      int32_t iRotate) {
  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);
}
FX_BOOL CXFA_FFCheckButton::OnLButtonUp(uint32_t dwFlags,
                                        FX_FLOAT fx,
                                        FX_FLOAT fy) {
  if (!m_pNormalWidget) {
    return FALSE;
  }
  if (!IsButtonDown()) {
    return FALSE;
  }
  SetButtonDown(FALSE);
  CFWL_MsgMouse ms;
  ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonUp;
  ms.m_dwFlags = dwFlags;
  ms.m_fx = fx;
  ms.m_fy = fy;
  FWLToClient(ms.m_fx, ms.m_fy);
  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
  TranslateFWLMessage(&ms);
  return TRUE;
}
XFA_CHECKSTATE CXFA_FFCheckButton::FWLState2XFAState() {
  XFA_CHECKSTATE eCheckState = XFA_CHECKSTATE_Off;
  uint32_t dwState = m_pNormalWidget->GetStates();
  if (dwState & FWL_STATE_CKB_Checked) {
    eCheckState = XFA_CHECKSTATE_On;
  } else if (dwState & FWL_STATE_CKB_Neutral) {
    eCheckState = XFA_CHECKSTATE_Neutral;
  }
  return eCheckState;
}
FX_BOOL CXFA_FFCheckButton::CommitData() {
  XFA_CHECKSTATE eCheckState = FWLState2XFAState();
  m_pDataAcc->SetCheckState(eCheckState, TRUE);
  return TRUE;
}
FX_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);
  }
}
FX_BOOL CXFA_FFCheckButton::UpdateFWLData() {
  if (!m_pNormalWidget) {
    return FALSE;
  }
  XFA_CHECKSTATE eState = m_pDataAcc->GetCheckState();
  SetFWLCheckState(eState);
  m_pNormalWidget->Update();
  return TRUE;
}
int32_t CXFA_FFCheckButton::OnProcessMessage(CFWL_Message* pMessage) {
  return m_pOldDelegate->OnProcessMessage(pMessage);
}

FWL_ERR 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;
  }
  return m_pOldDelegate->OnProcessEvent(pEvent);
}

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