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

#include <set>

#include "fxjse/include/cfxjse_arguments.h"
#include "third_party/base/stl_util.h"
#include "xfa/fxfa/app/xfa_ffnotify.h"
#include "xfa/fxfa/parser/xfa_doclayout.h"
#include "xfa/fxfa/parser/xfa_document.h"
#include "xfa/fxfa/parser/xfa_document_layout_imp.h"
#include "xfa/fxfa/parser/xfa_layout_appadapter.h"
#include "xfa/fxfa/parser/xfa_localemgr.h"
#include "xfa/fxfa/parser/xfa_object.h"
#include "xfa/fxfa/parser/xfa_parser.h"
#include "xfa/fxfa/parser/xfa_parser_imp.h"
#include "xfa/fxfa/parser/xfa_script.h"
#include "xfa/fxfa/parser/xfa_script_imp.h"
#include "xfa/fxfa/parser/xfa_utils.h"

CScript_LayoutPseudoModel::CScript_LayoutPseudoModel(CXFA_Document* pDocument)
    : CXFA_OrdinaryObject(pDocument, XFA_ELEMENT_LayoutPseudoModel) {
  m_uScriptHash = XFA_HASHCODE_Layout;
}
CScript_LayoutPseudoModel::~CScript_LayoutPseudoModel() {}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Ready(
    CFXJSE_Value* pValue,
    FX_BOOL bSetting,
    XFA_ATTRIBUTE eAttribute) {
  CXFA_FFNotify* pNotify = m_pDocument->GetParser()->GetNotify();
  if (!pNotify) {
    return;
  }
  if (bSetting) {
    ThrowException(XFA_IDS_UNABLE_SET_READY);
    return;
  }
  int32_t iStatus = pNotify->GetLayoutStatus();
  pValue->SetBoolean(iStatus >= 2);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_HWXY(
    CFXJSE_Arguments* pArguments,
    XFA_LAYOUTMODEL_HWXY layoutModel) {
  int32_t iLength = pArguments->GetLength();
  if (iLength < 1 || iLength > 3) {
    const FX_WCHAR* methodName = NULL;
    switch (layoutModel) {
      case XFA_LAYOUTMODEL_H:
        methodName = L"h";
        break;
      case XFA_LAYOUTMODEL_W:
        methodName = L"w";
        break;
      case XFA_LAYOUTMODEL_X:
        methodName = L"x";
        break;
      case XFA_LAYOUTMODEL_Y:
        methodName = L"y";
        break;
    }
    ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, methodName);
    return;
  }
  CXFA_Node* pNode = NULL;
  CFX_WideString wsUnit(L"pt");
  int32_t iIndex = 0;
  if (iLength >= 1) {
    pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
  }
  if (iLength >= 2) {
    CFX_ByteString bsUnit = pArguments->GetUTF8String(1);
    if (!bsUnit.IsEmpty()) {
      wsUnit = CFX_WideString::FromUTF8(bsUnit.AsStringC());
    }
  }
  if (iLength >= 3) {
    iIndex = pArguments->GetInt32(2);
  }
  if (!pNode) {
    return;
  }
  CXFA_LayoutProcessor* pDocLayout = m_pDocument->GetDocLayout();
  if (!pDocLayout) {
    return;
  }
  CFX_RectF rtRect;
  CXFA_Measurement measure;
  CXFA_LayoutItem* pLayoutItem = pDocLayout->GetLayoutItem(pNode);
  if (!pLayoutItem) {
    return;
  }
  while (iIndex > 0 && pLayoutItem) {
    pLayoutItem = pLayoutItem->GetNext();
    iIndex--;
  }
  CFXJSE_Value* pValue = pArguments->GetReturnValue();
  if (!pLayoutItem) {
    pValue->SetFloat(0);
    return;
  }
  pLayoutItem->GetRect(rtRect, TRUE);
  switch (layoutModel) {
    case XFA_LAYOUTMODEL_H:
      measure.Set(rtRect.height, XFA_UNIT_Pt);
      break;
    case XFA_LAYOUTMODEL_W:
      measure.Set(rtRect.width, XFA_UNIT_Pt);
      break;
    case XFA_LAYOUTMODEL_X:
      measure.Set(rtRect.left, XFA_UNIT_Pt);
      break;
    case XFA_LAYOUTMODEL_Y:
      measure.Set(rtRect.top, XFA_UNIT_Pt);
      break;
  }
  XFA_UNIT unit = measure.GetUnit(wsUnit.AsStringC());
  FX_FLOAT fValue = measure.ToUnit(unit);
  fValue = FXSYS_round(fValue * 1000) / 1000.0f;
  if (pValue)
    pValue->SetFloat(fValue);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_H(
    CFXJSE_Arguments* pArguments) {
  Script_LayoutPseudoModel_HWXY(pArguments, XFA_LAYOUTMODEL_H);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_W(
    CFXJSE_Arguments* pArguments) {
  Script_LayoutPseudoModel_HWXY(pArguments, XFA_LAYOUTMODEL_W);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_X(
    CFXJSE_Arguments* pArguments) {
  Script_LayoutPseudoModel_HWXY(pArguments, XFA_LAYOUTMODEL_X);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Y(
    CFXJSE_Arguments* pArguments) {
  Script_LayoutPseudoModel_HWXY(pArguments, XFA_LAYOUTMODEL_Y);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_NumberedPageCount(
    CFXJSE_Arguments* pArguments,
    FX_BOOL bNumbered) {
  CXFA_LayoutProcessor* pDocLayout = m_pDocument->GetDocLayout();
  if (!pDocLayout) {
    return;
  }
  int32_t iPageCount = 0;
  int32_t iPageNum = pDocLayout->CountPages();
  if (bNumbered) {
    for (int32_t i = 0; i < iPageNum; i++) {
      CXFA_ContainerLayoutItem* pLayoutPage = pDocLayout->GetPage(i);
      if (!pLayoutPage) {
        continue;
      }
      CXFA_Node* pMasterPage = pLayoutPage->GetMasterPage();
      if (pMasterPage->GetInteger(XFA_ATTRIBUTE_Numbered)) {
        iPageCount++;
      }
    }
  } else {
    iPageCount = iPageNum;
  }
  CFXJSE_Value* pValue = pArguments->GetReturnValue();
  if (pValue)
    pValue->SetInteger(iPageCount);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageCount(
    CFXJSE_Arguments* pArguments) {
  Script_LayoutPseudoModel_NumberedPageCount(pArguments, TRUE);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageSpan(
    CFXJSE_Arguments* pArguments) {
  int32_t iLength = pArguments->GetLength();
  if (iLength != 1) {
    ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"pageSpan");
    return;
  }
  CXFA_Node* pNode = NULL;
  if (iLength >= 1) {
    pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
  }
  if (!pNode) {
    return;
  }
  CXFA_LayoutProcessor* pDocLayout = m_pDocument->GetDocLayout();
  if (!pDocLayout) {
    return;
  }
  CFXJSE_Value* pValue = pArguments->GetReturnValue();
  CXFA_LayoutItem* pLayoutItem = pDocLayout->GetLayoutItem(pNode);
  if (!pLayoutItem) {
    pValue->SetInteger(-1);
    return;
  }
  int32_t iLast = pLayoutItem->GetLast()->GetPage()->GetPageIndex();
  int32_t iFirst = pLayoutItem->GetFirst()->GetPage()->GetPageIndex();
  int32_t iPageSpan = iLast - iFirst + 1;
  if (pValue)
    pValue->SetInteger(iPageSpan);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Page(
    CFXJSE_Arguments* pArguments) {
  Script_LayoutPseudoModel_PageImp(pArguments, FALSE);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_GetObjArray(
    CXFA_LayoutProcessor* pDocLayout,
    int32_t iPageNo,
    const CFX_WideString& wsType,
    FX_BOOL bOnPageArea,
    CXFA_NodeArray& retArray) {
  CXFA_ContainerLayoutItem* pLayoutPage = pDocLayout->GetPage(iPageNo);
  if (!pLayoutPage) {
    return;
  }
  if (wsType == FX_WSTRC(L"pageArea")) {
    if (CXFA_Node* pMasterPage = pLayoutPage->m_pFormNode) {
      retArray.Add(pMasterPage);
    }
    return;
  }
  if (wsType == FX_WSTRC(L"contentArea")) {
    for (CXFA_LayoutItem* pItem = pLayoutPage->m_pFirstChild; pItem;
         pItem = pItem->m_pNextSibling) {
      if (pItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) {
        retArray.Add(pItem->m_pFormNode);
      }
    }
    return;
  }
  std::set<CXFA_Node*> formItems;
  if (wsType.IsEmpty()) {
    if (CXFA_Node* pMasterPage = pLayoutPage->m_pFormNode) {
      retArray.Add(pMasterPage);
    }
    for (CXFA_LayoutItem* pItem = pLayoutPage->m_pFirstChild; pItem;
         pItem = pItem->m_pNextSibling) {
      if (pItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) {
        retArray.Add(pItem->m_pFormNode);
        if (!bOnPageArea) {
          CXFA_NodeIteratorTemplate<CXFA_ContentLayoutItem,
                                    CXFA_TraverseStrategy_ContentLayoutItem>
          iterator(static_cast<CXFA_ContentLayoutItem*>(pItem->m_pFirstChild));
          for (CXFA_ContentLayoutItem* pItemChild = iterator.GetCurrent();
               pItemChild; pItemChild = iterator.MoveToNext()) {
            if (!pItemChild->IsContentLayoutItem()) {
              continue;
            }
            XFA_ELEMENT eElementType = pItemChild->m_pFormNode->GetClassID();
            if (eElementType != XFA_ELEMENT_Field &&
                eElementType != XFA_ELEMENT_Draw &&
                eElementType != XFA_ELEMENT_Subform &&
                eElementType != XFA_ELEMENT_Area) {
              continue;
            }
            if (pdfium::ContainsValue(formItems, pItemChild->m_pFormNode))
              continue;

            formItems.insert(pItemChild->m_pFormNode);
            retArray.Add(pItemChild->m_pFormNode);
          }
        }
      } else {
        if (bOnPageArea) {
          CXFA_NodeIteratorTemplate<CXFA_ContentLayoutItem,
                                    CXFA_TraverseStrategy_ContentLayoutItem>
          iterator(static_cast<CXFA_ContentLayoutItem*>(pItem));
          for (CXFA_ContentLayoutItem* pItemChild = iterator.GetCurrent();
               pItemChild; pItemChild = iterator.MoveToNext()) {
            if (!pItemChild->IsContentLayoutItem()) {
              continue;
            }
            XFA_ELEMENT eElementType = pItemChild->m_pFormNode->GetClassID();
            if (eElementType != XFA_ELEMENT_Field &&
                eElementType != XFA_ELEMENT_Draw &&
                eElementType != XFA_ELEMENT_Subform &&
                eElementType != XFA_ELEMENT_Area) {
              continue;
            }
            if (pdfium::ContainsValue(formItems, pItemChild->m_pFormNode))
              continue;
            formItems.insert(pItemChild->m_pFormNode);
            retArray.Add(pItemChild->m_pFormNode);
          }
        }
      }
    }
    return;
  }
  XFA_ELEMENT eType = XFA_ELEMENT_UNKNOWN;
  if (wsType == FX_WSTRC(L"field")) {
    eType = XFA_ELEMENT_Field;
  } else if (wsType == FX_WSTRC(L"draw")) {
    eType = XFA_ELEMENT_Draw;
  } else if (wsType == FX_WSTRC(L"subform")) {
    eType = XFA_ELEMENT_Subform;
  } else if (wsType == FX_WSTRC(L"area")) {
    eType = XFA_ELEMENT_Area;
  }
  if (eType != XFA_ELEMENT_UNKNOWN) {
    for (CXFA_LayoutItem* pItem = pLayoutPage->m_pFirstChild; pItem;
         pItem = pItem->m_pNextSibling) {
      if (pItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) {
        if (!bOnPageArea) {
          CXFA_NodeIteratorTemplate<CXFA_ContentLayoutItem,
                                    CXFA_TraverseStrategy_ContentLayoutItem>
          iterator(static_cast<CXFA_ContentLayoutItem*>(pItem->m_pFirstChild));
          for (CXFA_ContentLayoutItem* pItemChild = iterator.GetCurrent();
               pItemChild; pItemChild = iterator.MoveToNext()) {
            if (!pItemChild->IsContentLayoutItem())
              continue;
            if (pItemChild->m_pFormNode->GetClassID() != eType)
              continue;
            if (pdfium::ContainsValue(formItems, pItemChild->m_pFormNode))
              continue;
            formItems.insert(pItemChild->m_pFormNode);
            retArray.Add(pItemChild->m_pFormNode);
          }
        }
      } else {
        if (bOnPageArea) {
          CXFA_NodeIteratorTemplate<CXFA_ContentLayoutItem,
                                    CXFA_TraverseStrategy_ContentLayoutItem>
          iterator(static_cast<CXFA_ContentLayoutItem*>(pItem));
          for (CXFA_ContentLayoutItem* pItemChild = iterator.GetCurrent();
               pItemChild; pItemChild = iterator.MoveToNext()) {
            if (!pItemChild->IsContentLayoutItem())
              continue;
            if (pItemChild->m_pFormNode->GetClassID() != eType)
              continue;
            if (pdfium::ContainsValue(formItems, pItemChild->m_pFormNode))
              continue;
            formItems.insert(pItemChild->m_pFormNode);
            retArray.Add(pItemChild->m_pFormNode);
          }
        }
      }
    }
    return;
  }
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageContent(
    CFXJSE_Arguments* pArguments) {
  int32_t iLength = pArguments->GetLength();
  if (iLength < 1 || iLength > 3) {
    ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"pageContent");
    return;
  }
  int32_t iIndex = 0;
  CFX_WideString wsType;
  FX_BOOL bOnPageArea = FALSE;
  if (iLength >= 1) {
    iIndex = pArguments->GetInt32(0);
  }
  if (iLength >= 2) {
    CFX_ByteString bsType = pArguments->GetUTF8String(1);
    wsType = CFX_WideString::FromUTF8(bsType.AsStringC());
  }
  if (iLength >= 3) {
    bOnPageArea = pArguments->GetInt32(2) == 0 ? FALSE : TRUE;
  }
  CXFA_FFNotify* pNotify = m_pDocument->GetParser()->GetNotify();
  if (!pNotify) {
    return;
  }
  CXFA_LayoutProcessor* pDocLayout = m_pDocument->GetDocLayout();
  if (!pDocLayout) {
    return;
  }
  CXFA_NodeArray retArray;
  Script_LayoutPseudoModel_GetObjArray(pDocLayout, iIndex, wsType, bOnPageArea,
                                       retArray);
  CXFA_ArrayNodeList* pArrayNodeList = new CXFA_ArrayNodeList(m_pDocument);
  pArrayNodeList->SetArrayNodeList(retArray);
  pArguments->GetReturnValue()->SetObject(
      pArrayNodeList, m_pDocument->GetScriptContext()->GetJseNormalClass());
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageCount(
    CFXJSE_Arguments* pArguments) {
  Script_LayoutPseudoModel_NumberedPageCount(pArguments, FALSE);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageCountInBatch(
    CFXJSE_Arguments* pArguments) {
  CXFA_FFNotify* pNotify = m_pDocument->GetParser()->GetNotify();
  if (!pNotify) {
    return;
  }
  CXFA_FFDoc* hDoc = pNotify->GetHDOC();
  int32_t iPageCount = pNotify->GetDocProvider()->AbsPageCountInBatch(hDoc);
  CFXJSE_Value* pValue = pArguments->GetReturnValue();
  if (pValue)
    pValue->SetInteger(iPageCount);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_SheetCountInBatch(
    CFXJSE_Arguments* pArguments) {
  CXFA_FFNotify* pNotify = m_pDocument->GetParser()->GetNotify();
  if (!pNotify) {
    return;
  }
  CXFA_FFDoc* hDoc = pNotify->GetHDOC();
  int32_t iPageCount = pNotify->GetDocProvider()->SheetCountInBatch(hDoc);
  CFXJSE_Value* pValue = pArguments->GetReturnValue();
  if (pValue)
    pValue->SetInteger(iPageCount);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Relayout(
    CFXJSE_Arguments* pArguments) {
  CXFA_Node* pRootNode = m_pDocument->GetRoot();
  CXFA_Node* pFormRoot = pRootNode->GetFirstChildByClass(XFA_ELEMENT_Form);
  ASSERT(pFormRoot);
  CXFA_Node* pContentRootNode = pFormRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
  CXFA_LayoutProcessor* pLayoutProcessor = m_pDocument->GetLayoutProcessor();
  if (pContentRootNode) {
    pLayoutProcessor->AddChangedContainer(pContentRootNode);
  }
  pLayoutProcessor->SetForceReLayout(TRUE);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageSpan(
    CFXJSE_Arguments* pArguments) {
  Script_LayoutPseudoModel_PageSpan(pArguments);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageInBatch(
    CFXJSE_Arguments* pArguments) {
  int32_t iLength = pArguments->GetLength();
  if (iLength != 1) {
    ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"absPageInBatch");
    return;
  }
  CXFA_Node* pNode = NULL;
  if (iLength >= 1) {
    pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
  }
  if (!pNode) {
    return;
  }
  CXFA_FFNotify* pNotify = m_pDocument->GetParser()->GetNotify();
  if (!pNotify) {
    return;
  }
  CXFA_LayoutProcessor* pDocLayout = m_pDocument->GetDocLayout();
  if (!pDocLayout) {
    return;
  }
  CXFA_FFWidget* hWidget =
      pNotify->GetHWidget(pDocLayout->GetLayoutItem(pNode));
  if (!hWidget) {
    return;
  }
  CXFA_FFDoc* hDoc = pNotify->GetHDOC();
  int32_t iPageCount = pNotify->GetDocProvider()->AbsPageInBatch(hDoc, hWidget);
  CFXJSE_Value* pValue = pArguments->GetReturnValue();
  if (pValue)
    pValue->SetInteger(iPageCount);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_SheetInBatch(
    CFXJSE_Arguments* pArguments) {
  int32_t iLength = pArguments->GetLength();
  if (iLength != 1) {
    ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"sheetInBatch");
    return;
  }
  CXFA_Node* pNode = NULL;
  if (iLength >= 1) {
    pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
  }
  if (!pNode) {
    return;
  }
  CXFA_FFNotify* pNotify = m_pDocument->GetParser()->GetNotify();
  if (!pNotify) {
    return;
  }
  CXFA_LayoutProcessor* pDocLayout = m_pDocument->GetDocLayout();
  if (!pDocLayout) {
    return;
  }
  CXFA_FFWidget* hWidget =
      pNotify->GetHWidget(pDocLayout->GetLayoutItem(pNode));
  if (!hWidget) {
    return;
  }
  CXFA_FFDoc* hDoc = pNotify->GetHDOC();
  int32_t iPageCount = pNotify->GetDocProvider()->SheetInBatch(hDoc, hWidget);
  CFXJSE_Value* pValue = pArguments->GetReturnValue();
  if (pValue)
    pValue->SetInteger(iPageCount);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Sheet(
    CFXJSE_Arguments* pArguments) {
  Script_LayoutPseudoModel_PageImp(pArguments, TRUE);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_RelayoutPageArea(
    CFXJSE_Arguments* pArguments) {}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_SheetCount(
    CFXJSE_Arguments* pArguments) {
  Script_LayoutPseudoModel_NumberedPageCount(pArguments, FALSE);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPage(
    CFXJSE_Arguments* pArguments) {
  Script_LayoutPseudoModel_PageImp(pArguments, TRUE);
}
void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageImp(
    CFXJSE_Arguments* pArguments,
    FX_BOOL bAbsPage) {
  int32_t iLength = pArguments->GetLength();
  if (iLength != 1) {
    const FX_WCHAR* methodName;
    if (bAbsPage) {
      methodName = L"absPage";
    } else {
      methodName = L"page";
    }
    ThrowException(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, methodName);
    return;
  }
  CXFA_Node* pNode = NULL;
  if (iLength >= 1) {
    pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
  }
  int32_t iPage = 0;
  CFXJSE_Value* pValue = pArguments->GetReturnValue();
  if (!pNode && pValue)
    pValue->SetInteger(iPage);

  CXFA_LayoutProcessor* pDocLayout = m_pDocument->GetDocLayout();
  if (!pDocLayout) {
    return;
  }
  CXFA_LayoutItem* pLayoutItem = pDocLayout->GetLayoutItem(pNode);
  if (!pLayoutItem) {
    pValue->SetInteger(-1);
    return;
  }
  iPage = pLayoutItem->GetFirst()->GetPage()->GetPageIndex();
  if (pValue)
    pValue->SetInteger(bAbsPage ? iPage : iPage + 1);
}
