// 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

#ifndef XFA_FXFA_INCLUDE_FXFA_WIDGET_H_
#define XFA_FXFA_INCLUDE_FXFA_WIDGET_H_

#include "core/fxcrt/include/fx_coordinates.h"
#include "core/fxge/include/fx_dib.h"
#include "xfa/fxfa/parser/cxfa_box.h"
#include "xfa/fxfa/parser/cxfa_event.h"
#include "xfa/fxfa/parser/cxfa_image.h"
#include "xfa/fxfa/parser/cxfa_margin.h"
#include "xfa/fxfa/parser/cxfa_script.h"
#include "xfa/fxfa/parser/cxfa_value.h"
#include "xfa/fxfa/parser/cxfa_widgetdata.h"

class CXFA_Node;
class CXFA_FFDocView;
class CXFA_FFDoc;
class CXFA_FFApp;
class CXFA_EventParam;
class CXFA_FFWidget;
class CXFA_TextLayout;
class CXFA_WidgetLayoutData;
class IFGAS_Font;
class IXFA_AppProvider;

class CXFA_WidgetAcc : public CXFA_WidgetData {
 public:
  CXFA_WidgetAcc(CXFA_FFDocView* pDocView, CXFA_Node* pNode);
  ~CXFA_WidgetAcc();

  FX_BOOL GetName(CFX_WideString& wsName, int32_t iNameType = 0);
  FX_BOOL ProcessValueChanged();
  void ResetData();

  void SetImageEdit(const CFX_WideString& wsContentType,
                    const CFX_WideString& wsHref,
                    const CFX_WideString& wsData);

  CXFA_WidgetAcc* GetExclGroup();
  CXFA_FFDocView* GetDocView();
  CXFA_FFDoc* GetDoc();
  CXFA_FFApp* GetApp();
  IXFA_AppProvider* GetAppProvider();

  int32_t ProcessEvent(int32_t iActivity, CXFA_EventParam* pEventParam);
  int32_t ProcessEvent(CXFA_Event& event, CXFA_EventParam* pEventParam);
  int32_t ProcessCalculate();
  int32_t ProcessValidate(int32_t iFlags = 0);
  int32_t ExecuteScript(CXFA_Script script,
                        CXFA_EventParam* pEventParam,
                        CFXJSE_Value** pRetValue = nullptr);

  CXFA_FFWidget* GetNextWidget(CXFA_FFWidget* pWidget);
  void StartWidgetLayout(FX_FLOAT& fCalcWidth, FX_FLOAT& fCalcHeight);
  FX_BOOL FindSplitPos(int32_t iBlockIndex, FX_FLOAT& fCalcHeight);
  FX_BOOL LoadCaption();
  void LoadText();
  FX_BOOL LoadImageImage();
  FX_BOOL LoadImageEditImage();
  void GetImageDpi(int32_t& iImageXDpi, int32_t& iImageYDpi);
  void GetImageEditDpi(int32_t& iImageXDpi, int32_t& iImageYDpi);
  CXFA_TextLayout* GetCaptionTextLayout();
  CXFA_TextLayout* GetTextLayout();
  CFX_DIBitmap* GetImageImage();
  CFX_DIBitmap* GetImageEditImage();
  void SetImageImage(CFX_DIBitmap* newImage);
  void SetImageEditImage(CFX_DIBitmap* newImage);
  void UpdateUIDisplay(CXFA_FFWidget* pExcept = NULL);

  CXFA_Node* GetDatasets();
  IFGAS_Font* GetFDEFont();
  FX_FLOAT GetFontSize();
  FX_ARGB GetTextColor();
  FX_FLOAT GetLineHeight();
  CXFA_WidgetLayoutData* GetWidgetLayoutData();

 protected:
  void ProcessScriptTestValidate(CXFA_Validate validate,
                                 int32_t iRet,
                                 CFXJSE_Value* pRetValue,
                                 FX_BOOL bVersionFlag);
  int32_t ProcessFormatTestValidate(CXFA_Validate validate,
                                    FX_BOOL bVersionFlag);
  int32_t ProcessNullTestValidate(CXFA_Validate validate,
                                  int32_t iFlags,
                                  FX_BOOL bVersionFlag);
  void GetValidateCaptionName(CFX_WideString& wsCaptionName,
                              FX_BOOL bVersionFlag);
  void GetValidateMessage(IXFA_AppProvider* pAppProvider,
                          CFX_WideString& wsMessage,
                          FX_BOOL bError,
                          FX_BOOL bVersionFlag);
  void CalcCaptionSize(CFX_SizeF& szCap);
  FX_BOOL CalculateFieldAutoSize(CFX_SizeF& size);
  FX_BOOL CalculateWidgetAutoSize(CFX_SizeF& size);
  FX_BOOL CalculateTextEditAutoSize(CFX_SizeF& size);
  FX_BOOL CalculateCheckButtonAutoSize(CFX_SizeF& size);
  FX_BOOL CalculatePushButtonAutoSize(CFX_SizeF& size);
  FX_BOOL CalculateImageEditAutoSize(CFX_SizeF& size);
  FX_BOOL CalculateImageAutoSize(CFX_SizeF& size);
  FX_BOOL CalculateTextAutoSize(CFX_SizeF& size);
  FX_FLOAT CalculateWidgetAutoHeight(FX_FLOAT fHeightCalc);
  FX_FLOAT CalculateWidgetAutoWidth(FX_FLOAT fWidthCalc);
  FX_FLOAT GetWidthWithoutMargin(FX_FLOAT fWidthCalc);
  FX_FLOAT GetHeightWithoutMargin(FX_FLOAT fHeightCalc);
  void CalculateTextContentSize(CFX_SizeF& size);
  void CalculateAccWidthAndHeight(XFA_ELEMENT eUIType,
                                  FX_FLOAT& fWidth,
                                  FX_FLOAT& fCalcHeight);
  void InitLayoutData();
  void StartTextLayout(FX_FLOAT& fCalcWidth, FX_FLOAT& fCalcHeight);

  CXFA_FFDocView* m_pDocView;
  std::unique_ptr<CXFA_WidgetLayoutData> m_pLayoutData;
  uint32_t m_nRecursionDepth;
};

#endif  // XFA_FXFA_INCLUDE_FXFA_WIDGET_H_
