// Copyright 2016 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/cxfa_validate.h"

#include "xfa/fxfa/parser/xfa_object.h"

CXFA_Validate::CXFA_Validate(CXFA_Node* pNode) : CXFA_Data(pNode) {}

int32_t CXFA_Validate::GetFormatTest() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_FormatTest);
}

FX_BOOL CXFA_Validate::SetTestValue(int32_t iType,
                                    CFX_WideString& wsValue,
                                    XFA_ATTRIBUTEENUM eName) {
  const XFA_ATTRIBUTEENUMINFO* pInfo =
      XFA_GetAttributeEnumByName(wsValue.AsStringC());
  if (pInfo)
    eName = pInfo->eName;

  m_pNode->SetEnum((XFA_ATTRIBUTE)iType, eName, FALSE);
  return TRUE;
}

FX_BOOL CXFA_Validate::SetNullTest(CFX_WideString wsValue) {
  return SetTestValue(XFA_ATTRIBUTE_NullTest, wsValue,
                      XFA_ATTRIBUTEENUM_Disabled);
}

int32_t CXFA_Validate::GetNullTest() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_NullTest);
}

int32_t CXFA_Validate::GetScriptTest() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_ScriptTest);
}

void CXFA_Validate::GetMessageText(CFX_WideString& wsMessage,
                                   const CFX_WideStringC& wsMessageType) {
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Message, FALSE);
  if (!pNode)
    return;

  CXFA_Node* pItemNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pItemNode;
       pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pItemNode->GetClassID() != XFA_ELEMENT_Text)
      continue;

    CFX_WideStringC wsName;
    pItemNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
    if (wsName.IsEmpty() || wsName == wsMessageType) {
      pItemNode->TryContent(wsMessage);
      return;
    }
  }
}

void CXFA_Validate::SetFormatMessageText(CFX_WideString wsMessage) {
  SetMessageText(wsMessage, FX_WSTRC(L"formatTest"));
}

void CXFA_Validate::GetFormatMessageText(CFX_WideString& wsMessage) {
  GetMessageText(wsMessage, FX_WSTRC(L"formatTest"));
}

void CXFA_Validate::SetNullMessageText(CFX_WideString wsMessage) {
  SetMessageText(wsMessage, FX_WSTRC(L"nullTest"));
}

void CXFA_Validate::GetNullMessageText(CFX_WideString& wsMessage) {
  GetMessageText(wsMessage, FX_WSTRC(L"nullTest"));
}

void CXFA_Validate::SetMessageText(CFX_WideString& wsMessage,
                                   const CFX_WideStringC& wsMessageType) {
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Message, TRUE);
  if (!pNode)
    return;

  CXFA_Node* pItemNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pItemNode;
       pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pItemNode->GetClassID() != XFA_ELEMENT_Text)
      continue;

    CFX_WideStringC wsName;
    pItemNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
    if (wsName.IsEmpty() || wsName == wsMessageType) {
      pItemNode->SetContent(wsMessage, wsMessage, FALSE);
      return;
    }
  }
  CXFA_Node* pTextNode = pNode->CreateSamePacketNode(XFA_ELEMENT_Text);
  pNode->InsertChild(pTextNode);
  pTextNode->SetCData(XFA_ATTRIBUTE_Name, wsMessageType, FALSE);
  pTextNode->SetContent(wsMessage, wsMessage, FALSE);
}

void CXFA_Validate::GetScriptMessageText(CFX_WideString& wsMessage) {
  GetMessageText(wsMessage, FX_WSTRC(L"scriptTest"));
}

void CXFA_Validate::SetScriptMessageText(CFX_WideString wsMessage) {
  SetMessageText(wsMessage, FX_WSTRC(L"scriptTest"));
}

void CXFA_Validate::GetPicture(CFX_WideString& wsPicture) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Picture))
    pNode->TryContent(wsPicture);
}

CXFA_Script CXFA_Validate::GetScript() {
  return CXFA_Script(m_pNode->GetChild(0, XFA_ELEMENT_Script));
}
