/*********************************************************************
** Copyright (c) 1992-2026 MAK Technologies, Inc
** All rights reserved.
*********************************************************************/

#pragma once

//! \file xmlFedReader.h
//! \ingroup mtl
//! \brief This file declares DtXmlFedReader

#include <stdio.h>
#include <string>

#include "fedReader.h"

#include <vlutil/vlString.h>
#include <vlutil/vlFilename.h>
#include <vlutil/vlFedTarget.h>

// 
// 
// //! Forward declarations
// struct _xmlNode;
// struct _xmlDoc;
// typedef unsigned char xmlChar;
// typedef struct _xmlNode xmlNode;
// typedef struct _xmlDoc xmlDoc;

#ifdef DtUSE_UTILITIES_NAMESPACE
namespace DtUSE_UTILITIES_NAMESPACE
{
#endif

//! Instances of DtXmlFedReader are used to read a FED file, and fill in a DtFedTarget with the information read.
//! The FED file must be in a RTI 1516+ XML file format
//! \ingroup mtl
class DT_DLL_MTL DtXmlFedReader : public DtFedReader
{
public:

   //! Constructor
   DtXmlFedReader();

   //! Destructor
   virtual ~DtXmlFedReader();

private:

   //! Copy constructor and Assignment operator - Unimplemented
   DtXmlFedReader( const DtXmlFedReader& );
   DtXmlFedReader& operator=( const DtXmlFedReader& );

public:

   //! Read the FED file fedFileName, setting values to fedTarget.
   //! Note if fedTarget is NULL the fedfile will be read and verified only.
   virtual DtFedReadStatus readFedFilePtr(FILE* filePointer, DtFedTarget *fedTarget, DtFilename fileName,
      unsigned int strictCheckingMask=DtFedReadStrictDisabled, bool useDTD=false, bool dontParseSwitches=false ) = 0;

public:

   //! Inspect the file for indicators of what type of FOM file it is (1516, Evolved, 1516_2025, ...)
   //@{
   static DtFomType fomType(void* fedFilePtr);
   static DtFomType fomType(xmlNode*  rootNode);
   //@}

   //! get the specified node
   static xmlNode* getNodeByName(xmlNode* currentNode, const xmlChar* nodeName);

   //! Return the data for the specified child of the given node
   static const xmlChar* childContentByName(xmlNode* node, const xmlChar *name);

protected:

   //! process the FED directive
   virtual DtFedReadStatus processFed(xmlNode* fedObj) = 0;
   
   //! process the transportations directive
   virtual DtFedReadStatus parseTransportationsList(xmlNode* currentNode) = 0;

   //! process the Objects directive
   virtual DtFedReadStatus processObjects(xmlNode* currentNode) = 0;

   //! process the Interactions directive
   virtual DtFedReadStatus processInteractions(xmlNode* currentNode) = 0;

   //! process the list object of classes
   virtual DtFedReadStatus parseObjectTree(xmlNode* currentNode, const DtString& parentName) = 0;

   //! process an attribute of an object class
   virtual DtFedReadStatus parseAttribute(xmlNode* currentNode, const DtString& parentName) = 0;

   //! process a directed interaction of an object class
   //! default implementation does nothing
   virtual DtFedReadStatus parseDirectedInteraction(xmlNode* currentNode, const DtString& parentName);

   //! process attribute dimension associations
   virtual DtFedReadStatus parseAttributeDimensions( xmlNode* currentNode, DtString const& objectClass,
      DtString const& attribute) = 0;

   //! process the list of interaction classes
   virtual DtFedReadStatus parseInteractionTree(xmlNode* currentNode, const DtString& parentName) = 0;

   //! process attribute dimension associations
   virtual DtFedReadStatus parseInteractionDimensions(xmlNode *currentNode, DtString const& interactionClass) = 0;

   //! process the list of dimensions
   virtual DtFedReadStatus parseDimensionList(xmlNode* currentNode) = 0;

   //! process a dimension
   virtual DtFedReadStatus parseDimension(xmlNode* currentNode) = 0;

   //! process switches
   virtual DtFedReadStatus parseSwitches(xmlNode* currentNode) = 0;

   //! process a parameter of an interaction class
   virtual DtFedReadStatus parseParameter(xmlNode* currentNode, const DtString& parentName) = 0;

   //! process the list of transportation classes
   virtual DtFedReadStatus parseTransportationTree(xmlNode* currentNode);

   //! process the list of datatype classes
   virtual DtFedReadStatus parseDataTypeTree(xmlNode* currentNode) = 0;

   //! process the list of notes classes
   virtual DtFedReadStatus parseNotesTree(xmlNode* currentNode) = 0;

   //! process the list of user defined tags.
   virtual DtFedReadStatus parseTagsTree(xmlNode* currentNode) = 0;

   //! process the list of basic data representations
   virtual DtFedReadStatus parseBasicDataTypesTree(xmlNode* currentNode) = 0;

   //! process the list of simple data types
   virtual DtFedReadStatus parseSimpleDataTypesTree(xmlNode* currentNode) = 0;

   //! process the list of array data types
   virtual DtFedReadStatus parseArrayDataTypesTree(xmlNode* currentNode) = 0;

   //! process the list of enumerated data types
   virtual DtFedReadStatus parseEnumeratedDataTypesTree(xmlNode* currentNode) = 0;

   //! process the list of fixed record data types
   virtual DtFedReadStatus parseFixedRecordDataTypesTree(xmlNode* currentNode) = 0;

   //! process the list of variant record data types
   virtual DtFedReadStatus parseVariantRecordDataTypesTree(xmlNode* currentNode) = 0;

   //! Appends the list of properties attached to an XML node to the given string
   virtual void appendNodeProperties(xmlNode*  currentNode, DtString& output) const;

   //! Appends the name and content of the given node to the given string
   virtual void appendNodeContent(xmlNode*  node, DtString& output) const;

   //! Return true if the node is blank text (space, tab, newline)
   virtual bool isBlankText(xmlNode*  node) const;

   //! Return the data for the specified property of the given node
   virtual const xmlChar* propertyByName( xmlNode* node, const xmlChar *name);

   //! Fill in a string with the data for the specified property of the given node (empty string if property not found)
   //! Return true if property is found
   virtual bool getPropertyByName( xmlNode* node, const xmlChar *name, DtString& propertyContent);

   //! Get the children content of the given node into the given string
   virtual bool getChildrenContent(xmlNode* node, DtString& content) const;

   //! Return the children content of the given node.
   virtual DtString childrenContent(xmlNode* node) const;

   //! Fill in a string with the data for the specified child of the given node (empty string if child not found)
   //! Return true if child is found
   virtual bool getChildContentByName(xmlNode* node, const xmlChar *name, DtString& childContent);

   //! Convert the given string to a long value
   virtual bool convertStringToULong(std::string numericString, unsigned long& value);

   //! Clip the characters from beginning of string up to the first occurrence of the given character 
   // template supports char* (or other char like w_char) and also basic_string.
   template<typename stringType, typename charType> void clipPrefix(stringType& valueSpec, charType c);

protected:

   DtFedTarget* myFedTarget;
   DtFilename myFileBeingRead;

   protected:

      static const DtString theValueObjectRoot;
      static const DtString theValuePrivilegeToDelete;
      static const DtString theValueEnabled;

};

template<typename stringType, typename charType> void DtXmlFedReader::clipPrefix(stringType& valueSpec, charType c)
{
   typename stringType::size_type tokenPos = valueSpec.find_first_not_of(c);
   if (tokenPos != stringType::npos)
   {
      valueSpec.erase(0, tokenPos);
   }
}

#ifdef DtUSE_UTILITIES_NAMESPACE
} //! end of namespace DtUSE_UTILITIES_NAMESPACE
#endif

