// 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/src/foxitlib.h"
#include "xfa/src/fxfa/src/common/xfa_utils.h"
#include "xfa/src/fxfa/src/common/xfa_object.h"
#include "xfa/src/fxfa/src/common/xfa_document.h"
#include "xfa/src/fxfa/src/common/xfa_parser.h"
#include "xfa/src/fxfa/src/common/xfa_script.h"
#include "xfa/src/fxfa/src/common/xfa_docdata.h"
#include "xfa/src/fxfa/src/common/xfa_doclayout.h"
#include "xfa/src/fxfa/src/common/xfa_localemgr.h"
#include "xfa/src/fxfa/src/common/xfa_fm2jsapi.h"
#include "xfa_script_resolveprocessor.h"
#include "xfa_script_nodehelper.h"
#include "xfa_script_imp.h"
CXFA_ResolveProcessor::CXFA_ResolveProcessor(void)
    : m_pNodeHelper(NULL), m_iCurStart(0) {
  m_pNodeHelper = new CXFA_NodeHelper;
}
CXFA_ResolveProcessor::~CXFA_ResolveProcessor(void) {
  if (m_pNodeHelper) {
    delete m_pNodeHelper;
    m_pNodeHelper = NULL;
  }
}
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes(CXFA_ResolveNodesData& rnd) {
  if (rnd.m_CurNode == NULL) {
    return -1;
  }
  if (!rnd.m_CurNode->IsNode()) {
    if (rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) {
      return XFA_ResolveNodes_ForAttributeRs(rnd.m_CurNode, rnd, rnd.m_wsName);
    }
    return 0;
  }
  if (rnd.m_dwStyles & XFA_RESOLVENODE_AnyChild) {
    return XFA_ResolveNodes_AnyChild(rnd);
  }
  FX_WCHAR wch = rnd.m_wsName.GetAt(0);
  switch (wch) {
    case '$':
      return XFA_ResolveNodes_Dollar(rnd);
    case '!':
      return XFA_ResolveNodes_Excalmatory(rnd);
    case '#':
      return XFA_ResolveNodes_NumberSign(rnd);
    case '*':
      return XFA_ResolveNodes_Asterisk(rnd);
    case '.':
      return XFA_ResolveNodes_AnyChild(rnd);
    default:
      break;
  }
  if (rnd.m_uHashName == XFA_HASHCODE_This && rnd.m_nLevel == 0) {
    rnd.m_Nodes.Add(rnd.m_pSC->GetThisObject());
    return 1;
  } else if (rnd.m_CurNode->GetClassID() == XFA_ELEMENT_Xfa) {
    CXFA_Object* pObjNode =
        rnd.m_pSC->GetDocument()->GetXFANode(rnd.m_uHashName);
    if (pObjNode) {
      rnd.m_Nodes.Add(pObjNode);
    } else if (rnd.m_uHashName == XFA_HASHCODE_Xfa) {
      rnd.m_Nodes.Add(rnd.m_CurNode);
    } else if ((rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) &&
               XFA_ResolveNodes_ForAttributeRs(rnd.m_CurNode, rnd,
                                               rnd.m_wsName)) {
      return 1;
    }
    if (rnd.m_Nodes.GetSize() > 0) {
      XFA_ResolveNode_FilterCondition(rnd, rnd.m_wsCondition);
    }
    return rnd.m_Nodes.GetSize();
  }
  int32_t nRet = XFA_ResolveNodes_Normal(rnd);
  if (nRet < 1 && rnd.m_uHashName == XFA_HASHCODE_Xfa) {
    rnd.m_Nodes.Add(rnd.m_pSC->GetDocument()->GetRoot());
  }
  return rnd.m_Nodes.GetSize();
}
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_AnyChild(
    CXFA_ResolveNodesData& rnd) {
  CFX_WideString wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
  CFX_WideString wsCondition = rnd.m_wsCondition;
  CXFA_Node* findNode = NULL;
  CXFA_NodeArray siblings;
  FX_BOOL bClassName = FALSE;
  if (wsName.GetAt(0) == '#') {
    bClassName = TRUE;
    wsName = wsName.Right(wsName.GetLength() - 1);
  }
  findNode = m_pNodeHelper->XFA_ResolveNodes_GetOneChild(
      (CXFA_Node*)rnd.m_CurNode, wsName, bClassName);
  if (findNode == NULL) {
    return 0;
  }
  if (wsCondition.IsEmpty()) {
    rnd.m_Nodes.Add(findNode);
    return rnd.m_Nodes.GetSize();
  }
  m_pNodeHelper->XFA_CountSiblings(findNode, XFA_LOGIC_Transparent,
                                   (CXFA_NodeArray*)&rnd.m_Nodes, bClassName);
  XFA_ResolveNode_FilterCondition(rnd, wsCondition);
  return rnd.m_Nodes.GetSize();
}
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Dollar(
    CXFA_ResolveNodesData& rnd) {
  CXFA_ObjArray& nodes = rnd.m_Nodes;
  CFX_WideString wsName = rnd.m_wsName;
  CFX_WideString wsCondition = rnd.m_wsCondition;
  int32_t iNameLen = wsName.GetLength();
  if (iNameLen == 1) {
    nodes.Add(rnd.m_CurNode);
    return 1;
  }
  if (rnd.m_nLevel > 0) {
    return -1;
  }
  FX_DWORD dwNameHash =
      FX_HashCode_String_GetW((const FX_WCHAR*)wsName + 1, iNameLen - 1);
  if (dwNameHash == XFA_HASHCODE_Xfa) {
    nodes.Add(rnd.m_pSC->GetDocument()->GetRoot());
  } else {
    CXFA_Object* pObjNode = rnd.m_pSC->GetDocument()->GetXFANode(dwNameHash);
    if (pObjNode) {
      rnd.m_Nodes.Add(pObjNode);
    }
  }
  if (rnd.m_Nodes.GetSize() > 0) {
    XFA_ResolveNode_FilterCondition(rnd, wsCondition);
  }
  return rnd.m_Nodes.GetSize();
}
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Excalmatory(
    CXFA_ResolveNodesData& rnd) {
  if (rnd.m_nLevel > 0) {
    return 0;
  }
  CXFA_Node* datasets =
      (CXFA_Node*)rnd.m_pSC->GetDocument()->GetXFANode(XFA_HASHCODE_Datasets);
  if (datasets == NULL) {
    return 0;
  }
  CXFA_ResolveNodesData rndFind;
  rndFind.m_pSC = rnd.m_pSC;
  rndFind.m_CurNode = datasets;
  rndFind.m_wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
  rndFind.m_uHashName =
      FX_HashCode_String_GetW(rndFind.m_wsName, rndFind.m_wsName.GetLength());
  rndFind.m_nLevel = rnd.m_nLevel + 1;
  rndFind.m_dwStyles = XFA_RESOLVENODE_Children;
  rndFind.m_wsCondition = rnd.m_wsCondition;
  XFA_ResolveNodes(rndFind);
  if (rndFind.m_Nodes.GetSize() > 0) {
    rnd.m_Nodes.Append(rndFind.m_Nodes);
    rndFind.m_Nodes.RemoveAll();
  }
  return rnd.m_Nodes.GetSize();
}
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_NumberSign(
    CXFA_ResolveNodesData& rnd) {
  CFX_WideString wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
  CFX_WideString wsCondition = rnd.m_wsCondition;
  CXFA_Node* curNode = (CXFA_Node*)rnd.m_CurNode;
  if (XFA_ResolveNodes_ForAttributeRs(curNode, rnd, wsName)) {
    return 1;
  }
  CXFA_ResolveNodesData rndFind;
  rndFind.m_pSC = rnd.m_pSC;
  rndFind.m_nLevel = rnd.m_nLevel + 1;
  rndFind.m_dwStyles = rnd.m_dwStyles;
  rndFind.m_dwStyles |= XFA_RESOLVENODE_TagName;
  rndFind.m_dwStyles &= ~XFA_RESOLVENODE_Attributes;
  rndFind.m_wsName = wsName;
  rndFind.m_uHashName =
      FX_HashCode_String_GetW(rndFind.m_wsName, rndFind.m_wsName.GetLength());
  rndFind.m_wsCondition = wsCondition;
  rndFind.m_CurNode = curNode;
  XFA_ResolveNodes_Normal(rndFind);
  if (rndFind.m_Nodes.GetSize() > 0) {
    if (wsCondition.GetLength() == 0 && rndFind.m_Nodes.Find(curNode) >= 0) {
      rnd.m_Nodes.Add(curNode);
    } else {
      rnd.m_Nodes.Append(rndFind.m_Nodes);
      rndFind.m_Nodes.RemoveAll();
    }
  }
  return rnd.m_Nodes.GetSize();
}
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_ForAttributeRs(
    CXFA_Object* curNode,
    CXFA_ResolveNodesData& rnd,
    const CFX_WideStringC& strAttr) {
  XFA_LPCSCRIPTATTRIBUTEINFO lpScriptAttribute =
      XFA_GetScriptAttributeByName(curNode->GetClassID(), strAttr);
  if (lpScriptAttribute) {
    rnd.m_pScriptAttribute = lpScriptAttribute;
    rnd.m_Nodes.Add(curNode);
    rnd.m_dwFlag = XFA_RESOVENODE_RSTYPE_Attribute;
    return 1;
  }
  return 0;
}
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Normal(
    CXFA_ResolveNodesData& rnd) {
  if (rnd.m_nLevel > 32) {
    return 0;
  }
  if (!rnd.m_CurNode->IsNode()) {
    return 0;
  }
  CXFA_Node* curNode = (CXFA_Node*)rnd.m_CurNode;
  CXFA_ObjArray& nodes = rnd.m_Nodes;
  int32_t nNum = nodes.GetSize();
  FX_DWORD dwStyles = rnd.m_dwStyles;
  CFX_WideString& wsName = rnd.m_wsName;
  uint32_t uNameHash = rnd.m_uHashName;
  CFX_WideString& wsCondition = rnd.m_wsCondition;
  CXFA_ResolveNodesData rndFind;
  rndFind.m_wsName = rnd.m_wsName;
  rndFind.m_wsCondition = rnd.m_wsCondition;
  rndFind.m_pSC = rnd.m_pSC;
  rndFind.m_nLevel = rnd.m_nLevel + 1;
  rndFind.m_uHashName = uNameHash;
  CXFA_NodeArray children;
  CXFA_NodeArray properties;
  CXFA_Node* pVariablesNode = NULL;
  CXFA_Node* pPageSetNode = NULL;
  CXFA_Node* pChild = curNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  while (pChild) {
    if (pChild->GetClassID() == XFA_ELEMENT_Variables) {
      pVariablesNode = pChild;
      pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
      continue;
    } else if (pChild->GetClassID() == XFA_ELEMENT_PageSet) {
      pPageSetNode = pChild;
      pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
      continue;
    } else {
      XFA_LPCPROPERTY pPropert = XFA_GetPropertyOfElement(
          curNode->GetClassID(), pChild->GetClassID(), XFA_XDPPACKET_UNKNOWN);
      if (pPropert) {
        properties.Add(pChild);
      } else {
        children.Add(pChild);
      }
    }
    pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
  }
  if ((dwStyles & XFA_RESOLVENODE_Properties) && pVariablesNode) {
    uint32_t uPropHash = pVariablesNode->GetClassHashCode();
    if (uPropHash == uNameHash) {
      nodes.Add(pVariablesNode);
    } else {
      rndFind.m_CurNode = pVariablesNode;
      XFA_ResolveNodes_SetStylesForChild(dwStyles, rndFind);
      CFX_WideString wsSaveCondition = rndFind.m_wsCondition;
      rndFind.m_wsCondition.Empty();
      XFA_ResolveNodes_Normal(rndFind);
      rndFind.m_wsCondition = wsSaveCondition;
      if (rndFind.m_Nodes.GetSize() > 0) {
        nodes.Append(rndFind.m_Nodes);
        rndFind.m_Nodes.RemoveAll();
      }
    }
    if (nodes.GetSize() > nNum) {
      XFA_ResolveNode_FilterCondition(rnd, wsCondition);
      if (nodes.GetSize() > 0) {
        return 1;
      }
      return 0;
    }
  }
  if (dwStyles & XFA_RESOLVENODE_Children) {
    FX_BOOL bSetFlag = FALSE;
    if (pPageSetNode && (dwStyles & XFA_RESOLVENODE_Properties)) {
      children.Add(pPageSetNode);
    }
    for (int32_t i = 0; i < children.GetSize(); i++) {
      CXFA_Node* child = children[i];
      if (dwStyles & XFA_RESOLVENODE_TagName) {
        if (child->GetClassHashCode() == uNameHash) {
          nodes.Add(child);
        }
      } else if (child->GetNameHash() == uNameHash) {
        nodes.Add(child);
      }
      if (m_pNodeHelper->XFA_NodeIsTransparent(child) &&
          child->GetClassID() != XFA_ELEMENT_PageSet) {
        if (!bSetFlag) {
          XFA_ResolveNodes_SetStylesForChild(dwStyles, rndFind);
          bSetFlag = TRUE;
        }
        rndFind.m_CurNode = child;
        CFX_WideString wsSaveCondition = rndFind.m_wsCondition;
        rndFind.m_wsCondition.Empty();
        XFA_ResolveNodes_Normal(rndFind);
        rndFind.m_wsCondition = wsSaveCondition;
        if (rndFind.m_Nodes.GetSize() > 0) {
          nodes.Append(rndFind.m_Nodes);
          rndFind.m_Nodes.RemoveAll();
        }
      }
    }
    if (nodes.GetSize() > nNum) {
      if (!(dwStyles & XFA_RESOLVENODE_ALL)) {
        CXFA_NodeArray upArrayNodes;
        if (m_pNodeHelper->XFA_NodeIsTransparent((CXFA_Node*)curNode)) {
          m_pNodeHelper->XFA_CountSiblings(
              (CXFA_Node*)nodes[0], XFA_LOGIC_Transparent, &upArrayNodes,
              !!(dwStyles & XFA_RESOLVENODE_TagName));
        }
        if (upArrayNodes.GetSize() > nodes.GetSize()) {
          upArrayNodes[0] = (CXFA_Node*)nodes[0];
          nodes.RemoveAll();
          nodes.Append((CXFA_ObjArray&)upArrayNodes);
          upArrayNodes.RemoveAll();
        }
      }
      XFA_ResolveNode_FilterCondition(rnd, wsCondition);
      if (nodes.GetSize() > 0) {
        return 1;
      }
      return 0;
    }
  }
  if (dwStyles & XFA_RESOLVENODE_Attributes) {
    if (XFA_ResolveNodes_ForAttributeRs(curNode, rnd, wsName)) {
      return 1;
    }
  }
  if (dwStyles & XFA_RESOLVENODE_Properties) {
    for (int32_t i = 0; i < properties.GetSize(); i++) {
      CXFA_Node* childProperty = properties[i];
      if (childProperty->IsUnnamed()) {
        uint32_t uPropHash = childProperty->GetClassHashCode();
        if (uPropHash == uNameHash) {
          nodes.Add(childProperty);
        }
      } else if (childProperty->GetNameHash() == uNameHash &&
                 childProperty->GetClassID() != XFA_ELEMENT_Extras &&
                 childProperty->GetClassID() != XFA_ELEMENT_Items) {
        nodes.Add(childProperty);
      }
    }
    if (nodes.GetSize() > nNum) {
      XFA_ResolveNode_FilterCondition(rnd, wsCondition);
      if (nodes.GetSize() > 0) {
        return 1;
      }
      return 0;
    }
    CXFA_Node* pProp = NULL;
    if (XFA_ELEMENT_Subform == curNode->GetClassID() &&
        XFA_HASHCODE_Occur == uNameHash) {
      CXFA_Node* pInstanceManager =
          ((CXFA_Node*)curNode)->GetInstanceMgrOfSubform();
      if (pInstanceManager) {
        pProp = pInstanceManager->GetProperty(0, XFA_ELEMENT_Occur, TRUE);
      }
    } else {
      XFA_LPCELEMENTINFO pElement = XFA_GetElementByName(wsName);
      if (pElement) {
        pProp = ((CXFA_Node*)curNode)
                    ->GetProperty(0, pElement->eName,
                                  pElement->eName != XFA_ELEMENT_PageSet);
      }
    }
    if (pProp) {
      nodes.Add(pProp);
      return nodes.GetSize();
    }
  }
  CXFA_Node* parentNode = m_pNodeHelper->XFA_ResolveNodes_GetParent(
      (CXFA_Node*)curNode, XFA_LOGIC_NoTransparent);
  uint32_t uCurClassHash = curNode->GetClassHashCode();
  if (parentNode == NULL) {
    if (uCurClassHash == uNameHash) {
      nodes.Add((CXFA_Node*)curNode);
      XFA_ResolveNode_FilterCondition(rnd, wsCondition);
      if (nodes.GetSize() > 0) {
        return 1;
      }
    }
    return 0;
  }
  if (dwStyles & XFA_RESOLVENODE_Siblings) {
    CXFA_Node* child = parentNode->GetNodeItem(XFA_NODEITEM_FirstChild);
    FX_DWORD dwSubStyles =
        XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties;
    if (dwStyles & XFA_RESOLVENODE_TagName) {
      dwSubStyles |= XFA_RESOLVENODE_TagName;
    }
    if (dwStyles & XFA_RESOLVENODE_ALL) {
      dwSubStyles |= XFA_RESOLVENODE_ALL;
    }
    rndFind.m_dwStyles = dwSubStyles;
    while (child) {
      if (child == curNode) {
        if (dwStyles & XFA_RESOLVENODE_TagName) {
          if (uCurClassHash == uNameHash) {
            nodes.Add(curNode);
          }
        } else {
          if (child->GetNameHash() == uNameHash) {
            nodes.Add(curNode);
            if (rnd.m_nLevel == 0 && wsCondition.GetLength() == 0) {
              nodes.RemoveAll();
              nodes.Add(curNode);
              return 1;
            }
          }
        }
        child = child->GetNodeItem(XFA_NODEITEM_NextSibling);
        continue;
      }
      if (dwStyles & XFA_RESOLVENODE_TagName) {
        if (child->GetClassHashCode() == uNameHash) {
          nodes.Add(child);
        }
      } else if (child->GetNameHash() == uNameHash) {
        nodes.Add(child);
      }
      XFA_LPCPROPERTY pPropert = XFA_GetPropertyOfElement(
          parentNode->GetClassID(), child->GetClassID(), XFA_XDPPACKET_UNKNOWN);
      FX_BOOL bInnerSearch = FALSE;
      if (pPropert) {
        if ((child->GetClassID() == XFA_ELEMENT_Variables ||
             child->GetClassID() == XFA_ELEMENT_PageSet)) {
          bInnerSearch = TRUE;
        }
      } else {
        if (m_pNodeHelper->XFA_NodeIsTransparent(child)) {
          bInnerSearch = TRUE;
        }
      }
      if (bInnerSearch) {
        rndFind.m_CurNode = child;
        CFX_WideString wsOriginCondition = rndFind.m_wsCondition;
        rndFind.m_wsCondition.Empty();
        FX_DWORD dwOriginStyle = rndFind.m_dwStyles;
        rndFind.m_dwStyles = dwOriginStyle | XFA_RESOLVENODE_ALL;
        XFA_ResolveNodes_Normal(rndFind);
        rndFind.m_dwStyles = dwOriginStyle;
        rndFind.m_wsCondition = wsOriginCondition;
        if (rndFind.m_Nodes.GetSize() > 0) {
          nodes.Append(rndFind.m_Nodes);
          rndFind.m_Nodes.RemoveAll();
        }
      }
      child = child->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
    if (nodes.GetSize() > nNum) {
      if (m_pNodeHelper->XFA_NodeIsTransparent(parentNode)) {
        CXFA_NodeArray upArrayNodes;
        m_pNodeHelper->XFA_CountSiblings(
            (CXFA_Node*)nodes[0], XFA_LOGIC_Transparent, &upArrayNodes,
            !!(dwStyles & XFA_RESOLVENODE_TagName));
        if (upArrayNodes.GetSize() > nodes.GetSize()) {
          upArrayNodes[0] = (CXFA_Node*)nodes[0];
          nodes.RemoveAll();
          nodes.Append((CXFA_ObjArray&)upArrayNodes);
          upArrayNodes.RemoveAll();
        }
      }
      XFA_ResolveNode_FilterCondition(rnd, wsCondition);
      if (nodes.GetSize() > 0) {
        return 1;
      }
      return 0;
    }
  }
  if (dwStyles & XFA_RESOLVENODE_Parent) {
    FX_DWORD dwSubStyles = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent |
                           XFA_RESOLVENODE_Properties;
    if (dwStyles & XFA_RESOLVENODE_TagName) {
      dwSubStyles |= XFA_RESOLVENODE_TagName;
    }
    if (dwStyles & XFA_RESOLVENODE_ALL) {
      dwSubStyles |= XFA_RESOLVENODE_ALL;
    }
    rndFind.m_dwStyles = dwSubStyles;
    rndFind.m_CurNode = parentNode;
    CXFA_NodeArray& array = rnd.m_pSC->GetUpObjectArray();
    array.Add(parentNode);
    XFA_ResolveNodes_Normal(rndFind);
    if (rndFind.m_Nodes.GetSize() > 0) {
      nodes.Append(rndFind.m_Nodes);
      rndFind.m_Nodes.RemoveAll();
    }
    if (nodes.GetSize() > nNum) {
      return 1;
    }
  }
  return 0;
}
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Asterisk(
    CXFA_ResolveNodesData& rnd) {
  CXFA_Node* curNode = (CXFA_Node*)rnd.m_CurNode;
  CXFA_ObjArray& nodes = rnd.m_Nodes;
  CXFA_NodeArray array;
  curNode->GetNodeList(array,
                       XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties);
  nodes.Append((CXFA_ObjArray&)array);
  return nodes.GetSize();
}
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_PopStack(
    CFX_Int32Array& stack) {
  int32_t nType = -1;
  int32_t iSize = stack.GetSize() - 1;
  if (iSize > -1) {
    nType = stack[iSize];
    stack.RemoveAt(iSize, 1);
  }
  return nType;
}
int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_GetFilter(
    const CFX_WideStringC& wsExpression,
    int32_t nStart,
    CXFA_ResolveNodesData& rnd) {
  FXSYS_assert(nStart > -1);
  int32_t iLength = wsExpression.GetLength();
  if (nStart >= iLength) {
    return 0;
  }
  CFX_WideString& wsName = rnd.m_wsName;
  CFX_WideString& wsCondition = rnd.m_wsCondition;
  FX_WCHAR* pNameBuf = wsName.GetBuffer(iLength - nStart);
  FX_WCHAR* pConditionBuf = wsCondition.GetBuffer(iLength - nStart);
  int32_t nNameCount = 0;
  int32_t nConditionCount = 0;
  CFX_Int32Array stack;
  int32_t nType = -1;
  const FX_WCHAR* pSrc = wsExpression.GetPtr();
  FX_WCHAR wPrev = 0, wCur;
  FX_BOOL bIsCondition = FALSE;
  while (nStart < iLength) {
    wCur = pSrc[nStart++];
    if (wCur == '.') {
      if (wPrev == '\\') {
        pNameBuf[nNameCount - 1] = wPrev = '.';
        continue;
      }
      if (nNameCount == 0) {
        pNameBuf[nNameCount++] = wCur;
        continue;
      }
      FX_WCHAR wLookahead = nStart < iLength ? pSrc[nStart] : 0;
      if (wLookahead != '[' && wLookahead != '(') {
        if (nType < 0) {
          break;
        }
      }
    }
    if (wCur == '[' || wCur == '(') {
      bIsCondition = TRUE;
    } else if (wCur == '.' && nStart < iLength &&
               (pSrc[nStart] == '[' || pSrc[nStart] == '(')) {
      bIsCondition = TRUE;
    }
    if (bIsCondition) {
      pConditionBuf[nConditionCount++] = wCur;
    } else {
      pNameBuf[nNameCount++] = wCur;
    }
    FX_BOOL bRecursive = TRUE;
    switch (nType) {
      case 0:
        if (wCur == ']') {
          nType = XFA_ResolveNodes_PopStack(stack);
          bRecursive = FALSE;
        }
        break;
      case 1:
        if (wCur == ')') {
          nType = XFA_ResolveNodes_PopStack(stack);
          bRecursive = FALSE;
        }
        break;
      case 2:
        if (wCur == '"') {
          nType = XFA_ResolveNodes_PopStack(stack);
          bRecursive = FALSE;
        }
        break;
    }
    if (bRecursive) {
      switch (wCur) {
        case '[':
          stack.Add(nType);
          nType = 0;
          break;
        case '(':
          stack.Add(nType);
          nType = 1;
          break;
        case '"':
          stack.Add(nType);
          nType = 2;
          break;
      }
    }
    wPrev = wCur;
  }
  if (stack.GetSize() > 0) {
    return -1;
  }
  wsName.ReleaseBuffer(nNameCount);
  wsName.TrimLeft();
  wsName.TrimRight();
  wsCondition.ReleaseBuffer(nConditionCount);
  wsCondition.TrimLeft();
  wsCondition.TrimRight();
  rnd.m_uHashName = FX_HashCode_String_GetW(wsName, wsName.GetLength());
  return nStart;
}
void CXFA_ResolveProcessor::XFA_ResolveNode_ConditionArray(
    int32_t iCurIndex,
    CFX_WideString wsCondition,
    int32_t iFoundCount,
    CXFA_ResolveNodesData& rnd) {
  CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
  int32_t iLen = wsCondition.GetLength();
  FX_BOOL bRelative = FALSE;
  FX_BOOL bAll = FALSE;
  int32_t i = 1;
  for (; i < iLen; ++i) {
    FX_WCHAR ch = wsCondition[i];
    if (ch == ' ') {
      continue;
    }
    if (ch == '+' || ch == '-') {
      bRelative = TRUE;
      break;
    } else if (ch == '*') {
      bAll = TRUE;
      break;
    } else {
      break;
    }
  }
  if (bAll) {
    if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
      if (rnd.m_dwStyles & XFA_RESOLVENODE_Bind) {
        m_pNodeHelper->m_pCreateParent = (CXFA_Node*)rnd.m_CurNode;
        m_pNodeHelper->m_iCreateCount = 1;
        findNodes.RemoveAll();
        m_pNodeHelper->m_iCurAllStart = -1;
        m_pNodeHelper->m_pAllStartParent = NULL;
      } else {
        if (m_pNodeHelper->m_iCurAllStart == -1) {
          m_pNodeHelper->m_iCurAllStart = m_iCurStart;
          m_pNodeHelper->m_pAllStartParent = (CXFA_Node*)rnd.m_CurNode;
        }
      }
    } else if (rnd.m_dwStyles & XFA_RESOLVENODE_BindNew) {
      if (m_pNodeHelper->m_iCurAllStart == -1) {
        m_pNodeHelper->m_iCurAllStart = m_iCurStart;
      }
    }
    return;
  }
  if (iFoundCount == 1 && !iLen) {
    return;
  }
  CFX_WideString wsIndex;
  wsIndex = wsCondition.Mid(i, iLen - 1 - i);
  int32_t iIndex = wsIndex.GetInteger();
  if (bRelative) {
    iIndex += iCurIndex;
  }
  if (iFoundCount <= iIndex || iIndex < 0) {
    if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
      m_pNodeHelper->m_pCreateParent = (CXFA_Node*)rnd.m_CurNode;
      m_pNodeHelper->m_iCreateCount = iIndex - iFoundCount + 1;
    }
    findNodes.RemoveAll();
  } else {
    CXFA_Node* ret = findNodes[iIndex];
    findNodes.RemoveAll();
    findNodes.Add(ret);
  }
}
void CXFA_ResolveProcessor::XFA_ResolveNode_DoPredicateFilter(
    int32_t iCurIndex,
    CFX_WideString wsCondition,
    int32_t iFoundCount,
    CXFA_ResolveNodesData& rnd) {
  CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
  FXSYS_assert(iFoundCount == findNodes.GetSize());
  CFX_WideString wsExpression;
  IXFA_ScriptContext* pContext = NULL;
  XFA_SCRIPTLANGTYPE eLangType = XFA_SCRIPTLANGTYPE_Unkown;
  if (wsCondition.Left(2) == FX_WSTRC(L".[") &&
      wsCondition.Right(1) == FX_WSTRC(L"]")) {
    eLangType = XFA_SCRIPTLANGTYPE_Formcalc;
  } else if (wsCondition.Left(2) == FX_WSTRC(L".(") &&
             wsCondition.Right(1) == FX_WSTRC(L")")) {
    eLangType = XFA_SCRIPTLANGTYPE_Javascript;
  } else {
    return;
  }
  pContext = rnd.m_pSC;
  wsExpression = wsCondition.Mid(2, wsCondition.GetLength() - 3);
  for (int32_t i = iFoundCount - 1; i >= 0; i--) {
    CXFA_Object* node = findNodes[i];
    FX_BOOL bRet = FALSE;
    FXJSE_HVALUE pRetValue = FXJSE_Value_Create(rnd.m_pSC->GetRuntime());
    bRet = pContext->RunScript(eLangType, wsExpression, pRetValue, node);
    if (!bRet || !FXJSE_Value_ToBoolean(pRetValue)) {
      findNodes.RemoveAt(i);
    }
    FXJSE_Value_Release(pRetValue);
  }
}

void CXFA_ResolveProcessor::XFA_ResolveNode_FilterCondition(
    CXFA_ResolveNodesData& rnd,
    CFX_WideString wsCondition) {
  CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
  int32_t iCurrIndex = 0;
  const CXFA_NodeArray& array = rnd.m_pSC->GetUpObjectArray();
  int32_t iSize = array.GetSize();
  if (iSize) {
    CXFA_Node* curNode = array[iSize - 1];
    FX_BOOL bIsProperty = m_pNodeHelper->XFA_NodeIsProperty(curNode);
    if (curNode->IsUnnamed() ||
        (bIsProperty && curNode->GetClassID() != XFA_ELEMENT_PageSet)) {
      iCurrIndex = m_pNodeHelper->XFA_GetIndex(curNode, XFA_LOGIC_Transparent,
                                               bIsProperty, TRUE);
    } else {
      iCurrIndex = m_pNodeHelper->XFA_GetIndex(curNode, XFA_LOGIC_Transparent,
                                               bIsProperty, FALSE);
    }
  }
  int32_t iFoundCount = findNodes.GetSize();
  wsCondition.TrimLeft();
  wsCondition.TrimRight();
  int32_t iLen = wsCondition.GetLength();
  if (!iLen) {
    if (rnd.m_dwStyles & XFA_RESOLVENODE_ALL) {
      return;
    }
    if (iFoundCount == 1) {
      return;
    }
    if (iFoundCount <= iCurrIndex) {
      if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
        m_pNodeHelper->m_pCreateParent = (CXFA_Node*)rnd.m_CurNode;
        m_pNodeHelper->m_iCreateCount = iCurrIndex - iFoundCount + 1;
      }
      findNodes.RemoveAll();
      return;
    } else {
      CXFA_Node* ret = findNodes[iCurrIndex];
      findNodes.RemoveAll();
      findNodes.Add(ret);
      return;
    }
  }
  FX_WCHAR wTypeChar = wsCondition[0];
  switch (wTypeChar) {
    case '[':
      XFA_ResolveNode_ConditionArray(iCurrIndex, wsCondition, iFoundCount, rnd);
      return;
    case '(':
      return;
    case '"':
      return;
    case '.':
      if (iLen > 1 && (wsCondition[1] == '[' || wsCondition[1] == '(')) {
        XFA_ResolveNode_DoPredicateFilter(iCurrIndex, wsCondition, iFoundCount,
                                          rnd);
      }
    default:
      return;
  }
}
void CXFA_ResolveProcessor::XFA_ResolveNodes_SetStylesForChild(
    FX_DWORD dwParentStyles,
    CXFA_ResolveNodesData& rnd) {
  FX_DWORD dwSubStyles = XFA_RESOLVENODE_Children;
  if (dwParentStyles & XFA_RESOLVENODE_TagName) {
    dwSubStyles |= XFA_RESOLVENODE_TagName;
  }
  dwSubStyles &= ~XFA_RESOLVENODE_Parent;
  dwSubStyles &= ~XFA_RESOLVENODE_Siblings;
  dwSubStyles &= ~XFA_RESOLVENODE_Properties;
  dwSubStyles |= XFA_RESOLVENODE_ALL;
  rnd.m_dwStyles = dwSubStyles;
}
int32_t CXFA_ResolveProcessor::XFA_ResolveNode_SetResultCreateNode(
    XFA_RESOLVENODE_RS& resolveNodeRS,
    CFX_WideString& wsLastCondition) {
  if (m_pNodeHelper->m_pCreateParent) {
    resolveNodeRS.nodes.Add(m_pNodeHelper->m_pCreateParent);
  } else {
    m_pNodeHelper->XFA_CreateNode_ForCondition(wsLastCondition);
  }
  resolveNodeRS.dwFlags = m_pNodeHelper->m_iCreateFlag;
  if (resolveNodeRS.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeOne) {
    if (m_pNodeHelper->m_iCurAllStart != -1) {
      resolveNodeRS.dwFlags = XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll;
    }
  }
  return resolveNodeRS.nodes.GetSize();
}
void CXFA_ResolveProcessor::XFA_ResolveNode_SetIndexDataBind(
    CFX_WideString& wsNextCondition,
    int32_t& iIndex,
    int32_t iCount) {
  if (m_pNodeHelper->XFA_CreateNode_ForCondition(wsNextCondition)) {
    if (m_pNodeHelper->m_eLastCreateType == XFA_ELEMENT_DataGroup) {
      iIndex = 0;
    } else {
      iIndex = iCount - 1;
    }
  } else {
    iIndex = iCount - 1;
  }
}
